[clang] [CIR][CIRGen] Support for section atttribute on cir.global (PR #188200)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Mar 30 23:47:46 PDT 2026
https://github.com/skc7 updated https://github.com/llvm/llvm-project/pull/188200
>From 2d1026139537d680f6a1983c022664e25741d2d5 Mon Sep 17 00:00:00 2001
From: skc7 <Krishna.Sankisa at amd.com>
Date: Tue, 24 Mar 2026 15:00:31 +0530
Subject: [PATCH 1/4] [CIR][CIRGen] Support for section atttribute
---
clang/include/clang/CIR/Dialect/IR/CIROps.td | 8 +++-
clang/include/clang/CIR/MissingFeatures.h | 1 -
clang/lib/CIR/CodeGen/CIRGenModule.cpp | 23 +++++++++--
.../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 39 ++++++++++++-------
clang/test/CIR/CodeGen/global-section.c | 14 +++++++
5 files changed, 67 insertions(+), 18 deletions(-)
create mode 100644 clang/test/CIR/CodeGen/global-section.c
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 329939dc1b2e9..0212dfb14a602 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -2842,7 +2842,9 @@ def CIR_GlobalOp : CIR_Op<"global", [
UnitAttr:$dso_local,
OptionalAttr<CIR_StaticLocalGuardAttr>:$static_local_guard,
OptionalAttr<I64Attr>:$alignment,
- OptionalAttr<ASTVarDeclInterface>:$ast);
+ OptionalAttr<ASTVarDeclInterface>:$ast,
+ OptionalAttr<StrAttr>:$section
+ );
let regions = (region MaxSizedRegion<1>:$ctorRegion,
MaxSizedRegion<1>:$dtorRegion);
@@ -2901,6 +2903,10 @@ def CIR_GlobalOp : CIR_Op<"global", [
void setupRegionInitializedLLVMGlobalOp(
cir::GlobalOp op, mlir::ConversionPatternRewriter &rewriter) const;
+ llvm::SmallVector<mlir::NamedAttribute> lowerGlobalAttributes(
+ cir::GlobalOp op,
+ mlir::ConversionPatternRewriter &rewriter) const;
+
mutable mlir::LLVM::ComdatOp comdatOp = nullptr;
mlir::SymbolRefAttr getComdatAttr(cir::GlobalOp &op,
mlir::OpBuilder &builder) const;
diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h
index 5051044eb5d50..7e4bcfe91216d 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -31,7 +31,6 @@ struct MissingFeatures {
static bool opGlobalThreadLocal() { return false; }
static bool opGlobalWeakRef() { return false; }
static bool opGlobalUnnamedAddr() { return false; }
- static bool opGlobalSection() { return false; }
static bool opGlobalVisibility() { return false; }
static bool opGlobalDLLImportExport() { return false; }
static bool opGlobalPartition() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index de68927089873..f5e36925142d7 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -664,8 +664,15 @@ void CIRGenModule::setCommonAttributes(GlobalDecl gd, mlir::Operation *gv) {
void CIRGenModule::setNonAliasAttributes(GlobalDecl gd, mlir::Operation *op) {
setCommonAttributes(gd, op);
+ const Decl *d = gd.getDecl();
+ if (d) {
+ if (auto globalOp = mlir::dyn_cast<cir::GlobalOp>(op)) {
+ if (const auto *sa = d->getAttr<SectionAttr>())
+ globalOp.setSectionAttr(builder.getStringAttr(sa->getName()));
+ }
+ }
+
assert(!cir::MissingFeatures::opGlobalUsedOrCompilerUsed());
- assert(!cir::MissingFeatures::opGlobalSection());
assert(!cir::MissingFeatures::opFuncCPUAndFeaturesAttributes());
assert(!cir::MissingFeatures::opFuncSection());
@@ -991,7 +998,11 @@ CIRGenModule::getOrCreateCIRGlobal(StringRef mangledName, mlir::Type ty,
errorNYI(d->getSourceRange(),
"getOrCreateCIRGlobal: MS static data member inline definition");
- assert(!cir::MissingFeatures::opGlobalSection());
+ // Emit section information for extern variables.
+ if (d->hasExternalStorage()) {
+ if (const SectionAttr *sa = d->getAttr<SectionAttr>())
+ gv.setSectionAttr(builder.getStringAttr(sa->getName()));
+ }
gv.setGlobalVisibilityAttr(getGlobalVisibilityAttrFromDecl(d));
// Handle XCore specific ABI requirements.
@@ -1243,7 +1254,13 @@ void CIRGenModule::emitGlobalVarDefinition(const clang::VarDecl *vd,
vd->getType().isConstantStorage(astContext,
/*ExcludeCtor=*/true,
/*ExcludeDtor=*/true)));
- assert(!cir::MissingFeatures::opGlobalSection());
+ // If it is in a read-only section, mark it 'constant'.
+ if (const SectionAttr *sa = vd->getAttr<SectionAttr>()) {
+ gv.setSectionAttr(getBuilder().getStringAttr(sa->getName()));
+ const ASTContext::SectionInfo &si = astContext.SectionInfos[sa->getName()];
+ if ((si.SectionFlags & ASTContext::PSF_Write) == 0)
+ gv.setConstant(true);
+ }
// Set CIR linkage and DLL storage class.
gv.setLinkage(linkage);
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index ba89fbe3091bc..d8414a7c3ed11 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -2566,6 +2566,26 @@ mlir::LogicalResult CIRToLLVMGetGlobalOpLowering::matchAndRewrite(
return mlir::success();
}
+llvm::SmallVector<mlir::NamedAttribute>
+CIRToLLVMGlobalOpLowering::lowerGlobalAttributes(
+ cir::GlobalOp op, mlir::ConversionPatternRewriter &rewriter) const {
+ SmallVector<mlir::NamedAttribute> attributes;
+
+ if (auto sectionAttr = op.getSectionAttr())
+ attributes.push_back(rewriter.getNamedAttr("section", sectionAttr));
+
+ mlir::LLVM::VisibilityAttr visibility = mlir::LLVM::VisibilityAttr::get(
+ getContext(), lowerCIRVisibilityToLLVMVisibility(
+ op.getGlobalVisibilityAttr().getValue()));
+ attributes.push_back(rewriter.getNamedAttr("visibility_", visibility));
+
+ if (op->getAttr(CUDAExternallyInitializedAttr::getMnemonic()))
+ attributes.push_back(rewriter.getNamedAttr("externally_initialized",
+ rewriter.getUnitAttr()));
+
+ return attributes;
+}
+
/// Replace CIR global with a region initialized LLVM global and update
/// insertion point to the end of the initializer block.
void CIRToLLVMGlobalOpLowering::setupRegionInitializedLLVMGlobalOp(
@@ -2589,7 +2609,9 @@ void CIRToLLVMGlobalOpLowering::setupRegionInitializedLLVMGlobalOp(
const StringRef symbol = op.getSymName();
mlir::SymbolRefAttr comdatAttr = getComdatAttr(op, rewriter);
- SmallVector<mlir::NamedAttribute> attributes;
+ SmallVector<mlir::NamedAttribute> attributes =
+ lowerGlobalAttributes(op, rewriter);
+
mlir::LLVM::GlobalOp newGlobalOp =
rewriter.replaceOpWithNewOp<mlir::LLVM::GlobalOp>(
op, llvmType, isConst, linkage, symbol, nullptr, alignment, addrSpace,
@@ -2650,14 +2672,8 @@ mlir::LogicalResult CIRToLLVMGlobalOpLowering::matchAndRewrite(
const uint64_t alignment = op.getAlignment().value_or(0);
const mlir::LLVM::Linkage linkage = convertLinkage(op.getLinkage());
const StringRef symbol = op.getSymName();
- SmallVector<mlir::NamedAttribute> attributes;
-
- // Mark externally_initialized for __device__ and __constant__
- if (auto extInit =
- op->getAttr(CUDAExternallyInitializedAttr::getMnemonic())) {
- attributes.push_back(rewriter.getNamedAttr("externally_initialized",
- rewriter.getUnitAttr()));
- }
+ SmallVector<mlir::NamedAttribute> attributes =
+ lowerGlobalAttributes(op, rewriter);
if (init.has_value()) {
if (mlir::isa<cir::FPAttr, cir::IntAttr, cir::BoolAttr>(init.value())) {
@@ -2688,13 +2704,10 @@ mlir::LogicalResult CIRToLLVMGlobalOpLowering::matchAndRewrite(
}
}
- mlir::LLVM::Visibility visibility =
- lowerCIRVisibilityToLLVMVisibility(op.getGlobalVisibility());
mlir::SymbolRefAttr comdatAttr = getComdatAttr(op, rewriter);
- auto newOp = rewriter.replaceOpWithNewOp<mlir::LLVM::GlobalOp>(
+ rewriter.replaceOpWithNewOp<mlir::LLVM::GlobalOp>(
op, llvmType, isConst, linkage, symbol, init.value_or(mlir::Attribute()),
alignment, addrSpace, isDsoLocal, isThreadLocal, comdatAttr, attributes);
- newOp.setVisibility_(visibility);
return mlir::success();
}
diff --git a/clang/test/CIR/CodeGen/global-section.c b/clang/test/CIR/CodeGen/global-section.c
new file mode 100644
index 0000000000000..f82c085b73312
--- /dev/null
+++ b/clang/test/CIR/CodeGen/global-section.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o - | FileCheck %s --check-prefix=CIR
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o - | FileCheck %s --check-prefix=LLVM
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=LLVM
+
+extern int __attribute__((section(".shared"))) ext;
+int getExt(void) {
+ return ext;
+}
+// CIR: cir.global "private" external @ext : !s32i {{{.*}}section = ".shared"}
+// LLVM: @ext = external global i32, section ".shared"
+
+int __attribute__((section(".shared"))) glob = 42;
+// CIR: cir.global external @glob = #cir.int<42> : !s32i {{{.*}}section = ".shared"}
+// LLVM: @glob = global i32 42, section ".shared"
>From 8179135cc9d431cc895e08db910fe81b1dc93126 Mon Sep 17 00:00:00 2001
From: skc7 <Krishna.Sankisa at amd.com>
Date: Fri, 27 Mar 2026 11:45:58 +0530
Subject: [PATCH 2/4] update CIRGlobalValueInterface for section
---
.../clang/CIR/Interfaces/CIROpInterfaces.td | 16 ++++++++++++++++
clang/include/clang/CIR/MissingFeatures.h | 1 -
clang/lib/CIR/CodeGen/CIRGenModule.cpp | 5 ++---
3 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/clang/include/clang/CIR/Interfaces/CIROpInterfaces.td b/clang/include/clang/CIR/Interfaces/CIROpInterfaces.td
index 41885d4df8f20..898e28964eef0 100644
--- a/clang/include/clang/CIR/Interfaces/CIROpInterfaces.td
+++ b/clang/include/clang/CIR/Interfaces/CIROpInterfaces.td
@@ -155,6 +155,22 @@ let cppNamespace = "::cir" in {
/*defaultImplementation=*/[{
return cir::isWeakForLinker($_op.getLinkage());
}]
+ >,
+ InterfaceMethod<"",
+ "void", "setSection", (ins "mlir::StringAttr":$val), [{}],
+ /*defaultImplementation=*/[{
+ if (val)
+ $_op->setAttr("section", val);
+ else
+ $_op->removeAttr("section");
+ }]
+ >,
+ InterfaceMethod<"",
+ "mlir::StringAttr", "getSectionAttr", (ins), [{}],
+ /*defaultImplementation=*/[{
+ return mlir::dyn_cast_if_present<mlir::StringAttr>(
+ $_op->getAttr("section"));
+ }]
>
];
let extraClassDeclaration = [{
diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h
index 7e4bcfe91216d..7227dbd2c60f7 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -85,7 +85,6 @@ struct MissingFeatures {
static bool opFuncOptNoneAttr() { return false; }
static bool opFuncParameterAttributes() { return false; }
static bool opFuncReadOnly() { return false; }
- static bool opFuncSection() { return false; }
static bool opFuncUnwindTablesAttr() { return false; }
static bool opFuncWillReturn() { return false; }
static bool opFuncNoReturn() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index f5e36925142d7..982983b78c33b 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -666,9 +666,9 @@ void CIRGenModule::setNonAliasAttributes(GlobalDecl gd, mlir::Operation *op) {
const Decl *d = gd.getDecl();
if (d) {
- if (auto globalOp = mlir::dyn_cast<cir::GlobalOp>(op)) {
+ if (auto gvi = mlir::dyn_cast<cir::CIRGlobalValueInterface>(op)) {
if (const auto *sa = d->getAttr<SectionAttr>())
- globalOp.setSectionAttr(builder.getStringAttr(sa->getName()));
+ gvi.setSection(builder.getStringAttr(sa->getName()));
}
}
@@ -1256,7 +1256,6 @@ void CIRGenModule::emitGlobalVarDefinition(const clang::VarDecl *vd,
/*ExcludeDtor=*/true)));
// If it is in a read-only section, mark it 'constant'.
if (const SectionAttr *sa = vd->getAttr<SectionAttr>()) {
- gv.setSectionAttr(getBuilder().getStringAttr(sa->getName()));
const ASTContext::SectionInfo &si = astContext.SectionInfos[sa->getName()];
if ((si.SectionFlags & ASTContext::PSF_Write) == 0)
gv.setConstant(true);
>From 08c830ac8c46b801e97293fc42e7598711f4d161 Mon Sep 17 00:00:00 2001
From: skc7 <Krishna.Sankisa at amd.com>
Date: Fri, 27 Mar 2026 15:03:29 +0530
Subject: [PATCH 3/4] remove MissingFeatures::opFuncSection
---
clang/lib/CIR/CodeGen/CIRGenModule.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index 982983b78c33b..a23768c902aa3 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -674,7 +674,6 @@ void CIRGenModule::setNonAliasAttributes(GlobalDecl gd, mlir::Operation *op) {
assert(!cir::MissingFeatures::opGlobalUsedOrCompilerUsed());
assert(!cir::MissingFeatures::opFuncCPUAndFeaturesAttributes());
- assert(!cir::MissingFeatures::opFuncSection());
getTargetCIRGenInfo().setTargetAttributes(gd.getDecl(), op, *this);
}
>From f918f84135349488e078a60e88d5573db0d2d30e Mon Sep 17 00:00:00 2001
From: skc7 <Krishna.Sankisa at amd.com>
Date: Tue, 31 Mar 2026 12:16:17 +0530
Subject: [PATCH 4/4] add opGlobalPragmaClangSection missing feature
---
clang/include/clang/CIR/MissingFeatures.h | 1 +
clang/lib/CIR/CodeGen/CIRGenModule.cpp | 1 +
clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 2 +-
clang/test/CIR/CodeGen/global-section.c | 4 ++++
4 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h
index 7227dbd2c60f7..ebdc75ebe8c35 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -35,6 +35,7 @@ struct MissingFeatures {
static bool opGlobalDLLImportExport() { return false; }
static bool opGlobalPartition() { return false; }
static bool opGlobalUsedOrCompilerUsed() { return false; }
+ static bool opGlobalPragmaClangSection() { return false; }
static bool opGlobalAnnotations() { return false; }
static bool opGlobalCtorPriority() { return false; }
static bool setDSOLocal() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index a23768c902aa3..80fca0f6cd001 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -672,6 +672,7 @@ void CIRGenModule::setNonAliasAttributes(GlobalDecl gd, mlir::Operation *op) {
}
}
+ assert(!cir::MissingFeatures::opGlobalPragmaClangSection());
assert(!cir::MissingFeatures::opGlobalUsedOrCompilerUsed());
assert(!cir::MissingFeatures::opFuncCPUAndFeaturesAttributes());
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index d8414a7c3ed11..b6cb61dbf27cd 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -2571,7 +2571,7 @@ CIRToLLVMGlobalOpLowering::lowerGlobalAttributes(
cir::GlobalOp op, mlir::ConversionPatternRewriter &rewriter) const {
SmallVector<mlir::NamedAttribute> attributes;
- if (auto sectionAttr = op.getSectionAttr())
+ if (mlir::StringAttr sectionAttr = op.getSectionAttr())
attributes.push_back(rewriter.getNamedAttr("section", sectionAttr));
mlir::LLVM::VisibilityAttr visibility = mlir::LLVM::VisibilityAttr::get(
diff --git a/clang/test/CIR/CodeGen/global-section.c b/clang/test/CIR/CodeGen/global-section.c
index f82c085b73312..aa2253e95e767 100644
--- a/clang/test/CIR/CodeGen/global-section.c
+++ b/clang/test/CIR/CodeGen/global-section.c
@@ -12,3 +12,7 @@ int getExt(void) {
int __attribute__((section(".shared"))) glob = 42;
// CIR: cir.global external @glob = #cir.int<42> : !s32i {{{.*}}section = ".shared"}
// LLVM: @glob = global i32 42, section ".shared"
+
+__attribute__((section(".custom_fn"))) void func_in_section(void) {}
+// CIR: cir.func {{.*}}@func_in_section() {{.*}}section = ".custom_fn"
+// LLVM: define {{.*}}@func_in_section(){{.*}}section ".custom_fn"
More information about the cfe-commits
mailing list