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 <[email protected]>
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 `.<n>` 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<cir::GlobalOp, 1> &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<!s32i x 4>
-// CIR-DAG: cir.global "private" constant cir_private @[[GV1:.*]] = 
#cir.const_array<[#cir.int<50> : !s32i, #cir.int<60> : !s32i]> : 
!cir.array<!s32i x 2>
+// 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<!s32i x 4> {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<!s32i x 2> {alignment = 4 : i64}
 
 // CIR: cir.func{{.*}} @_Z1fb
 // CIR:   cir.get_global @[[GV0]] : !cir.ptr<!cir.array<!s32i x 4>>
 // CIR:   cir.get_global @[[GV1]] : !cir.ptr<!cir.array<!s32i x 2>>
 
-// 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: define{{.*}} @_Z1fb
 // LLVM:   call void @llvm.memcpy.p0.p0.i64(ptr {{[^,]+}}, ptr align 4 
@[[GV0]], i64 16, i1 false)
 // LLVM:   call void @llvm.memcpy.p0.p0.i64(ptr {{[^,]+}}, ptr align 4 
@[[GV1]], i64 8, i1 false)
 
-// OGCG-DAG: @[[GV0:.*]] = private unnamed_addr constant [4 x i32] [i32 10, 
i32 20, i32 30, i32 40]
-// OGCG-DAG: @[[GV1:.*]] = private unnamed_addr constant [2 x i32] [i32 50, 
i32 60]
+// OGCG-DAG: @[[GV0:.*]] = private unnamed_addr constant [4 x i32] [i32 10, 
i32 20, i32 30, i32 40], align 16
+// OGCG-DAG: @[[GV1:.*]] = private unnamed_addr constant [2 x i32] [i32 50, 
i32 60], align 4
 
 // OGCG: define{{.*}} @_Z1fb
 // OGCG:   call void @llvm.memcpy.p0.p0.i64(ptr {{[^,]+}}, ptr 
{{[^,]+}}@[[GV0]], i64 16, i1 false)
diff --git a/clang/test/CIR/CodeGen/union-agg-init.c 
b/clang/test/CIR/CodeGen/union-agg-init.c
index ab603d24d8712..af966b499b994 100644
--- a/clang/test/CIR/CodeGen/union-agg-init.c
+++ b/clang/test/CIR/CodeGen/union-agg-init.c
@@ -10,10 +10,10 @@ typedef union vec3 {
   double component[3];
 } vec3;
 
-// LLVMCIR: @__const.ret_outer.__retval = {{.*}}%struct.outer { 
%union.needs_padding zeroinitializer, i32 1 }
-// OGCG: @__const.ret_outer.o = {{.*}}{ { i32, [4 x i8] }, i32, [4 x i8] } { { 
i32, [4 x i8] } zeroinitializer, i32 1, [4 x i8] zeroinitializer }
+// LLVMCIR: @__const.ret_outer.__retval = {{.*}}%struct.outer { 
%union.needs_padding zeroinitializer, i32 1 }, align 8
+// OGCG: @__const.ret_outer.o = {{.*}}{ { i32, [4 x i8] }, i32, [4 x i8] } { { 
i32, [4 x i8] } zeroinitializer, i32 1, [4 x i8] zeroinitializer }, align 8
 
-// CIR: cir.global "private" constant cir_private @__const.ret_outer.__retval 
= #cir.const_record<{#cir.zero : !rec_needs_padding, #cir.int<1> : !s32i}> : 
!rec_outer
+// CIR: cir.global "private" constant cir_private @__const.ret_outer.__retval 
= #cir.const_record<{#cir.zero : !rec_needs_padding, #cir.int<1> : !s32i}> : 
!rec_outer {alignment = 8 : i64}
 
 // In C mode, this does do zero padding.
 vec3 ret_vec3() {

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to