diff options
| author | Oliver Stannard <oliver.stannard@arm.com> | 2025-02-20 17:07:16 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-02-20 17:07:16 +0000 |
| commit | 02e8fd7a30903d65c85b3cfb56e8039b71c31972 (patch) | |
| tree | e4d9cf73197927c10091eb51a18e7956d33ab954 /clang/test/CodeGen/aapcs-align.cpp | |
| parent | be51ef4518ad3375e267667a89d379ce46efc4bb (diff) | |
[ARM,AArch64] Fix ABI bugs with over-sized bitfields (#126774)
This fixes two bugs in the ABI for over-sized bitfields for ARM and
AArch64:
The container type picked for an over-sized bitfield already contributes
to the alignment of the structure, but it should also contribute to the
"unadjusted alignment" which is used by the ARM and AArch64 PCS.
AAPCS64 defines the bitfield layout algorithm for over-sized bitfields
as picking a container which is the fundamental integer data type with
the largest size less than or equal to the bit-field width. Since
AAPCS64 has a 128-bit integer fundamental data type, we need to consider
Int128 as a container type for AArch64.
Diffstat (limited to 'clang/test/CodeGen/aapcs-align.cpp')
| -rw-r--r-- | clang/test/CodeGen/aapcs-align.cpp | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/clang/test/CodeGen/aapcs-align.cpp b/clang/test/CodeGen/aapcs-align.cpp index 4f393d9e6b7f..c7bc5ba0bbfe 100644 --- a/clang/test/CodeGen/aapcs-align.cpp +++ b/clang/test/CodeGen/aapcs-align.cpp @@ -6,6 +6,11 @@ extern "C" { +// CHECK: @sizeof_OverSizedBitfield ={{.*}} global i32 8 +// CHECK: @alignof_OverSizedBitfield ={{.*}} global i32 8 +// CHECK: @sizeof_VeryOverSizedBitfield ={{.*}} global i32 16 +// CHECK: @alignof_VeryOverSizedBitfield ={{.*}} global i32 8 + // Base case, nothing interesting. struct S { int x, y; @@ -138,4 +143,42 @@ void g6() { // CHECK: call void @f6m(i32 noundef 1, i32 noundef 2, i32 noundef 3, i32 noundef 4, i32 noundef 5, [4 x i32] [i32 6, i32 7, i32 0, i32 undef]) // CHECK: declare void @f6(i32 noundef, [4 x i32]) // CHECK: declare void @f6m(i32 noundef, i32 noundef, i32 noundef, i32 noundef, i32 noundef, [4 x i32]) + +// Over-sized bitfield, which results in a 64-bit container type, so 64-bit +// alignment. +struct OverSizedBitfield { + int x : 64; +}; + +unsigned sizeof_OverSizedBitfield = sizeof(OverSizedBitfield); +unsigned alignof_OverSizedBitfield = alignof(OverSizedBitfield); + +// CHECK: define{{.*}} void @g7 +// CHECK: call void @f7(i32 noundef 1, [1 x i64] [i64 42]) +// CHECK: declare void @f7(i32 noundef, [1 x i64]) +void f7(int a, OverSizedBitfield b); +void g7() { + OverSizedBitfield s = {42}; + f7(1, s); +} + +// There are no 128-bit fundamental data types defined by AAPCS32, so this gets +// a 64-bit container plus 64 bits of padding, giving it a size of 16 bytes and +// alignment of 8 bytes. +struct VeryOverSizedBitfield { + int x : 128; +}; + +unsigned sizeof_VeryOverSizedBitfield = sizeof(VeryOverSizedBitfield); +unsigned alignof_VeryOverSizedBitfield = alignof(VeryOverSizedBitfield); + +// CHECK: define{{.*}} void @g8 +// CHECK: call void @f8(i32 noundef 1, [2 x i64] [i64 42, i64 0]) +// CHECK: declare void @f8(i32 noundef, [2 x i64]) +void f8(int a, VeryOverSizedBitfield b); +void g8() { + VeryOverSizedBitfield s = {42}; + f8(1, s); +} + } |
