[clang] [CIR] Fix reference alignment to use pointee type (PR #186667)
Henrich Lauko via cfe-commits
cfe-commits at lists.llvm.org
Sun Mar 15 06:24:59 PDT 2026
https://github.com/xlauko created https://github.com/llvm/llvm-project/pull/186667
getNaturalTypeAlignment on a reference type returned pointer alignment
instead of pointee alignment. Pass the pointee type with
forPointeeType=true to match traditional codegen's
getNaturalPointeeTypeAlignment behavior. Fix applies to both argument
and return type attribute construction paths.
>From 0277b448c910fc8201776bec11f7b1445c138992 Mon Sep 17 00:00:00 2001
From: xlauko <xlauko at mail.muni.cz>
Date: Sun, 15 Mar 2026 13:54:42 +0100
Subject: [PATCH] [CIR] Fix reference alignment to use pointee type
getNaturalTypeAlignment on a reference type returned pointer alignment
instead of pointee alignment. Pass the pointee type with
forPointeeType=true to match traditional codegen's
getNaturalPointeeTypeAlignment behavior. Fix applies to both argument
and return type attribute construction paths.
---
clang/lib/CIR/CodeGen/CIRGenCall.cpp | 18 +++++++++++-----
clang/test/CIR/CodeGen/arg-attrs.cpp | 31 ++++++++++++++++++++++++----
2 files changed, 40 insertions(+), 9 deletions(-)
diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.cpp b/clang/lib/CIR/CodeGen/CIRGenCall.cpp
index 1d7f15c569798..10aa3c4af2d3b 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCall.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCall.cpp
@@ -620,7 +620,10 @@ void CIRGenModule::constructFunctionReturnAttributes(
if (pointeeTy->isObjectType())
retAttrs.set(mlir::LLVM::LLVMDialect::getAlignAttrName(),
builder.getI64IntegerAttr(
- getNaturalTypeAlignment(pointeeTy).getQuantity()));
+ getNaturalTypeAlignment(pointeeTy,
+ /*baseInfo=*/nullptr,
+ /*forPointeeType=*/true)
+ .getQuantity()));
}
}
}
@@ -659,7 +662,9 @@ void CIRGenModule::constructFunctionArgumentAttributes(
argAttrs[0].set(mlir::LLVM::LLVMDialect::getAlignAttrName(),
builder.getI64IntegerAttr(
- getNaturalTypeAlignment(thisTy).getQuantity()));
+ getNaturalTypeAlignment(thisTy, /*baseInfo=*/nullptr,
+ /*forPointeeType=*/true)
+ .getQuantity()));
// TODO(cir): the classic codegen has a recently-added bunch of logic for
// 'dead_on_return' as an attribute. This both doesn't exist in the LLVM
@@ -702,9 +707,12 @@ void CIRGenModule::constructFunctionArgumentAttributes(
argAttrList.set(mlir::LLVM::LLVMDialect::getNonNullAttrName(),
mlir::UnitAttr::get(&getMLIRContext()));
if (pointeeTy->isObjectType())
- argAttrList.set(mlir::LLVM::LLVMDialect::getAlignAttrName(),
- builder.getI64IntegerAttr(
- getNaturalTypeAlignment(argType).getQuantity()));
+ argAttrList.set(
+ mlir::LLVM::LLVMDialect::getAlignAttrName(),
+ builder.getI64IntegerAttr(
+ getNaturalTypeAlignment(pointeeTy, /*baseInfo=*/nullptr,
+ /*forPointeeType=*/true)
+ .getQuantity()));
}
}
}
diff --git a/clang/test/CIR/CodeGen/arg-attrs.cpp b/clang/test/CIR/CodeGen/arg-attrs.cpp
index a66cf661dc66c..800b86e602cd0 100644
--- a/clang/test/CIR/CodeGen/arg-attrs.cpp
+++ b/clang/test/CIR/CodeGen/arg-attrs.cpp
@@ -18,18 +18,41 @@ void Struct::this_func(){}
// CIR: cir.func {{.*}}@_ZN6Struct9this_funcEv(%{{.*}}: !cir.ptr<!rec_Struct> {llvm.align = 4 : i64, llvm.dereferenceable = 20 : i64, llvm.nonnull, llvm.noundef} {{.*}}) {
// BOTH: define {{.*}}void @_ZN6Struct9this_funcEv(ptr noundef nonnull align 4 dereferenceable(20) %{{.*}})
void Struct::arg_attr(Struct s, int &i, Incomplete &j){}
- // CIR: cir.func {{.*}}@_ZN6Struct8arg_attrES_RiR10Incomplete(%{{.*}}: !cir.ptr<!rec_Struct> {llvm.align = 4 : i64, llvm.dereferenceable = 20 : i64, llvm.nonnull, llvm.noundef} {{.*}}, %{{.*}}: !rec_Struct {{.*}}, %{{.*}}: !cir.ptr<!s32i> {llvm.align = 8 : i64, llvm.dereferenceable = 4 : i64, llvm.nonnull, llvm.noundef} {{.*}}, %arg3: !cir.ptr<!rec_Incomplete> {llvm.align = 8 : i64, llvm.nonnull, llvm.noundef} {{.*}}) {
- // LLVM: define {{.*}}void @_ZN6Struct8arg_attrES_RiR10Incomplete(ptr noundef nonnull align 4 dereferenceable(20) %{{.*}}, %struct.Struct %{{.*}}, ptr noundef nonnull align 8 dereferenceable(4) %{{.*}}, ptr noundef nonnull align 8 %{{.*}})
+ // CIR: cir.func {{.*}}@_ZN6Struct8arg_attrES_RiR10Incomplete(%{{.*}}: !cir.ptr<!rec_Struct> {llvm.align = 4 : i64, llvm.dereferenceable = 20 : i64, llvm.nonnull, llvm.noundef} {{.*}}, %{{.*}}: !rec_Struct {{.*}}, %{{.*}}: !cir.ptr<!s32i> {llvm.align = 4 : i64, llvm.dereferenceable = 4 : i64, llvm.nonnull, llvm.noundef} {{.*}}, %arg3: !cir.ptr<!rec_Incomplete> {llvm.align = 1 : i64, llvm.nonnull, llvm.noundef} {{.*}}) {
+ // LLVM: define {{.*}}void @_ZN6Struct8arg_attrES_RiR10Incomplete(ptr noundef nonnull align 4 dereferenceable(20) %{{.*}}, %struct.Struct %{{.*}}, ptr noundef nonnull align 4 dereferenceable(4) %{{.*}}, ptr noundef nonnull align 1 %{{.*}})
// OGCG: define {{.*}}void @_ZN6Struct8arg_attrES_RiR10Incomplete(ptr noundef nonnull align 4 dereferenceable(20) %{{.*}}, ptr noundef byval(%struct.Struct) align 8 %{{.*}}, ptr noundef nonnull align 4 dereferenceable(4) %{{.*}}, ptr noundef nonnull align 1 %{{.*}})
+struct __attribute__((aligned(32))) Aligned32 {
+ int x;
+ void method();
+};
+
+void Aligned32::method() {}
+ // CIR: cir.func {{.*}}@_ZN9Aligned326methodEv(%{{.*}}: !cir.ptr<!rec_Aligned32> {llvm.align = 32 : i64, llvm.dereferenceable = 32 : i64, llvm.nonnull, llvm.noundef} {{.*}}) {
+ // BOTH: define {{.*}}void @_ZN9Aligned326methodEv(ptr noundef nonnull align 32 dereferenceable(32) %{{.*}})
+
+void aligned_ref(Aligned32 &a) {}
+ // CIR: cir.func {{.*}}@_Z11aligned_refR9Aligned32(%{{.*}}: !cir.ptr<!rec_Aligned32> {llvm.align = 32 : i64, llvm.dereferenceable = 32 : i64, llvm.nonnull, llvm.noundef} {{.*}}) {
+ // BOTH: define {{.*}}void @_Z11aligned_refR9Aligned32(ptr noundef nonnull align 32 dereferenceable(32) %{{.*}})
+
+int g;
+int &return_int_ref() { return g; }
+ // CIR: cir.func {{.*}}@_Z14return_int_refv() -> (!cir.ptr<!s32i> {llvm.align = 4 : i64, llvm.dereferenceable = 4 : i64, llvm.nonnull, llvm.noundef}) {
+ // BOTH: define {{.*}}noundef nonnull align 4 dereferenceable(4) ptr @_Z14return_int_refv()
+
+Aligned32 ga;
+Aligned32 &return_aligned_ref() { return ga; }
+ // CIR: cir.func {{.*}}@_Z18return_aligned_refv() -> (!cir.ptr<!rec_Aligned32> {llvm.align = 32 : i64, llvm.dereferenceable = 32 : i64, llvm.nonnull, llvm.noundef}) {
+ // BOTH: define {{.*}}noundef nonnull align 32 dereferenceable(32) ptr @_Z18return_aligned_refv()
+
void caller(Struct s, int i, Incomplete &inc) {
s.this_func();
// CIR: cir.call @_ZN6Struct9this_funcEv(%{{.*}}) : (!cir.ptr<!rec_Struct> {llvm.align = 4 : i64, llvm.dereferenceable = 20 : i64, llvm.nonnull, llvm.noundef})
// BOTH: call void @_ZN6Struct9this_funcEv(ptr noundef nonnull align 4 dereferenceable(20) %{{.*}})
s.arg_attr(s, i, inc);
- // CIR: cir.call @_ZN6Struct8arg_attrES_RiR10Incomplete(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) : (!cir.ptr<!rec_Struct> {llvm.align = 4 : i64, llvm.dereferenceable = 20 : i64, llvm.nonnull, llvm.noundef}, !rec_Struct, !cir.ptr<!s32i> {llvm.align = 8 : i64, llvm.dereferenceable = 4 : i64, llvm.nonnull, llvm.noundef}, !cir.ptr<!rec_Incomplete> {llvm.align = 8 : i64, llvm.nonnull, llvm.noundef})
- // LLVM: call void @_ZN6Struct8arg_attrES_RiR10Incomplete(ptr noundef nonnull align 4 dereferenceable(20) %{{.*}}, %struct.Struct %{{.*}}, ptr noundef nonnull align 8 dereferenceable(4) %{{.*}}, ptr noundef nonnull align 8 %{{.*}})
+ // CIR: cir.call @_ZN6Struct8arg_attrES_RiR10Incomplete(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) : (!cir.ptr<!rec_Struct> {llvm.align = 4 : i64, llvm.dereferenceable = 20 : i64, llvm.nonnull, llvm.noundef}, !rec_Struct, !cir.ptr<!s32i> {llvm.align = 4 : i64, llvm.dereferenceable = 4 : i64, llvm.nonnull, llvm.noundef}, !cir.ptr<!rec_Incomplete> {llvm.align = 1 : i64, llvm.nonnull, llvm.noundef})
+ // LLVM: call void @_ZN6Struct8arg_attrES_RiR10Incomplete(ptr noundef nonnull align 4 dereferenceable(20) %{{.*}}, %struct.Struct %{{.*}}, ptr noundef nonnull align 4 dereferenceable(4) %{{.*}}, ptr noundef nonnull align 1 %{{.*}})
// OGCG: call void @_ZN6Struct8arg_attrES_RiR10Incomplete(ptr noundef nonnull align 4 dereferenceable(20) %{{.*}}, ptr noundef byval(%struct.Struct) align 8 %{{.*}}, ptr noundef nonnull align 4 dereferenceable(4) %{{.*}}, ptr noundef nonnull align 1 %{{.*}})
}
More information about the cfe-commits
mailing list