[clang] [CIR] Set alignment correctly in getOrCreateConstAggregateGlobal (PR #216321)
https://github.com/erichkeane closed https://github.com/llvm/llvm-project/pull/216321 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CIR] Set alignment correctly in getOrCreateConstAggregateGlobal (PR #216321)
https://github.com/erichkeane updated
https://github.com/llvm/llvm-project/pull/216321
>From 6a49483b788e05034cacb29440c38911c1959c05 Mon Sep 17 00:00:00 2001
From: erichkeane
Date: Fri, 14 Aug 2026 07:06:01 -0700
Subject: [PATCH] [CIR] Set alignment correctly in
getOrCreateConstAggregateGlobal
Just a drive-by that I discovered while debugging something else, we end
up not getting the 'alignment' of these aggregates set at all. This
patch just wires through the alloca's alignment onto these constants,
which matches classic codegen.
---
.../CIR/Dialect/Transforms/LoweringPrepare.cpp | 16
.../CodeGen/local-const-aggregate-name-clash.cpp | 12 ++--
clang/test/CIR/CodeGen/union-agg-init.c | 6 +++---
3 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp
b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp
index 28ba14962cc7b..3ee7c84781848 100644
--- a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp
+++ b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp
@@ -112,11 +112,10 @@ struct LoweringPreparePass
/// already has a matching type and initial value, that global is reused.
/// Otherwise a new global is created with the next available `.` suffix
/// (matching CIRGenBuilder::createVersionedGlobal and OGCG behavior).
- cir::GlobalOp getOrCreateConstAggregateGlobal(CIRBaseBuilderTy &builder,
-mlir::Location loc,
-llvm::StringRef baseName,
-mlir::Type ty,
-mlir::TypedAttr constant);
+ cir::GlobalOp
+ getOrCreateConstAggregateGlobal(CIRBaseBuilderTy &builder, mlir::Location
loc,
+ llvm::StringRef baseName, mlir::Type ty,
+ mlir::TypedAttr constant, uint64_t
alignment);
/// Build the function that initializes the specified global
cir::FuncOp buildCXXGlobalVarDeclInitFunc(cir::GlobalOp op);
@@ -2147,7 +2146,7 @@ void
LoweringPreparePass::lowerTrivialCopyCall(cir::CallOp op) {
cir::GlobalOp LoweringPreparePass::getOrCreateConstAggregateGlobal(
CIRBaseBuilderTy &builder, mlir::Location loc, llvm::StringRef baseName,
-mlir::Type ty, mlir::TypedAttr constant) {
+mlir::Type ty, mlir::TypedAttr constant, uint64_t alignment) {
// Look up (and lazily populate) the per-base-name cache.
llvm::SmallVector &versions =
constAggregateGlobals[baseName];
@@ -2194,6 +2193,7 @@ cir::GlobalOp
LoweringPreparePass::getOrCreateConstAggregateGlobal(
mlir::SymbolTable::setSymbolVisibility(
gv, mlir::SymbolTable::Visibility::Private);
gv.setInitialValueAttr(constant);
+ gv.setAlignment(alignment);
// Keep the cached symbol table in sync with the new global so subsequent
// lookups for other base names find it.
@@ -2245,8 +2245,8 @@ void
LoweringPreparePass::lowerStoreOfConstAggregate(cir::StoreOp op) {
// Check for existing globals and create a new global with a unique name
// if no match is found.
- cir::GlobalOp gv = getOrCreateConstAggregateGlobal(builder, op.getLoc(),
- baseName, ty, constant);
+ cir::GlobalOp gv = getOrCreateConstAggregateGlobal(
+ builder, op.getLoc(), baseName, ty, constant, alloca.getAlignment());
// Now replace the store with get_global + copy.
builder.setInsertionPoint(op);
diff --git a/clang/test/CIR/CodeGen/local-const-aggregate-name-clash.cpp
b/clang/test/CIR/CodeGen/local-const-aggregate-name-clash.cpp
index 411c80ab1d016..f8ecb371c43a9 100644
--- a/clang/test/CIR/CodeGen/local-const-aggregate-name-clash.cpp
+++ b/clang/test/CIR/CodeGen/local-const-aggregate-name-clash.cpp
@@ -23,22 +23,22 @@ void f(bool which) {
}
}
-// CIR-DAG: cir.global "private" constant cir_private @[[GV0:.*]] =
#cir.const_array<[#cir.int<10> : !s32i, #cir.int<20> : !s32i, #cir.int<30> :
!s32i, #cir.int<40> : !s32i]> : !cir.array
-// CIR-DAG: cir.global "private" constant cir_private @[[GV1:.*]] =
#cir.const_array<[#cir.int<50> : !s32i, #cir.int<60> : !s32i]> :
!cir.array
+// CIR-DAG: cir.global "private" constant cir_private @[[GV0:.*]] =
#cir.const_array<[#cir.int<10> : !s32i, #cir.int<20> : !s32i, #cir.int<30> :
!s32i, #cir.int<40> : !s32i]> : !cir.array {alignment = 16 : i64}
+// CIR-DAG: cir.global "private" constant cir_private @[[GV1:.*]] =
#cir.const_array<[#cir.int<50> : !s32i, #cir.int<60> : !s32i]> :
!cir.array {alignment = 4 : i64}
// CIR: cir.func{{.*}} @_Z1fb
// CIR: cir.get_global @[[GV0]] : !cir.ptr>
// CIR: cir.get_global @[[GV1]] : !cir.ptr>
-// LLVM-DAG: @[[GV0:.*]] = private constant [4 x i32] [i32 10, i32 20, i32 30,
i32 40]
-// LLVM-DAG: @[[GV1:.*]] = private constant [2 x i32] [i32 50, i32 60]
+// LLVM-DAG: @[[GV0:.*]] = private constant [4 x i32] [i32 10, i32 20, i32
[clang] [CIR] Set alignment correctly in getOrCreateConstAggregateGlobal (PR #216321)
llvmorg-github-actions[bot] wrote:
@llvm/pr-subscribers-clang
Author: Erich Keane (erichkeane)
Changes
Just a drive-by that I discovered while debugging something else, we end up not
getting the 'alignment' of these aggregates set at all. This patch just wires
through the alloca's alignment onto these constants, which matches classic
codegen.
---
Full diff: https://github.com/llvm/llvm-project/pull/216321.diff
3 Files Affected:
- (modified) clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp (+8-8)
- (modified) clang/test/CIR/CodeGen/local-const-aggregate-name-clash.cpp (+6-6)
- (modified) clang/test/CIR/CodeGen/union-agg-init.c (+3-3)
``diff
diff --git a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp
b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp
index 28ba14962cc7b..3ee7c84781848 100644
--- a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp
+++ b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp
@@ -112,11 +112,10 @@ struct LoweringPreparePass
/// already has a matching type and initial value, that global is reused.
/// Otherwise a new global is created with the next available `.` suffix
/// (matching CIRGenBuilder::createVersionedGlobal and OGCG behavior).
- cir::GlobalOp getOrCreateConstAggregateGlobal(CIRBaseBuilderTy &builder,
-mlir::Location loc,
-llvm::StringRef baseName,
-mlir::Type ty,
-mlir::TypedAttr constant);
+ cir::GlobalOp
+ getOrCreateConstAggregateGlobal(CIRBaseBuilderTy &builder, mlir::Location
loc,
+ llvm::StringRef baseName, mlir::Type ty,
+ mlir::TypedAttr constant, uint64_t
alignment);
/// Build the function that initializes the specified global
cir::FuncOp buildCXXGlobalVarDeclInitFunc(cir::GlobalOp op);
@@ -2147,7 +2146,7 @@ void
LoweringPreparePass::lowerTrivialCopyCall(cir::CallOp op) {
cir::GlobalOp LoweringPreparePass::getOrCreateConstAggregateGlobal(
CIRBaseBuilderTy &builder, mlir::Location loc, llvm::StringRef baseName,
-mlir::Type ty, mlir::TypedAttr constant) {
+mlir::Type ty, mlir::TypedAttr constant, uint64_t alignment) {
// Look up (and lazily populate) the per-base-name cache.
llvm::SmallVector &versions =
constAggregateGlobals[baseName];
@@ -2194,6 +2193,7 @@ cir::GlobalOp
LoweringPreparePass::getOrCreateConstAggregateGlobal(
mlir::SymbolTable::setSymbolVisibility(
gv, mlir::SymbolTable::Visibility::Private);
gv.setInitialValueAttr(constant);
+ gv.setAlignment(alignment);
// Keep the cached symbol table in sync with the new global so subsequent
// lookups for other base names find it.
@@ -2245,8 +2245,8 @@ void
LoweringPreparePass::lowerStoreOfConstAggregate(cir::StoreOp op) {
// Check for existing globals and create a new global with a unique name
// if no match is found.
- cir::GlobalOp gv = getOrCreateConstAggregateGlobal(builder, op.getLoc(),
- baseName, ty, constant);
+ cir::GlobalOp gv = getOrCreateConstAggregateGlobal(
+ builder, op.getLoc(), baseName, ty, constant, alloca.getAlignment());
// Now replace the store with get_global + copy.
builder.setInsertionPoint(op);
diff --git a/clang/test/CIR/CodeGen/local-const-aggregate-name-clash.cpp
b/clang/test/CIR/CodeGen/local-const-aggregate-name-clash.cpp
index 411c80ab1d016..f8ecb371c43a9 100644
--- a/clang/test/CIR/CodeGen/local-const-aggregate-name-clash.cpp
+++ b/clang/test/CIR/CodeGen/local-const-aggregate-name-clash.cpp
@@ -23,22 +23,22 @@ void f(bool which) {
}
}
-// CIR-DAG: cir.global "private" constant cir_private @[[GV0:.*]] =
#cir.const_array<[#cir.int<10> : !s32i, #cir.int<20> : !s32i, #cir.int<30> :
!s32i, #cir.int<40> : !s32i]> : !cir.array
-// CIR-DAG: cir.global "private" constant cir_private @[[GV1:.*]] =
#cir.const_array<[#cir.int<50> : !s32i, #cir.int<60> : !s32i]> :
!cir.array
+// CIR-DAG: cir.global "private" constant cir_private @[[GV0:.*]] =
#cir.const_array<[#cir.int<10> : !s32i, #cir.int<20> : !s32i, #cir.int<30> :
!s32i, #cir.int<40> : !s32i]> : !cir.array {alignment = 16 : i64}
+// CIR-DAG: cir.global "private" constant cir_private @[[GV1:.*]] =
#cir.const_array<[#cir.int<50> : !s32i, #cir.int<60> : !s32i]> :
!cir.array {alignment = 4 : i64}
// CIR: cir.func{{.*}} @_Z1fb
// CIR: cir.get_global @[[GV0]] : !cir.ptr>
// CIR: cir.get_global @[[GV1]] : !cir.ptr>
-// LLVM-DAG: @[[GV0:.*]] = private constant [4 x i32] [i32 10, i32 20, i32 30,
i32 40]
-// LLVM-DAG: @[[GV1:.*]] = private constant [2 x i32] [i32 50, i32 60]
+// LLVM-DAG: @[[GV0:.*]] = private constant [4 x i32] [i32 10, i32 20, i32 30,
i32 40], align 16
+// LLVM-DAG: @[[GV1:.*]] = private constant [2 x i32] [i32 50, i32 60], align 4
// LLVM:
[clang] [CIR] Set alignment correctly in getOrCreateConstAggregateGlobal (PR #216321)
https://github.com/erichkeane created
https://github.com/llvm/llvm-project/pull/216321
Just a drive-by that I discovered while debugging something else, we end up not
getting the 'alignment' of these aggregates set at all. This patch just wires
through the alloca's alignment onto these constants, which matches classic
codegen.
>From 6a49483b788e05034cacb29440c38911c1959c05 Mon Sep 17 00:00:00 2001
From: erichkeane
Date: Fri, 14 Aug 2026 07:06:01 -0700
Subject: [PATCH] [CIR] Set alignment correctly in
getOrCreateConstAggregateGlobal
Just a drive-by that I discovered while debugging something else, we end
up not getting the 'alignment' of these aggregates set at all. This
patch just wires through the alloca's alignment onto these constants,
which matches classic codegen.
---
.../CIR/Dialect/Transforms/LoweringPrepare.cpp | 16
.../CodeGen/local-const-aggregate-name-clash.cpp | 12 ++--
clang/test/CIR/CodeGen/union-agg-init.c | 6 +++---
3 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp
b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp
index 28ba14962cc7b..3ee7c84781848 100644
--- a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp
+++ b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp
@@ -112,11 +112,10 @@ struct LoweringPreparePass
/// already has a matching type and initial value, that global is reused.
/// Otherwise a new global is created with the next available `.` suffix
/// (matching CIRGenBuilder::createVersionedGlobal and OGCG behavior).
- cir::GlobalOp getOrCreateConstAggregateGlobal(CIRBaseBuilderTy &builder,
-mlir::Location loc,
-llvm::StringRef baseName,
-mlir::Type ty,
-mlir::TypedAttr constant);
+ cir::GlobalOp
+ getOrCreateConstAggregateGlobal(CIRBaseBuilderTy &builder, mlir::Location
loc,
+ llvm::StringRef baseName, mlir::Type ty,
+ mlir::TypedAttr constant, uint64_t
alignment);
/// Build the function that initializes the specified global
cir::FuncOp buildCXXGlobalVarDeclInitFunc(cir::GlobalOp op);
@@ -2147,7 +2146,7 @@ void
LoweringPreparePass::lowerTrivialCopyCall(cir::CallOp op) {
cir::GlobalOp LoweringPreparePass::getOrCreateConstAggregateGlobal(
CIRBaseBuilderTy &builder, mlir::Location loc, llvm::StringRef baseName,
-mlir::Type ty, mlir::TypedAttr constant) {
+mlir::Type ty, mlir::TypedAttr constant, uint64_t alignment) {
// Look up (and lazily populate) the per-base-name cache.
llvm::SmallVector &versions =
constAggregateGlobals[baseName];
@@ -2194,6 +2193,7 @@ cir::GlobalOp
LoweringPreparePass::getOrCreateConstAggregateGlobal(
mlir::SymbolTable::setSymbolVisibility(
gv, mlir::SymbolTable::Visibility::Private);
gv.setInitialValueAttr(constant);
+ gv.setAlignment(alignment);
// Keep the cached symbol table in sync with the new global so subsequent
// lookups for other base names find it.
@@ -2245,8 +2245,8 @@ void
LoweringPreparePass::lowerStoreOfConstAggregate(cir::StoreOp op) {
// Check for existing globals and create a new global with a unique name
// if no match is found.
- cir::GlobalOp gv = getOrCreateConstAggregateGlobal(builder, op.getLoc(),
- baseName, ty, constant);
+ cir::GlobalOp gv = getOrCreateConstAggregateGlobal(
+ builder, op.getLoc(), baseName, ty, constant, alloca.getAlignment());
// Now replace the store with get_global + copy.
builder.setInsertionPoint(op);
diff --git a/clang/test/CIR/CodeGen/local-const-aggregate-name-clash.cpp
b/clang/test/CIR/CodeGen/local-const-aggregate-name-clash.cpp
index 411c80ab1d016..f8ecb371c43a9 100644
--- a/clang/test/CIR/CodeGen/local-const-aggregate-name-clash.cpp
+++ b/clang/test/CIR/CodeGen/local-const-aggregate-name-clash.cpp
@@ -23,22 +23,22 @@ void f(bool which) {
}
}
-// CIR-DAG: cir.global "private" constant cir_private @[[GV0:.*]] =
#cir.const_array<[#cir.int<10> : !s32i, #cir.int<20> : !s32i, #cir.int<30> :
!s32i, #cir.int<40> : !s32i]> : !cir.array
-// CIR-DAG: cir.global "private" constant cir_private @[[GV1:.*]] =
#cir.const_array<[#cir.int<50> : !s32i, #cir.int<60> : !s32i]> :
!cir.array
+// CIR-DAG: cir.global "private" constant cir_private @[[GV0:.*]] =
#cir.const_array<[#cir.int<10> : !s32i, #cir.int<20> : !s32i, #cir.int<30> :
!s32i, #cir.int<40> : !s32i]> : !cir.array {alignment = 16 : i64}
+// CIR-DAG: cir.global "private" constant cir_private @[[GV1:.*]] =
#cir.const_array<[#cir.int<50> : !s32i, #cir.int<60> : !s32i]> :
!cir.array {alignment = 4 : i64}
// CIR: cir.func{{.*}} @_Z1fb
// CIR: cir.get_global @[[GV0]] : !cir.ptr>
// CIR: cir.get_global @[[GV1]] :
