[llvm-branch-commits] [clang] [CIR] Add support for string literal lvalues in ConstantLValueEmitter (PR #154360)
Morris Hafner via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Aug 19 09:46:58 PDT 2025
https://github.com/mmha updated https://github.com/llvm/llvm-project/pull/154360
>From d592acb40bfcea7b9e3eca1ac29ecab96315d26f Mon Sep 17 00:00:00 2001
From: Morris Hafner <mhafner at nvidia.com>
Date: Tue, 19 Aug 2025 17:13:51 +0200
Subject: [PATCH 1/2] [CIR] Add support for string literal lavlues in
ConstantLValueEmitter
---
clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp | 3 +-
clang/lib/CIR/CodeGen/CIRGenModule.cpp | 13 ++++++++
clang/lib/CIR/CodeGen/CIRGenModule.h | 6 ++++
clang/test/CIR/CodeGen/string-literals.cpp | 34 +++++++++++++++++---
4 files changed, 50 insertions(+), 6 deletions(-)
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
index 2fbf69d5d01f4..d26269eb93d3f 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
@@ -546,8 +546,7 @@ ConstantLValueEmitter::VisitCompoundLiteralExpr(const CompoundLiteralExpr *e) {
ConstantLValue
ConstantLValueEmitter::VisitStringLiteral(const StringLiteral *e) {
- cgm.errorNYI(e->getSourceRange(), "ConstantLValueEmitter: string literal");
- return {};
+ return cgm.getAddrOfConstantStringFromLiteral(e);
}
ConstantLValue
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index 7c52adcfa56c7..cb8cc30835f62 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -1318,6 +1318,19 @@ cir::GlobalOp CIRGenModule::getGlobalForStringLiteral(const StringLiteral *s,
return gv;
}
+/// Return a pointer to a constant array for the given string literal.
+cir::GlobalViewAttr
+CIRGenModule::getAddrOfConstantStringFromLiteral(const StringLiteral *s,
+ StringRef name) {
+ cir::GlobalOp gv = getGlobalForStringLiteral(s, name);
+ auto arrayTy = mlir::dyn_cast<cir::ArrayType>(gv.getSymType());
+ assert(arrayTy && "String literal must be array");
+ assert(!cir::MissingFeatures::addressSpace());
+ cir::PointerType ptrTy = getBuilder().getPointerTo(arrayTy.getElementType());
+
+ return builder.getGlobalViewAttr(ptrTy, gv);
+}
+
void CIRGenModule::emitExplicitCastExprType(const ExplicitCastExpr *e,
CIRGenFunction *cgf) {
if (cgf && e->getType()->isVariablyModifiedType())
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.h b/clang/lib/CIR/CodeGen/CIRGenModule.h
index ce9d0344aa940..769857ab49bb8 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.h
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.h
@@ -198,6 +198,12 @@ class CIRGenModule : public CIRGenTypeCache {
cir::GlobalOp getGlobalForStringLiteral(const StringLiteral *s,
llvm::StringRef name = ".str");
+ /// Return a global symbol reference to a constant array for the given string
+ /// literal.
+ cir::GlobalViewAttr
+ getAddrOfConstantStringFromLiteral(const StringLiteral *s,
+ llvm::StringRef name = ".str");
+
/// Set attributes which are common to any form of a global definition (alias,
/// Objective-C method, function, global variable).
///
diff --git a/clang/test/CIR/CodeGen/string-literals.cpp b/clang/test/CIR/CodeGen/string-literals.cpp
index a20add08bfc2d..14115672e28e2 100644
--- a/clang/test/CIR/CodeGen/string-literals.cpp
+++ b/clang/test/CIR/CodeGen/string-literals.cpp
@@ -5,11 +5,37 @@
// RUN: %clang_cc1 -triple aarch64-none-linux-android21 -emit-llvm %s -o %t.ll
// RUN: FileCheck --check-prefix=OGCG --input-file=%t.ll %s
-// CIR: cir.global "private" constant cir_private dso_local @[[STR1_GLOBAL:.*]] = #cir.const_array<"abcd\00" : !cir.array<!s8i x 5>> : !cir.array<!s8i x 5>
-// LLVM: @[[STR1_GLOBAL:.*]] = private constant [5 x i8] c"abcd\00"
+char const *array[] {
+ "my", "hands", "are", "typing", "words"
+};
-// OGCG: @[[STR1_GLOBAL:.*]] = private unnamed_addr constant [5 x i8] c"abcd\00"
+// CIR: cir.global "private" constant cir_private dso_local @"[[STR:.+]]" = #cir.const_array<"my\00" : !cir.array<!s8i x 3>> : !cir.array<!s8i x 3>
+// CIR: cir.global "private" constant cir_private dso_local @"[[STR1:.+]]" = #cir.const_array<"hands\00" : !cir.array<!s8i x 6>> : !cir.array<!s8i x 6>
+// CIR: cir.global "private" constant cir_private dso_local @"[[STR2:.+]]" = #cir.const_array<"are\00" : !cir.array<!s8i x 4>> : !cir.array<!s8i x 4>
+// CIR: cir.global "private" constant cir_private dso_local @"[[STR3:.+]]" = #cir.const_array<"typing\00" : !cir.array<!s8i x 7>> : !cir.array<!s8i x 7>
+// CIR: cir.global "private" constant cir_private dso_local @"[[STR4:.+]]" = #cir.const_array<"words\00" : !cir.array<!s8i x 6>> : !cir.array<!s8i x 6>
+// CIR: cir.global external @array = #cir.const_array<[#cir.global_view<@"[[STR]]"> : !cir.ptr<!s8i>, #cir.global_view<@"[[STR1]]"> : !cir.ptr<!s8i>, #cir.global_view<@"[[STR2]]"> : !cir.ptr<!s8i>, #cir.global_view<@"[[STR3]]"> : !cir.ptr<!s8i>, #cir.global_view<@"[[STR4]]"> : !cir.ptr<!s8i>]> : !cir.array<!cir.ptr<!s8i> x 5>
+
+// LLVM: @[[STR:.+]] = private constant [3 x i8] c"my\00"
+// LLVM: @[[STR1:.+]] = private constant [6 x i8] c"hands\00"
+// LLVM: @[[STR2:.+]] = private constant [4 x i8] c"are\00"
+// LLVM: @[[STR3:.+]] = private constant [7 x i8] c"typing\00"
+// LLVM: @[[STR4:.+]] = private constant [6 x i8] c"words\00"
+// LLVM: @array = global [5 x ptr] [ptr @[[STR]], ptr @[[STR1]], ptr @[[STR2]], ptr @[[STR3]], ptr @[[STR4]]]
+
+// OGCG: @[[STR:.+]] = private unnamed_addr constant [3 x i8] c"my\00"
+// OGCG: @[[STR1:.+]] = private unnamed_addr constant [6 x i8] c"hands\00"
+// OGCG: @[[STR2:.+]] = private unnamed_addr constant [4 x i8] c"are\00"
+// OGCG: @[[STR3:.+]] = private unnamed_addr constant [7 x i8] c"typing\00"
+// OGCG: @[[STR4:.+]] = private unnamed_addr constant [6 x i8] c"words\00"
+// OGCG: @array = global [5 x ptr] [ptr @[[STR]], ptr @[[STR1]], ptr @[[STR2]], ptr @[[STR3]], ptr @[[STR4]]]
+
+// CIR: cir.global "private" constant cir_private dso_local @[[STR5_GLOBAL:.*]] = #cir.const_array<"abcd\00" : !cir.array<!s8i x 5>> : !cir.array<!s8i x 5>
+
+// LLVM: @[[STR5_GLOBAL:.*]] = private constant [5 x i8] c"abcd\00"
+
+// OGCG: @[[STR5_GLOBAL:.*]] = private unnamed_addr constant [5 x i8] c"abcd\00"
decltype(auto) returns_literal() {
return "abcd";
@@ -17,7 +43,7 @@ decltype(auto) returns_literal() {
// CIR: cir.func{{.*}} @_Z15returns_literalv() -> !cir.ptr<!cir.array<!s8i x 5>>
// CIR: %[[RET_ADDR:.*]] = cir.alloca !cir.ptr<!cir.array<!s8i x 5>>, !cir.ptr<!cir.ptr<!cir.array<!s8i x 5>>>, ["__retval"]
-// CIR: %[[STR_ADDR:.*]] = cir.get_global @[[STR1_GLOBAL]] : !cir.ptr<!cir.array<!s8i x 5>>
+// CIR: %[[STR_ADDR:.*]] = cir.get_global @[[STR5_GLOBAL]] : !cir.ptr<!cir.array<!s8i x 5>>
// CIR: cir.store{{.*}} %[[STR_ADDR]], %[[RET_ADDR]]
// CIR: %[[RET:.*]] = cir.load %[[RET_ADDR]]
// CIR: cir.return %[[RET]]
>From 42be3d186e1aa55b6c4f7ebac86e4a2ac79d8f93 Mon Sep 17 00:00:00 2001
From: Morris Hafner <mmha at users.noreply.github.com>
Date: Tue, 19 Aug 2025 18:46:51 +0200
Subject: [PATCH 2/2] Update clang/lib/CIR/CodeGen/CIRGenModule.cpp
Co-authored-by: Andy Kaylor <akaylor at nvidia.com>
---
clang/lib/CIR/CodeGen/CIRGenModule.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index cb8cc30835f62..49f5f3ce4368d 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -1323,8 +1323,7 @@ cir::GlobalViewAttr
CIRGenModule::getAddrOfConstantStringFromLiteral(const StringLiteral *s,
StringRef name) {
cir::GlobalOp gv = getGlobalForStringLiteral(s, name);
- auto arrayTy = mlir::dyn_cast<cir::ArrayType>(gv.getSymType());
- assert(arrayTy && "String literal must be array");
+ auto arrayTy = mlir::cast<cir::ArrayType>(gv.getSymType());
assert(!cir::MissingFeatures::addressSpace());
cir::PointerType ptrTy = getBuilder().getPointerTo(arrayTy.getElementType());
More information about the llvm-branch-commits
mailing list