[clang] [CIR] Add constant attribute to GlobalOp (PR #154359)
Morris Hafner via cfe-commits
cfe-commits at lists.llvm.org
Tue Aug 19 08:15:40 PDT 2025
https://github.com/mmha created https://github.com/llvm/llvm-project/pull/154359
This patch adds the constant attribute to cir.global, the appropriate lowering to LLVM constant and updates the tests.
>From 50399d0569e01a5a00878afc5d52c27a52e54d4a Mon Sep 17 00:00:00 2001
From: Morris Hafner <mhafner at nvidia.com>
Date: Tue, 19 Aug 2025 16:58:44 +0200
Subject: [PATCH] [CIR] Add constant attribute to GlobalOp
This patch adds the constant attribute to cir.global, the appropriate lowering to LLVM constant and updates the tests.
---
.../clang/CIR/Dialect/Builder/CIRBaseBuilder.h | 4 ++--
clang/include/clang/CIR/Dialect/IR/CIROps.td | 3 +++
clang/lib/CIR/CodeGen/CIRGenBuilder.h | 4 ++--
clang/lib/CIR/CodeGen/CIRGenDecl.cpp | 2 +-
clang/lib/CIR/CodeGen/CIRGenModule.cpp | 10 +++++-----
clang/lib/CIR/CodeGen/CIRGenModule.h | 1 +
clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 5 ++++-
clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 2 +-
clang/test/CIR/CodeGen/builtin_printf.cpp | 8 ++++----
clang/test/CIR/CodeGen/string-literals.c | 12 ++++++------
clang/test/CIR/CodeGen/string-literals.cpp | 4 ++--
11 files changed, 31 insertions(+), 24 deletions(-)
diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index 1def6457e156c..5b72745ea69c7 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -252,11 +252,11 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
[[nodiscard]] cir::GlobalOp createGlobal(mlir::ModuleOp mlirModule,
mlir::Location loc,
mlir::StringRef name,
- mlir::Type type,
+ mlir::Type type, bool isConstant,
cir::GlobalLinkageKind linkage) {
mlir::OpBuilder::InsertionGuard guard(*this);
setInsertionPointToStart(mlirModule.getBody());
- return create<cir::GlobalOp>(loc, name, type, linkage);
+ return create<cir::GlobalOp>(loc, name, type, isConstant, linkage);
}
cir::GetMemberOp createGetMember(mlir::Location loc, mlir::Type resultTy,
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 369bcb1ddb1bb..55371425b0b73 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -1702,12 +1702,14 @@ def CIR_GlobalOp : CIR_Op<"global", [
CIR_GlobalLinkageKind:$linkage,
OptionalAttr<AnyAttr>:$initial_value,
UnitAttr:$comdat,
+ UnitAttr:$constant,
UnitAttr:$dso_local,
OptionalAttr<I64Attr>:$alignment);
let assemblyFormat = [{
($sym_visibility^)?
(`` $global_visibility^)?
+ (`constant` $constant^)?
$linkage
(`comdat` $comdat^)?
(`dso_local` $dso_local^)?
@@ -1726,6 +1728,7 @@ def CIR_GlobalOp : CIR_Op<"global", [
let builders = [OpBuilder<(ins
"llvm::StringRef":$sym_name,
"mlir::Type":$sym_type,
+ CArg<"bool", "false">:$isConstant,
// CIR defaults to external linkage.
CArg<"cir::GlobalLinkageKind",
"cir::GlobalLinkageKind::ExternalLinkage">:$linkage)>];
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
index c1088c4cd0821..17e18d5e6aaf3 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h
+++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
@@ -422,7 +422,7 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
/// for its name so it can be referenced correctly.
[[nodiscard]] cir::GlobalOp
createVersionedGlobal(mlir::ModuleOp module, mlir::Location loc,
- mlir::StringRef name, mlir::Type type,
+ mlir::StringRef name, mlir::Type type, bool isConstant,
cir::GlobalLinkageKind linkage) {
// Create a unique name if the given name is already taken.
std::string uniqueName;
@@ -431,7 +431,7 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
else
uniqueName = name.str();
- return createGlobal(module, loc, uniqueName, type, linkage);
+ return createGlobal(module, loc, uniqueName, type, isConstant, linkage);
}
mlir::Value createSetBitfield(mlir::Location loc, mlir::Type resultType,
diff --git a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
index f8e051e52dbae..7cc024fd5596c 100644
--- a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
@@ -297,7 +297,7 @@ CIRGenModule::getOrCreateStaticVarDecl(const VarDecl &d,
mlir::Attribute init = builder.getZeroInitAttr(convertType(ty));
cir::GlobalOp gv = builder.createVersionedGlobal(
- getModule(), getLoc(d.getLocation()), name, lty, linkage);
+ getModule(), getLoc(d.getLocation()), name, lty, false, linkage);
// TODO(cir): infer visibility from linkage in global op builder.
gv.setVisibility(getMLIRVisibilityFromCIRLinkage(linkage));
gv.setInitialValueAttr(init);
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index d5296881540aa..7c52adcfa56c7 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -458,7 +458,7 @@ mlir::Operation *CIRGenModule::getGlobalValue(StringRef name) {
cir::GlobalOp CIRGenModule::createGlobalOp(CIRGenModule &cgm,
mlir::Location loc, StringRef name,
- mlir::Type t,
+ mlir::Type t, bool isConstant,
mlir::Operation *insertPoint) {
cir::GlobalOp g;
CIRGenBuilderTy &builder = cgm.getBuilder();
@@ -479,7 +479,7 @@ cir::GlobalOp CIRGenModule::createGlobalOp(CIRGenModule &cgm,
builder.setInsertionPointToStart(cgm.getModule().getBody());
}
- g = builder.create<cir::GlobalOp>(loc, name, t);
+ g = builder.create<cir::GlobalOp>(loc, name, t, isConstant);
if (!insertPoint)
cgm.lastGlobalOp = g;
@@ -581,7 +581,7 @@ CIRGenModule::getOrCreateCIRGlobal(StringRef mangledName, mlir::Type ty,
// mlir::SymbolTable::Visibility::Public is the default, no need to explicitly
// mark it as such.
cir::GlobalOp gv =
- CIRGenModule::createGlobalOp(*this, loc, mangledName, ty,
+ CIRGenModule::createGlobalOp(*this, loc, mangledName, ty, false,
/*insertPoint=*/entry.getOperation());
// This is the first use or definition of a mangled name. If there is a
@@ -1239,8 +1239,8 @@ generateStringLiteral(mlir::Location loc, mlir::TypedAttr c,
// Create a global variable for this string
// FIXME(cir): check for insertion point in module level.
- cir::GlobalOp gv =
- CIRGenModule::createGlobalOp(cgm, loc, globalName, c.getType());
+ cir::GlobalOp gv = CIRGenModule::createGlobalOp(
+ cgm, loc, globalName, c.getType(), !cgm.getLangOpts().WritableStrings);
// Set up extra information and add to the module
gv.setAlignmentAttr(cgm.getSize(alignment));
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.h b/clang/lib/CIR/CodeGen/CIRGenModule.h
index 06cc3e09e416b..ce9d0344aa940 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.h
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.h
@@ -150,6 +150,7 @@ class CIRGenModule : public CIRGenTypeCache {
static cir::GlobalOp createGlobalOp(CIRGenModule &cgm, mlir::Location loc,
llvm::StringRef name, mlir::Type t,
+ bool isConstant = false,
mlir::Operation *insertPoint = nullptr);
llvm::StringMap<unsigned> cgGlobalNames;
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index 220927601f74e..461e0b81c407c 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -1358,11 +1358,14 @@ mlir::LogicalResult cir::GlobalOp::verify() {
void cir::GlobalOp::build(OpBuilder &odsBuilder, OperationState &odsState,
llvm::StringRef sym_name, mlir::Type sym_type,
- cir::GlobalLinkageKind linkage) {
+ bool isConstant, cir::GlobalLinkageKind linkage) {
odsState.addAttribute(getSymNameAttrName(odsState.name),
odsBuilder.getStringAttr(sym_name));
odsState.addAttribute(getSymTypeAttrName(odsState.name),
mlir::TypeAttr::get(sym_type));
+ if (isConstant)
+ odsState.addAttribute(getConstantAttrName(odsState.name),
+ odsBuilder.getUnitAttr());
cir::GlobalLinkageKindAttr linkageAttr =
cir::GlobalLinkageKindAttr::get(odsBuilder.getContext(), linkage);
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 9ab7178e9ab12..12e477bf5a243 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -1502,7 +1502,7 @@ void CIRToLLVMGlobalOpLowering::setupRegionInitializedLLVMGlobalOp(
// in CIRToLLVMGlobalOpLowering::matchAndRewrite() but that will go
// away when the placeholders are no longer needed.
assert(!cir::MissingFeatures::opGlobalConstant());
- const bool isConst = false;
+ const bool isConst = op.getConstant();
assert(!cir::MissingFeatures::addressSpace());
const unsigned addrSpace = 0;
const bool isDsoLocal = op.getDsoLocal();
diff --git a/clang/test/CIR/CodeGen/builtin_printf.cpp b/clang/test/CIR/CodeGen/builtin_printf.cpp
index 43128e44b19e4..80875c349bfcf 100644
--- a/clang/test/CIR/CodeGen/builtin_printf.cpp
+++ b/clang/test/CIR/CodeGen/builtin_printf.cpp
@@ -5,10 +5,10 @@
// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll
// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
-// CIR: cir.global "private" cir_private dso_local @".str" = #cir.const_array<"%s\00" : !cir.array<!s8i x 3>> : !cir.array<!s8i x 3>
-// CIR: cir.global "private" cir_private dso_local @".str.1" = #cir.const_array<"%s %d\0A\00" : !cir.array<!s8i x 7>> : !cir.array<!s8i x 7>
-// LLVM: @.str = private global [3 x i8] c"%s\00"
-// LLVM: @.str.1 = private global [7 x i8] c"%s %d\0A\00"
+// CIR: cir.global "private" constant cir_private dso_local @".str" = #cir.const_array<"%s\00" : !cir.array<!s8i x 3>> : !cir.array<!s8i x 3>
+// CIR: cir.global "private" constant cir_private dso_local @".str.1" = #cir.const_array<"%s %d\0A\00" : !cir.array<!s8i x 7>> : !cir.array<!s8i x 7>
+// LLVM: @.str = private constant [3 x i8] c"%s\00"
+// LLVM: @.str.1 = private constant [7 x i8] c"%s %d\0A\00"
// OGCG: @.str = private unnamed_addr constant [3 x i8] c"%s\00"
// OGCG: @.str.1 = private unnamed_addr constant [7 x i8] c"%s %d\0A\00"
diff --git a/clang/test/CIR/CodeGen/string-literals.c b/clang/test/CIR/CodeGen/string-literals.c
index 44fd191173c33..38657b2cd1175 100644
--- a/clang/test/CIR/CodeGen/string-literals.c
+++ b/clang/test/CIR/CodeGen/string-literals.c
@@ -17,13 +17,13 @@ char g_exact[4] = "123";
// CIR: cir.global external @g_exact = #cir.const_array<"123\00" : !cir.array<!s8i x 4>> : !cir.array<!s8i x 4>
-// CIR: cir.global "private" cir_private dso_local @[[STR1_GLOBAL:.*]] = #cir.const_array<"1\00" : !cir.array<!s8i x 2>> : !cir.array<!s8i x 2>
-// CIR: cir.global "private" cir_private dso_local @[[STR2_GLOBAL:.*]] = #cir.zero : !cir.array<!s8i x 1>
-// CIR: cir.global "private" cir_private dso_local @[[STR3_GLOBAL:.*]] = #cir.zero : !cir.array<!s8i x 2>
+// CIR: cir.global "private" constant cir_private dso_local @[[STR1_GLOBAL:.*]] = #cir.const_array<"1\00" : !cir.array<!s8i x 2>> : !cir.array<!s8i x 2>
+// CIR: cir.global "private" constant cir_private dso_local @[[STR2_GLOBAL:.*]] = #cir.zero : !cir.array<!s8i x 1>
+// CIR: cir.global "private" constant cir_private dso_local @[[STR3_GLOBAL:.*]] = #cir.zero : !cir.array<!s8i x 2>
-// LLVM: @[[STR1_GLOBAL:.*]] = private global [2 x i8] c"1\00"
-// LLVM: @[[STR2_GLOBAL:.*]] = private global [1 x i8] zeroinitializer
-// LLVM: @[[STR3_GLOBAL:.*]] = private global [2 x i8] zeroinitializer
+// LLVM: @[[STR1_GLOBAL:.*]] = private constant [2 x i8] c"1\00"
+// LLVM: @[[STR2_GLOBAL:.*]] = private constant [1 x i8] zeroinitializer
+// LLVM: @[[STR3_GLOBAL:.*]] = private constant [2 x i8] zeroinitializer
// OGCG: @[[STR1_GLOBAL:.*]] = private unnamed_addr constant [2 x i8] c"1\00"
// OGCG: @[[STR2_GLOBAL:.*]] = private unnamed_addr constant [1 x i8] zeroinitializer
diff --git a/clang/test/CIR/CodeGen/string-literals.cpp b/clang/test/CIR/CodeGen/string-literals.cpp
index 081c4c2c5a4a2..a20add08bfc2d 100644
--- a/clang/test/CIR/CodeGen/string-literals.cpp
+++ b/clang/test/CIR/CodeGen/string-literals.cpp
@@ -5,9 +5,9 @@
// 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" cir_private dso_local @[[STR1_GLOBAL:.*]] = #cir.const_array<"abcd\00" : !cir.array<!s8i x 5>> : !cir.array<!s8i x 5>
+// 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 global [5 x i8] c"abcd\00"
+// LLVM: @[[STR1_GLOBAL:.*]] = private constant [5 x i8] c"abcd\00"
// OGCG: @[[STR1_GLOBAL:.*]] = private unnamed_addr constant [5 x i8] c"abcd\00"
More information about the cfe-commits
mailing list