[clang] [CIR] Upstream support for string literals (PR #140796)
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)
@@ -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)
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)
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)
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)
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)
@@ -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)
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)
@@ -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)
@@ -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)
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)
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)
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