Skip to content

Commit 146ac68

Browse files
committed
[ARM, AArch64] Fix passing of structures with aligned base classes
RecordLayout::UnadjustedAlignment was documented as "Maximum of the alignments of the record members in characters", but RecordLayout::getUnadjustedAlignment(), which just returns UnadjustedAlignment, was documented as getting "the record alignment in characters, before alignment adjustement." These are not the same thing: the former excludes alignment of base classes, the latter takes it into account. ItaniumRecordLayoutBuilder::LayoutBase was setting it according to the former, but the AAPCS calling convention handling, currently the only user, relies on it being set according to the latter. Fixes #135551.
1 parent 7eae1a4 commit 146ac68

File tree

4 files changed

+42
-25
lines changed

4 files changed

+42
-25
lines changed

clang/include/clang/AST/RecordLayout.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,9 @@ class ASTRecordLayout {
7575
// performance or backwards compatibility preserving (e.g. AIX-ABI).
7676
CharUnits PreferredAlignment;
7777

78-
// UnadjustedAlignment - Maximum of the alignments of the record members in
79-
// characters.
78+
// UnadjustedAlignment - Alignment of record in characters before alignment
79+
// adjustments. Maximum of the alignments of the record members and base
80+
// classes in characters.
8081
CharUnits UnadjustedAlignment;
8182

8283
/// RequiredAlignment - The required alignment of the object. In the MS-ABI
@@ -186,7 +187,7 @@ class ASTRecordLayout {
186187
CharUnits getPreferredAlignment() const { return PreferredAlignment; }
187188

188189
/// getUnadjustedAlignment - Get the record alignment in characters, before
189-
/// alignment adjustement.
190+
/// alignment adjustment.
190191
CharUnits getUnadjustedAlignment() const { return UnadjustedAlignment; }
191192

192193
/// getSize - Get the record size in characters.

clang/lib/AST/RecordLayoutBuilder.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1302,6 +1302,7 @@ ItaniumRecordLayoutBuilder::LayoutBase(const BaseSubobjectInfo *Base) {
13021302
setSize(std::max(getSize(), Offset + Layout.getSize()));
13031303

13041304
// Remember max struct/class alignment.
1305+
UnadjustedAlignment = std::max(UnadjustedAlignment, BaseAlign);
13051306
UpdateAlignment(BaseAlign, UnpackedAlignTo, PreferredBaseAlign);
13061307

13071308
return Offset;

clang/test/CodeGen/aapcs64-align.cpp

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -67,25 +67,40 @@ void g3() {
6767
// CHECK: declare void @f3(i64 noundef, i128)
6868
// CHECK: declare void @f3m(i64 noundef, i64 noundef, i64 noundef, i64 noundef, i64 noundef, i128)
6969

70+
// Increased natural alignment through a base class.
71+
struct SB16 : S16 {};
72+
73+
void f4(long, SB16);
74+
void f4m(long, long, long, long, long, SB16);
75+
void g4() {
76+
SB16 s = {6, 7};
77+
f4(1, s);
78+
f4m(1, 2, 3, 4, 5, s);
79+
}
80+
// CHECK: define{{.*}} void @g4
81+
// CHECK: call void @f4(i64 noundef 1, i128 129127208515966861318)
82+
// CHECK: call void @f4m(i64 noundef 1, i64 noundef 2, i64 noundef 3, i64 noundef 4, i64 noundef 5, i128 129127208515966861318)
83+
// CHECK: declare void @f4(i64 noundef, i128)
84+
// CHECK: declare void @f4m(i64 noundef, i64 noundef, i64 noundef, i64 noundef, i64 noundef, i128)
7085

7186
// Packed structure.
7287
struct __attribute__((packed)) P {
7388
int x;
7489
long u;
7590
};
7691

77-
void f4(int, P);
78-
void f4m(int, int, int, int, int, P);
79-
void g4() {
92+
void f5(int, P);
93+
void f5m(int, int, int, int, int, P);
94+
void g5() {
8095
P s = {6, 7};
81-
f4(1, s);
82-
f4m(1, 2, 3, 4, 5, s);
96+
f5(1, s);
97+
f5m(1, 2, 3, 4, 5, s);
8398
}
84-
// CHECK: define{{.*}} void @g4()
85-
// CHECK: call void @f4(i32 noundef 1, [2 x i64] [i64 30064771078, i64 0])
86-
// CHECK: void @f4m(i32 noundef 1, i32 noundef 2, i32 noundef 3, i32 noundef 4, i32 noundef 5, [2 x i64] [i64 30064771078, i64 0])
87-
// CHECK: declare void @f4(i32 noundef, [2 x i64])
88-
// CHECK: declare void @f4m(i32 noundef, i32 noundef, i32 noundef, i32 noundef, i32 noundef, [2 x i64])
99+
// CHECK: define{{.*}} void @g5()
100+
// CHECK: call void @f5(i32 noundef 1, [2 x i64] [i64 30064771078, i64 0])
101+
// CHECK: void @f5m(i32 noundef 1, i32 noundef 2, i32 noundef 3, i32 noundef 4, i32 noundef 5, [2 x i64] [i64 30064771078, i64 0])
102+
// CHECK: declare void @f5(i32 noundef, [2 x i64])
103+
// CHECK: declare void @f5m(i32 noundef, i32 noundef, i32 noundef, i32 noundef, i32 noundef, [2 x i64])
89104

90105

91106
// Packed structure, overaligned, same as above.
@@ -94,18 +109,18 @@ struct __attribute__((packed, aligned(16))) P16 {
94109
long y;
95110
};
96111

97-
void f5(int, P16);
98-
void f5m(int, int, int, int, int, P16);
99-
void g5() {
100-
P16 s = {6, 7};
101-
f5(1, s);
102-
f5m(1, 2, 3, 4, 5, s);
112+
void f6(int, P16);
113+
void f6m(int, int, int, int, int, P16);
114+
void g6() {
115+
P16 s = {6, 7};
116+
f6(1, s);
117+
f6m(1, 2, 3, 4, 5, s);
103118
}
104-
// CHECK: define{{.*}} void @g5()
105-
// CHECK: call void @f5(i32 noundef 1, [2 x i64] [i64 30064771078, i64 0])
106-
// CHECK: void @f5m(i32 noundef 1, i32 noundef 2, i32 noundef 3, i32 noundef 4, i32 noundef 5, [2 x i64] [i64 30064771078, i64 0])
107-
// CHECK: declare void @f5(i32 noundef, [2 x i64])
108-
// CHECK: declare void @f5m(i32 noundef, i32 noundef, i32 noundef, i32 noundef, i32 noundef, [2 x i64])
119+
// CHECK: define{{.*}} void @g6()
120+
// CHECK: call void @f6(i32 noundef 1, [2 x i64] [i64 30064771078, i64 0])
121+
// CHECK: void @f6m(i32 noundef 1, i32 noundef 2, i32 noundef 3, i32 noundef 4, i32 noundef 5, [2 x i64] [i64 30064771078, i64 0])
122+
// CHECK: declare void @f6(i32 noundef, [2 x i64])
123+
// CHECK: declare void @f6m(i32 noundef, i32 noundef, i32 noundef, i32 noundef, i32 noundef, [2 x i64])
109124

110125
//BitInt alignment
111126
struct BITINT129 {

clang/test/CodeGen/arm-vfp16-arguments2.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ struct S5 : B1 {
4242
// CHECK-FULL: define{{.*}} arm_aapcs_vfpcc %struct.S1 @_Z2f12S1(%struct.S1 returned %s1.coerce)
4343
struct S1 f1(struct S1 s1) { return s1; }
4444

45-
// CHECK-SOFT: define{{.*}} void @_Z2f22S2(ptr dead_on_unwind noalias writable writeonly sret(%struct.S2) align 8 captures(none) initializes((0, 16)) %agg.result, [4 x i32] %s2.coerce)
45+
// CHECK-SOFT: define{{.*}} void @_Z2f22S2(ptr dead_on_unwind noalias writable writeonly sret(%struct.S2) align 8 captures(none) initializes((0, 16)) %agg.result, [2 x i64] %s2.coerce)
4646
// CHECK-HARD: define{{.*}} arm_aapcs_vfpcc [2 x <2 x i32>] @_Z2f22S2([2 x <2 x i32>] returned %s2.coerce)
4747
// CHECK-FULL: define{{.*}} arm_aapcs_vfpcc %struct.S2 @_Z2f22S2(%struct.S2 %s2.coerce)
4848
struct S2 f2(struct S2 s2) { return s2; }

0 commit comments

Comments
 (0)