[clang] [CIR] Upstream support for string literals (PR #140796)

2025-05-21 Thread Andy Kaylor via cfe-commits

https://github.com/andykaylor updated 
https://github.com/llvm/llvm-project/pull/140796

>From 7e1e98fd2f1686709fe16b6853dcbf00623e626c Mon Sep 17 00:00:00 2001
From: Andy Kaylor 
Date: Tue, 20 May 2025 09:51:41 -0700
Subject: [PATCH 1/5] [CIR] Upstream support for string literals

This adds the minimal support needed to handle string literals.
---
 .../CIR/Dialect/Builder/CIRBaseBuilder.h  |   7 ++
 clang/include/clang/CIR/MissingFeatures.h |   1 +
 clang/lib/CIR/CodeGen/CIRGenBuilder.h |  28 +
 clang/lib/CIR/CodeGen/CIRGenExpr.cpp  |  10 ++
 clang/lib/CIR/CodeGen/CIRGenFunction.cpp  |   2 +
 clang/lib/CIR/CodeGen/CIRGenFunction.h|   2 +
 clang/lib/CIR/CodeGen/CIRGenModule.cpp| 102 ++
 clang/lib/CIR/CodeGen/CIRGenModule.h  |  11 ++
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp |  12 +++
 clang/test/CIR/CodeGen/string-literals.c  |  56 ++
 10 files changed, 231 insertions(+)
 create mode 100644 clang/test/CIR/CodeGen/string-literals.c

diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h 
b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index b680e4162a5ce..738f33bf36c9e 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -13,6 +13,7 @@
 #include "clang/CIR/Dialect/IR/CIRAttrs.h"
 #include "clang/CIR/Dialect/IR/CIRDialect.h"
 #include "clang/CIR/Dialect/IR/CIRTypes.h"
+#include "clang/CIR/MissingFeatures.h"
 #include "llvm/ADT/STLForwardCompat.h"
 #include "llvm/Support/ErrorHandling.h"
 
@@ -177,6 +178,12 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
 return create(loc, addrType, type, name, alignment);
   }
 
+  mlir::Value createGetGlobal(mlir::Location loc, cir::GlobalOp global) {
+assert(!cir::MissingFeatures::addressSpace());
+return create(loc, getPointerTo(global.getSymType()),
+global.getSymName());
+  }
+
   cir::LoadOp createLoad(mlir::Location loc, mlir::Value ptr,
  bool isVolatile = false, uint64_t alignment = 0) {
 mlir::IntegerAttr intAttr;
diff --git a/clang/include/clang/CIR/MissingFeatures.h 
b/clang/include/clang/CIR/MissingFeatures.h
index 7b33d94483d5f..d43e2d9f461d1 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -38,6 +38,7 @@ struct MissingFeatures {
   static bool opGlobalWeakRef() { return false; }
   static bool opGlobalLinkage() { return false; }
   static bool opGlobalSetVisitibility() { return false; }
+  static bool opGlobalUnnamedAddr() { return false; }
 
   static bool supportIFuncAttr() { return false; }
   static bool supportVisibility() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h 
b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
index b1b0826a4e44a..aff8b8949f3ad 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h
+++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
@@ -26,6 +26,34 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
   CIRGenBuilderTy(mlir::MLIRContext &mlirContext, const CIRGenTypeCache &tc)
   : CIRBaseBuilderTy(mlirContext), typeCache(tc) {}
 
+  /// Get a cir::ConstArrayAttr for a string literal.
+  /// Note: This is different from what is returned by
+  /// mlir::Builder::getStringAttr() which is an mlir::StringAttr.
+  mlir::Attribute getString(llvm::StringRef str, mlir::Type eltTy,
+unsigned size) {
+unsigned finalSize = size ? size : str.size();
+
+size_t lastNonZeroPos = str.find_last_not_of('\0');
+// If the string is full of null bytes, emit a #cir.zero rather than
+// a #cir.const_array.
+if (lastNonZeroPos == llvm::StringRef::npos) {
+  auto arrayTy = cir::ArrayType::get(eltTy, finalSize);
+  return cir::ZeroAttr::get(arrayTy);
+}
+// We emit trailing zeros only if there are multiple trailing zeros.
+int trailingZerosNum = 0;
+if (finalSize > lastNonZeroPos + 2)
+  trailingZerosNum = finalSize - lastNonZeroPos - 1;
+auto truncatedArrayTy =
+cir::ArrayType::get(eltTy, finalSize - trailingZerosNum);
+auto fullArrayTy = cir::ArrayType::get(eltTy, finalSize);
+return cir::ConstArrayAttr::get(
+fullArrayTy,
+mlir::StringAttr::get(str.drop_back(trailingZerosNum),
+  truncatedArrayTy),
+trailingZerosNum);
+  }
+
   std::string getUniqueAnonRecordName() { return getUniqueRecordName("anon"); }
 
   std::string getUniqueRecordName(const std::string &baseName) {
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index c5fe3c1378624..a8fecafe4a1f3 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -743,6 +743,16 @@ CIRGenFunction::emitArraySubscriptExpr(const 
clang::ArraySubscriptExpr *e) {
   return lv;
 }
 
+LValue CIRGenFunction::emitStringLiteralLValue(const StringLiteral

[clang] [CIR] Upstream support for string literals (PR #140796)

2025-05-21 Thread Henrich Lauko via cfe-commits


@@ -136,6 +139,14 @@ class CIRGenModule : public CIRGenTypeCache {
   getAddrOfGlobalVar(const VarDecl *d, mlir::Type ty = {},
  ForDefinition_t isForDefinition = NotForDefinition);
 
+  /// Return a constant array for the given string.
+  mlir::Attribute getConstantArrayFromStringLiteral(const StringLiteral *e);
+
+  /// Return a global symbol reference to a constant array for the given string
+  /// literal.
+  cir::GlobalOp getGlobalForStringLiteral(const StringLiteral *S,
+  llvm::StringRef Name = ".str");

xlauko wrote:

```suggestion
  cir::GlobalOp getGlobalForStringLiteral(const StringLiteral *s,
  llvm::StringRef name = ".str");
```

https://github.com/llvm/llvm-project/pull/140796
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Upstream support for string literals (PR #140796)

2025-05-20 Thread Andy Kaylor via cfe-commits

https://github.com/andykaylor updated 
https://github.com/llvm/llvm-project/pull/140796

>From 7e1e98fd2f1686709fe16b6853dcbf00623e626c Mon Sep 17 00:00:00 2001
From: Andy Kaylor 
Date: Tue, 20 May 2025 09:51:41 -0700
Subject: [PATCH 1/4] [CIR] Upstream support for string literals

This adds the minimal support needed to handle string literals.
---
 .../CIR/Dialect/Builder/CIRBaseBuilder.h  |   7 ++
 clang/include/clang/CIR/MissingFeatures.h |   1 +
 clang/lib/CIR/CodeGen/CIRGenBuilder.h |  28 +
 clang/lib/CIR/CodeGen/CIRGenExpr.cpp  |  10 ++
 clang/lib/CIR/CodeGen/CIRGenFunction.cpp  |   2 +
 clang/lib/CIR/CodeGen/CIRGenFunction.h|   2 +
 clang/lib/CIR/CodeGen/CIRGenModule.cpp| 102 ++
 clang/lib/CIR/CodeGen/CIRGenModule.h  |  11 ++
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp |  12 +++
 clang/test/CIR/CodeGen/string-literals.c  |  56 ++
 10 files changed, 231 insertions(+)
 create mode 100644 clang/test/CIR/CodeGen/string-literals.c

diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h 
b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index b680e4162a5ce..738f33bf36c9e 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -13,6 +13,7 @@
 #include "clang/CIR/Dialect/IR/CIRAttrs.h"
 #include "clang/CIR/Dialect/IR/CIRDialect.h"
 #include "clang/CIR/Dialect/IR/CIRTypes.h"
+#include "clang/CIR/MissingFeatures.h"
 #include "llvm/ADT/STLForwardCompat.h"
 #include "llvm/Support/ErrorHandling.h"
 
@@ -177,6 +178,12 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
 return create(loc, addrType, type, name, alignment);
   }
 
+  mlir::Value createGetGlobal(mlir::Location loc, cir::GlobalOp global) {
+assert(!cir::MissingFeatures::addressSpace());
+return create(loc, getPointerTo(global.getSymType()),
+global.getSymName());
+  }
+
   cir::LoadOp createLoad(mlir::Location loc, mlir::Value ptr,
  bool isVolatile = false, uint64_t alignment = 0) {
 mlir::IntegerAttr intAttr;
diff --git a/clang/include/clang/CIR/MissingFeatures.h 
b/clang/include/clang/CIR/MissingFeatures.h
index 7b33d94483d5f..d43e2d9f461d1 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -38,6 +38,7 @@ struct MissingFeatures {
   static bool opGlobalWeakRef() { return false; }
   static bool opGlobalLinkage() { return false; }
   static bool opGlobalSetVisitibility() { return false; }
+  static bool opGlobalUnnamedAddr() { return false; }
 
   static bool supportIFuncAttr() { return false; }
   static bool supportVisibility() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h 
b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
index b1b0826a4e44a..aff8b8949f3ad 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h
+++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
@@ -26,6 +26,34 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
   CIRGenBuilderTy(mlir::MLIRContext &mlirContext, const CIRGenTypeCache &tc)
   : CIRBaseBuilderTy(mlirContext), typeCache(tc) {}
 
+  /// Get a cir::ConstArrayAttr for a string literal.
+  /// Note: This is different from what is returned by
+  /// mlir::Builder::getStringAttr() which is an mlir::StringAttr.
+  mlir::Attribute getString(llvm::StringRef str, mlir::Type eltTy,
+unsigned size) {
+unsigned finalSize = size ? size : str.size();
+
+size_t lastNonZeroPos = str.find_last_not_of('\0');
+// If the string is full of null bytes, emit a #cir.zero rather than
+// a #cir.const_array.
+if (lastNonZeroPos == llvm::StringRef::npos) {
+  auto arrayTy = cir::ArrayType::get(eltTy, finalSize);
+  return cir::ZeroAttr::get(arrayTy);
+}
+// We emit trailing zeros only if there are multiple trailing zeros.
+int trailingZerosNum = 0;
+if (finalSize > lastNonZeroPos + 2)
+  trailingZerosNum = finalSize - lastNonZeroPos - 1;
+auto truncatedArrayTy =
+cir::ArrayType::get(eltTy, finalSize - trailingZerosNum);
+auto fullArrayTy = cir::ArrayType::get(eltTy, finalSize);
+return cir::ConstArrayAttr::get(
+fullArrayTy,
+mlir::StringAttr::get(str.drop_back(trailingZerosNum),
+  truncatedArrayTy),
+trailingZerosNum);
+  }
+
   std::string getUniqueAnonRecordName() { return getUniqueRecordName("anon"); }
 
   std::string getUniqueRecordName(const std::string &baseName) {
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index c5fe3c1378624..a8fecafe4a1f3 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -743,6 +743,16 @@ CIRGenFunction::emitArraySubscriptExpr(const 
clang::ArraySubscriptExpr *e) {
   return lv;
 }
 
+LValue CIRGenFunction::emitStringLiteralLValue(const StringLiteral

[clang] [CIR] Upstream support for string literals (PR #140796)

2025-05-20 Thread Andy Kaylor via cfe-commits

https://github.com/andykaylor updated 
https://github.com/llvm/llvm-project/pull/140796

>From 7e1e98fd2f1686709fe16b6853dcbf00623e626c Mon Sep 17 00:00:00 2001
From: Andy Kaylor 
Date: Tue, 20 May 2025 09:51:41 -0700
Subject: [PATCH 1/3] [CIR] Upstream support for string literals

This adds the minimal support needed to handle string literals.
---
 .../CIR/Dialect/Builder/CIRBaseBuilder.h  |   7 ++
 clang/include/clang/CIR/MissingFeatures.h |   1 +
 clang/lib/CIR/CodeGen/CIRGenBuilder.h |  28 +
 clang/lib/CIR/CodeGen/CIRGenExpr.cpp  |  10 ++
 clang/lib/CIR/CodeGen/CIRGenFunction.cpp  |   2 +
 clang/lib/CIR/CodeGen/CIRGenFunction.h|   2 +
 clang/lib/CIR/CodeGen/CIRGenModule.cpp| 102 ++
 clang/lib/CIR/CodeGen/CIRGenModule.h  |  11 ++
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp |  12 +++
 clang/test/CIR/CodeGen/string-literals.c  |  56 ++
 10 files changed, 231 insertions(+)
 create mode 100644 clang/test/CIR/CodeGen/string-literals.c

diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h 
b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index b680e4162a5ce..738f33bf36c9e 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -13,6 +13,7 @@
 #include "clang/CIR/Dialect/IR/CIRAttrs.h"
 #include "clang/CIR/Dialect/IR/CIRDialect.h"
 #include "clang/CIR/Dialect/IR/CIRTypes.h"
+#include "clang/CIR/MissingFeatures.h"
 #include "llvm/ADT/STLForwardCompat.h"
 #include "llvm/Support/ErrorHandling.h"
 
@@ -177,6 +178,12 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
 return create(loc, addrType, type, name, alignment);
   }
 
+  mlir::Value createGetGlobal(mlir::Location loc, cir::GlobalOp global) {
+assert(!cir::MissingFeatures::addressSpace());
+return create(loc, getPointerTo(global.getSymType()),
+global.getSymName());
+  }
+
   cir::LoadOp createLoad(mlir::Location loc, mlir::Value ptr,
  bool isVolatile = false, uint64_t alignment = 0) {
 mlir::IntegerAttr intAttr;
diff --git a/clang/include/clang/CIR/MissingFeatures.h 
b/clang/include/clang/CIR/MissingFeatures.h
index 7b33d94483d5f..d43e2d9f461d1 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -38,6 +38,7 @@ struct MissingFeatures {
   static bool opGlobalWeakRef() { return false; }
   static bool opGlobalLinkage() { return false; }
   static bool opGlobalSetVisitibility() { return false; }
+  static bool opGlobalUnnamedAddr() { return false; }
 
   static bool supportIFuncAttr() { return false; }
   static bool supportVisibility() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h 
b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
index b1b0826a4e44a..aff8b8949f3ad 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h
+++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
@@ -26,6 +26,34 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
   CIRGenBuilderTy(mlir::MLIRContext &mlirContext, const CIRGenTypeCache &tc)
   : CIRBaseBuilderTy(mlirContext), typeCache(tc) {}
 
+  /// Get a cir::ConstArrayAttr for a string literal.
+  /// Note: This is different from what is returned by
+  /// mlir::Builder::getStringAttr() which is an mlir::StringAttr.
+  mlir::Attribute getString(llvm::StringRef str, mlir::Type eltTy,
+unsigned size) {
+unsigned finalSize = size ? size : str.size();
+
+size_t lastNonZeroPos = str.find_last_not_of('\0');
+// If the string is full of null bytes, emit a #cir.zero rather than
+// a #cir.const_array.
+if (lastNonZeroPos == llvm::StringRef::npos) {
+  auto arrayTy = cir::ArrayType::get(eltTy, finalSize);
+  return cir::ZeroAttr::get(arrayTy);
+}
+// We emit trailing zeros only if there are multiple trailing zeros.
+int trailingZerosNum = 0;
+if (finalSize > lastNonZeroPos + 2)
+  trailingZerosNum = finalSize - lastNonZeroPos - 1;
+auto truncatedArrayTy =
+cir::ArrayType::get(eltTy, finalSize - trailingZerosNum);
+auto fullArrayTy = cir::ArrayType::get(eltTy, finalSize);
+return cir::ConstArrayAttr::get(
+fullArrayTy,
+mlir::StringAttr::get(str.drop_back(trailingZerosNum),
+  truncatedArrayTy),
+trailingZerosNum);
+  }
+
   std::string getUniqueAnonRecordName() { return getUniqueRecordName("anon"); }
 
   std::string getUniqueRecordName(const std::string &baseName) {
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index c5fe3c1378624..a8fecafe4a1f3 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -743,6 +743,16 @@ CIRGenFunction::emitArraySubscriptExpr(const 
clang::ArraySubscriptExpr *e) {
   return lv;
 }
 
+LValue CIRGenFunction::emitStringLiteralLValue(const StringLiteral

[clang] [CIR] Upstream support for string literals (PR #140796)

2025-05-20 Thread Erich Keane via cfe-commits

https://github.com/erichkeane commented:

still ok, 1 nit.

https://github.com/llvm/llvm-project/pull/140796
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Upstream support for string literals (PR #140796)

2025-05-20 Thread Erich Keane via cfe-commits

https://github.com/erichkeane edited 
https://github.com/llvm/llvm-project/pull/140796
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Upstream support for string literals (PR #140796)

2025-05-20 Thread Erich Keane via cfe-commits


@@ -26,6 +26,34 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
   CIRGenBuilderTy(mlir::MLIRContext &mlirContext, const CIRGenTypeCache &tc)
   : CIRBaseBuilderTy(mlirContext), typeCache(tc) {}
 
+  /// Get a cir::ConstArrayAttr for a string literal.
+  /// Note: This is different from what is returned by
+  /// mlir::Builder::getStringAttr() which is an mlir::StringAttr.
+  mlir::Attribute getString(llvm::StringRef str, mlir::Type eltTy,
+std::optional size) {
+size_t finalSize = size ? *size : str.size();

erichkeane wrote:

```suggestion
size_t finalSize = size.value_or(str.size());
```

https://github.com/llvm/llvm-project/pull/140796
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Upstream support for string literals (PR #140796)

2025-05-20 Thread Andy Kaylor via cfe-commits

https://github.com/andykaylor updated 
https://github.com/llvm/llvm-project/pull/140796

>From 7e1e98fd2f1686709fe16b6853dcbf00623e626c Mon Sep 17 00:00:00 2001
From: Andy Kaylor 
Date: Tue, 20 May 2025 09:51:41 -0700
Subject: [PATCH 1/2] [CIR] Upstream support for string literals

This adds the minimal support needed to handle string literals.
---
 .../CIR/Dialect/Builder/CIRBaseBuilder.h  |   7 ++
 clang/include/clang/CIR/MissingFeatures.h |   1 +
 clang/lib/CIR/CodeGen/CIRGenBuilder.h |  28 +
 clang/lib/CIR/CodeGen/CIRGenExpr.cpp  |  10 ++
 clang/lib/CIR/CodeGen/CIRGenFunction.cpp  |   2 +
 clang/lib/CIR/CodeGen/CIRGenFunction.h|   2 +
 clang/lib/CIR/CodeGen/CIRGenModule.cpp| 102 ++
 clang/lib/CIR/CodeGen/CIRGenModule.h  |  11 ++
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp |  12 +++
 clang/test/CIR/CodeGen/string-literals.c  |  56 ++
 10 files changed, 231 insertions(+)
 create mode 100644 clang/test/CIR/CodeGen/string-literals.c

diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h 
b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index b680e4162a5ce..738f33bf36c9e 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -13,6 +13,7 @@
 #include "clang/CIR/Dialect/IR/CIRAttrs.h"
 #include "clang/CIR/Dialect/IR/CIRDialect.h"
 #include "clang/CIR/Dialect/IR/CIRTypes.h"
+#include "clang/CIR/MissingFeatures.h"
 #include "llvm/ADT/STLForwardCompat.h"
 #include "llvm/Support/ErrorHandling.h"
 
@@ -177,6 +178,12 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
 return create(loc, addrType, type, name, alignment);
   }
 
+  mlir::Value createGetGlobal(mlir::Location loc, cir::GlobalOp global) {
+assert(!cir::MissingFeatures::addressSpace());
+return create(loc, getPointerTo(global.getSymType()),
+global.getSymName());
+  }
+
   cir::LoadOp createLoad(mlir::Location loc, mlir::Value ptr,
  bool isVolatile = false, uint64_t alignment = 0) {
 mlir::IntegerAttr intAttr;
diff --git a/clang/include/clang/CIR/MissingFeatures.h 
b/clang/include/clang/CIR/MissingFeatures.h
index 7b33d94483d5f..d43e2d9f461d1 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -38,6 +38,7 @@ struct MissingFeatures {
   static bool opGlobalWeakRef() { return false; }
   static bool opGlobalLinkage() { return false; }
   static bool opGlobalSetVisitibility() { return false; }
+  static bool opGlobalUnnamedAddr() { return false; }
 
   static bool supportIFuncAttr() { return false; }
   static bool supportVisibility() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h 
b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
index b1b0826a4e44a..aff8b8949f3ad 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h
+++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
@@ -26,6 +26,34 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
   CIRGenBuilderTy(mlir::MLIRContext &mlirContext, const CIRGenTypeCache &tc)
   : CIRBaseBuilderTy(mlirContext), typeCache(tc) {}
 
+  /// Get a cir::ConstArrayAttr for a string literal.
+  /// Note: This is different from what is returned by
+  /// mlir::Builder::getStringAttr() which is an mlir::StringAttr.
+  mlir::Attribute getString(llvm::StringRef str, mlir::Type eltTy,
+unsigned size) {
+unsigned finalSize = size ? size : str.size();
+
+size_t lastNonZeroPos = str.find_last_not_of('\0');
+// If the string is full of null bytes, emit a #cir.zero rather than
+// a #cir.const_array.
+if (lastNonZeroPos == llvm::StringRef::npos) {
+  auto arrayTy = cir::ArrayType::get(eltTy, finalSize);
+  return cir::ZeroAttr::get(arrayTy);
+}
+// We emit trailing zeros only if there are multiple trailing zeros.
+int trailingZerosNum = 0;
+if (finalSize > lastNonZeroPos + 2)
+  trailingZerosNum = finalSize - lastNonZeroPos - 1;
+auto truncatedArrayTy =
+cir::ArrayType::get(eltTy, finalSize - trailingZerosNum);
+auto fullArrayTy = cir::ArrayType::get(eltTy, finalSize);
+return cir::ConstArrayAttr::get(
+fullArrayTy,
+mlir::StringAttr::get(str.drop_back(trailingZerosNum),
+  truncatedArrayTy),
+trailingZerosNum);
+  }
+
   std::string getUniqueAnonRecordName() { return getUniqueRecordName("anon"); }
 
   std::string getUniqueRecordName(const std::string &baseName) {
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index c5fe3c1378624..a8fecafe4a1f3 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -743,6 +743,16 @@ CIRGenFunction::emitArraySubscriptExpr(const 
clang::ArraySubscriptExpr *e) {
   return lv;
 }
 
+LValue CIRGenFunction::emitStringLiteralLValue(const StringLiteral

[clang] [CIR] Upstream support for string literals (PR #140796)

2025-05-20 Thread Erich Keane via cfe-commits


@@ -26,6 +26,34 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
   CIRGenBuilderTy(mlir::MLIRContext &mlirContext, const CIRGenTypeCache &tc)
   : CIRBaseBuilderTy(mlirContext), typeCache(tc) {}
 
+  /// Get a cir::ConstArrayAttr for a string literal.
+  /// Note: This is different from what is returned by
+  /// mlir::Builder::getStringAttr() which is an mlir::StringAttr.
+  mlir::Attribute getString(llvm::StringRef str, mlir::Type eltTy,
+unsigned size) {
+unsigned finalSize = size ? size : str.size();

erichkeane wrote:

instead of 0 being special, can we make `size` be an `optional`?

https://github.com/llvm/llvm-project/pull/140796
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Upstream support for string literals (PR #140796)

2025-05-20 Thread Erich Keane via cfe-commits


@@ -26,6 +26,34 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
   CIRGenBuilderTy(mlir::MLIRContext &mlirContext, const CIRGenTypeCache &tc)
   : CIRBaseBuilderTy(mlirContext), typeCache(tc) {}
 
+  /// Get a cir::ConstArrayAttr for a string literal.
+  /// Note: This is different from what is returned by
+  /// mlir::Builder::getStringAttr() which is an mlir::StringAttr.
+  mlir::Attribute getString(llvm::StringRef str, mlir::Type eltTy,
+unsigned size) {
+unsigned finalSize = size ? size : str.size();
+
+size_t lastNonZeroPos = str.find_last_not_of('\0');
+// If the string is full of null bytes, emit a #cir.zero rather than
+// a #cir.const_array.
+if (lastNonZeroPos == llvm::StringRef::npos) {
+  auto arrayTy = cir::ArrayType::get(eltTy, finalSize);
+  return cir::ZeroAttr::get(arrayTy);
+}
+// We emit trailing zeros only if there are multiple trailing zeros.
+int trailingZerosNum = 0;

erichkeane wrote:

This could probably end up being size_t in length with a big enough set of 
zeros, right?  It doesn't look like you try tomake it negative anywhere, so 
perhaps it should too be size_t?

https://github.com/llvm/llvm-project/pull/140796
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Upstream support for string literals (PR #140796)

2025-05-20 Thread Erich Keane via cfe-commits

https://github.com/erichkeane approved this pull request.


https://github.com/llvm/llvm-project/pull/140796
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [CIR] Upstream support for string literals (PR #140796)

2025-05-20 Thread Andy Kaylor via cfe-commits

https://github.com/andykaylor created 
https://github.com/llvm/llvm-project/pull/140796

This adds the minimal support needed to handle string literals.

>From 7e1e98fd2f1686709fe16b6853dcbf00623e626c Mon Sep 17 00:00:00 2001
From: Andy Kaylor 
Date: Tue, 20 May 2025 09:51:41 -0700
Subject: [PATCH] [CIR] Upstream support for string literals

This adds the minimal support needed to handle string literals.
---
 .../CIR/Dialect/Builder/CIRBaseBuilder.h  |   7 ++
 clang/include/clang/CIR/MissingFeatures.h |   1 +
 clang/lib/CIR/CodeGen/CIRGenBuilder.h |  28 +
 clang/lib/CIR/CodeGen/CIRGenExpr.cpp  |  10 ++
 clang/lib/CIR/CodeGen/CIRGenFunction.cpp  |   2 +
 clang/lib/CIR/CodeGen/CIRGenFunction.h|   2 +
 clang/lib/CIR/CodeGen/CIRGenModule.cpp| 102 ++
 clang/lib/CIR/CodeGen/CIRGenModule.h  |  11 ++
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp |  12 +++
 clang/test/CIR/CodeGen/string-literals.c  |  56 ++
 10 files changed, 231 insertions(+)
 create mode 100644 clang/test/CIR/CodeGen/string-literals.c

diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h 
b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index b680e4162a5ce..738f33bf36c9e 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -13,6 +13,7 @@
 #include "clang/CIR/Dialect/IR/CIRAttrs.h"
 #include "clang/CIR/Dialect/IR/CIRDialect.h"
 #include "clang/CIR/Dialect/IR/CIRTypes.h"
+#include "clang/CIR/MissingFeatures.h"
 #include "llvm/ADT/STLForwardCompat.h"
 #include "llvm/Support/ErrorHandling.h"
 
@@ -177,6 +178,12 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
 return create(loc, addrType, type, name, alignment);
   }
 
+  mlir::Value createGetGlobal(mlir::Location loc, cir::GlobalOp global) {
+assert(!cir::MissingFeatures::addressSpace());
+return create(loc, getPointerTo(global.getSymType()),
+global.getSymName());
+  }
+
   cir::LoadOp createLoad(mlir::Location loc, mlir::Value ptr,
  bool isVolatile = false, uint64_t alignment = 0) {
 mlir::IntegerAttr intAttr;
diff --git a/clang/include/clang/CIR/MissingFeatures.h 
b/clang/include/clang/CIR/MissingFeatures.h
index 7b33d94483d5f..d43e2d9f461d1 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -38,6 +38,7 @@ struct MissingFeatures {
   static bool opGlobalWeakRef() { return false; }
   static bool opGlobalLinkage() { return false; }
   static bool opGlobalSetVisitibility() { return false; }
+  static bool opGlobalUnnamedAddr() { return false; }
 
   static bool supportIFuncAttr() { return false; }
   static bool supportVisibility() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h 
b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
index b1b0826a4e44a..aff8b8949f3ad 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h
+++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
@@ -26,6 +26,34 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
   CIRGenBuilderTy(mlir::MLIRContext &mlirContext, const CIRGenTypeCache &tc)
   : CIRBaseBuilderTy(mlirContext), typeCache(tc) {}
 
+  /// Get a cir::ConstArrayAttr for a string literal.
+  /// Note: This is different from what is returned by
+  /// mlir::Builder::getStringAttr() which is an mlir::StringAttr.
+  mlir::Attribute getString(llvm::StringRef str, mlir::Type eltTy,
+unsigned size) {
+unsigned finalSize = size ? size : str.size();
+
+size_t lastNonZeroPos = str.find_last_not_of('\0');
+// If the string is full of null bytes, emit a #cir.zero rather than
+// a #cir.const_array.
+if (lastNonZeroPos == llvm::StringRef::npos) {
+  auto arrayTy = cir::ArrayType::get(eltTy, finalSize);
+  return cir::ZeroAttr::get(arrayTy);
+}
+// We emit trailing zeros only if there are multiple trailing zeros.
+int trailingZerosNum = 0;
+if (finalSize > lastNonZeroPos + 2)
+  trailingZerosNum = finalSize - lastNonZeroPos - 1;
+auto truncatedArrayTy =
+cir::ArrayType::get(eltTy, finalSize - trailingZerosNum);
+auto fullArrayTy = cir::ArrayType::get(eltTy, finalSize);
+return cir::ConstArrayAttr::get(
+fullArrayTy,
+mlir::StringAttr::get(str.drop_back(trailingZerosNum),
+  truncatedArrayTy),
+trailingZerosNum);
+  }
+
   std::string getUniqueAnonRecordName() { return getUniqueRecordName("anon"); }
 
   std::string getUniqueRecordName(const std::string &baseName) {
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index c5fe3c1378624..a8fecafe4a1f3 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -743,6 +743,16 @@ CIRGenFunction::emitArraySubscriptExpr(const 
clang::ArraySubscriptExpr *e) {
   return lv;
 }
 
+LValu

[clang] [CIR] Upstream support for string literals (PR #140796)

2025-05-20 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Andy Kaylor (andykaylor)


Changes

This adds the minimal support needed to handle string literals.

---
Full diff: https://github.com/llvm/llvm-project/pull/140796.diff


10 Files Affected:

- (modified) clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h (+7) 
- (modified) clang/include/clang/CIR/MissingFeatures.h (+1) 
- (modified) clang/lib/CIR/CodeGen/CIRGenBuilder.h (+28) 
- (modified) clang/lib/CIR/CodeGen/CIRGenExpr.cpp (+10) 
- (modified) clang/lib/CIR/CodeGen/CIRGenFunction.cpp (+2) 
- (modified) clang/lib/CIR/CodeGen/CIRGenFunction.h (+2) 
- (modified) clang/lib/CIR/CodeGen/CIRGenModule.cpp (+102) 
- (modified) clang/lib/CIR/CodeGen/CIRGenModule.h (+11) 
- (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp (+12) 
- (added) clang/test/CIR/CodeGen/string-literals.c (+56) 


``diff
diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h 
b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index b680e4162a5ce..738f33bf36c9e 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -13,6 +13,7 @@
 #include "clang/CIR/Dialect/IR/CIRAttrs.h"
 #include "clang/CIR/Dialect/IR/CIRDialect.h"
 #include "clang/CIR/Dialect/IR/CIRTypes.h"
+#include "clang/CIR/MissingFeatures.h"
 #include "llvm/ADT/STLForwardCompat.h"
 #include "llvm/Support/ErrorHandling.h"
 
@@ -177,6 +178,12 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
 return create(loc, addrType, type, name, alignment);
   }
 
+  mlir::Value createGetGlobal(mlir::Location loc, cir::GlobalOp global) {
+assert(!cir::MissingFeatures::addressSpace());
+return create(loc, getPointerTo(global.getSymType()),
+global.getSymName());
+  }
+
   cir::LoadOp createLoad(mlir::Location loc, mlir::Value ptr,
  bool isVolatile = false, uint64_t alignment = 0) {
 mlir::IntegerAttr intAttr;
diff --git a/clang/include/clang/CIR/MissingFeatures.h 
b/clang/include/clang/CIR/MissingFeatures.h
index 7b33d94483d5f..d43e2d9f461d1 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -38,6 +38,7 @@ struct MissingFeatures {
   static bool opGlobalWeakRef() { return false; }
   static bool opGlobalLinkage() { return false; }
   static bool opGlobalSetVisitibility() { return false; }
+  static bool opGlobalUnnamedAddr() { return false; }
 
   static bool supportIFuncAttr() { return false; }
   static bool supportVisibility() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h 
b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
index b1b0826a4e44a..aff8b8949f3ad 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h
+++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
@@ -26,6 +26,34 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
   CIRGenBuilderTy(mlir::MLIRContext &mlirContext, const CIRGenTypeCache &tc)
   : CIRBaseBuilderTy(mlirContext), typeCache(tc) {}
 
+  /// Get a cir::ConstArrayAttr for a string literal.
+  /// Note: This is different from what is returned by
+  /// mlir::Builder::getStringAttr() which is an mlir::StringAttr.
+  mlir::Attribute getString(llvm::StringRef str, mlir::Type eltTy,
+unsigned size) {
+unsigned finalSize = size ? size : str.size();
+
+size_t lastNonZeroPos = str.find_last_not_of('\0');
+// If the string is full of null bytes, emit a #cir.zero rather than
+// a #cir.const_array.
+if (lastNonZeroPos == llvm::StringRef::npos) {
+  auto arrayTy = cir::ArrayType::get(eltTy, finalSize);
+  return cir::ZeroAttr::get(arrayTy);
+}
+// We emit trailing zeros only if there are multiple trailing zeros.
+int trailingZerosNum = 0;
+if (finalSize > lastNonZeroPos + 2)
+  trailingZerosNum = finalSize - lastNonZeroPos - 1;
+auto truncatedArrayTy =
+cir::ArrayType::get(eltTy, finalSize - trailingZerosNum);
+auto fullArrayTy = cir::ArrayType::get(eltTy, finalSize);
+return cir::ConstArrayAttr::get(
+fullArrayTy,
+mlir::StringAttr::get(str.drop_back(trailingZerosNum),
+  truncatedArrayTy),
+trailingZerosNum);
+  }
+
   std::string getUniqueAnonRecordName() { return getUniqueRecordName("anon"); }
 
   std::string getUniqueRecordName(const std::string &baseName) {
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index c5fe3c1378624..a8fecafe4a1f3 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -743,6 +743,16 @@ CIRGenFunction::emitArraySubscriptExpr(const 
clang::ArraySubscriptExpr *e) {
   return lv;
 }
 
+LValue CIRGenFunction::emitStringLiteralLValue(const StringLiteral *e) {
+  cir::GlobalOp globalOp = cgm.getGlobalForStringLiteral(e);
+  assert(!cir::MissingFeatures::opGlobalAlignment());
+  mlir::Value addr =
+  b