Skip to content

Commit 49839f9

Browse files
committed
[clang] Better SysV bitfield access units (#65742)
Reimplement bitfield access unit computation for SysV ABIs. Considers expense of unaligned and non-power-of-2 accesses.
1 parent 7df79ab commit 49839f9

20 files changed

+1141
-1681
lines changed

clang/lib/CodeGen/CGRecordLayoutBuilder.cpp

Lines changed: 261 additions & 90 deletions
Large diffs are not rendered by default.

clang/test/CodeGen/aapcs-bitfield-access-unit.c

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ struct st2 {
2929
short c : 7;
3030
} st2;
3131
// LAYOUT-LABEL: LLVMType:%struct.st2 =
32-
// LAYOUT-SAME: type { i16, i8 }
32+
// LAYOUT-SAME: type { i32 }
3333
// LAYOUT: BitFields:[
34-
// LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:10 IsSigned:1 StorageSize:16 StorageOffset:0
35-
// LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:7 IsSigned:1 StorageSize:8 StorageOffset:2
34+
// LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:10 IsSigned:1 StorageSize:32 StorageOffset:0
35+
// LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:7 IsSigned:1 StorageSize:32 StorageOffset:0
3636
// LAYOUT-NEXT: ]>
3737

3838
struct st3 {
@@ -60,10 +60,10 @@ struct st5 {
6060
volatile char c : 5;
6161
} st5;
6262
// LAYOUT-LABEL: LLVMType:%struct.st5 =
63-
// LAYOUT-SAME: type { i16, i8 }
63+
// LAYOUT-SAME: type { i32 }
6464
// LAYOUT: BitFields:[
65-
// LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:12 IsSigned:1 StorageSize:16 StorageOffset:0
66-
// LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:5 IsSigned:1 StorageSize:8 StorageOffset:2
65+
// LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:12 IsSigned:1 StorageSize:32 StorageOffset:0
66+
// LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:5 IsSigned:1 StorageSize:32 StorageOffset:0
6767
// LAYOUT-NEXT: ]>
6868

6969
struct st6 {
@@ -141,7 +141,7 @@ struct st12{
141141
int f : 16;
142142
} st12;
143143
// LAYOUT-LABEL: LLVMType:%struct.st12 =
144-
// LAYOUT-SAME: type { i24 }
144+
// LAYOUT-SAME: type { i32 }
145145
// LAYOUT: BitFields:[
146146
// LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:8 IsSigned:1 StorageSize:32 StorageOffset:0
147147
// LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:16 IsSigned:1 StorageSize:32 StorageOffset:0
@@ -152,10 +152,10 @@ struct st13 {
152152
int b : 32;
153153
} __attribute__((packed)) st13;
154154
// LAYOUT-LABEL: LLVMType:%struct.st13 =
155-
// LAYOUT-SAME: type { [5 x i8] }
155+
// LAYOUT-SAME: type <{ i8, i32 }>
156156
// LAYOUT: BitFields:[
157-
// LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:8 IsSigned:1 StorageSize:40 StorageOffset:0
158-
// LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:32 IsSigned:1 StorageSize:40 StorageOffset:0
157+
// LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:8 IsSigned:1 StorageSize:8 StorageOffset:0
158+
// LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:32 IsSigned:1 StorageSize:32 StorageOffset:1
159159
// LAYOUT-NEXT: ]>
160160

161161
struct st14 {
@@ -183,23 +183,23 @@ struct st16 {
183183
int d : 16;
184184
} st16;
185185
// LAYOUT-LABEL: LLVMType:%struct.st16 =
186-
// LAYOUT-SAME: type { i48, i48 }
186+
// LAYOUT-SAME: type { i32, i16, i32, i16 }
187187
// LAYOUT: BitFields:[
188-
// LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:32 IsSigned:1 StorageSize:64 StorageOffset:0
189-
// LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:16 IsSigned:1 StorageSize:64 StorageOffset:0
190-
// LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:32 IsSigned:1 StorageSize:64 StorageOffset:8
191-
// LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:16 IsSigned:1 StorageSize:64 StorageOffset:8
188+
// LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:32 IsSigned:1 StorageSize:32 StorageOffset:0
189+
// LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:16 IsSigned:1 StorageSize:16 StorageOffset:4
190+
// LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:32 IsSigned:1 StorageSize:32 StorageOffset:8
191+
// LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:16 IsSigned:1 StorageSize:16 StorageOffset:12
192192
// LAYOUT-NEXT: ]>
193193

194194
struct st17 {
195195
int b : 32;
196196
char c : 8;
197197
} __attribute__((packed)) st17;
198198
// LAYOUT-LABEL: LLVMType:%struct.st17 =
199-
// LAYOUT-SAME: type { [5 x i8] }
199+
// LAYOUT-SAME: type <{ i32, i8 }>
200200
// LAYOUT: BitFields:[
201-
// LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:32 IsSigned:1 StorageSize:40 StorageOffset:0
202-
// LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:8 IsSigned:1 StorageSize:40 StorageOffset:0
201+
// LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:32 IsSigned:1 StorageSize:32 StorageOffset:0
202+
// LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:8 IsSigned:1 StorageSize:8 StorageOffset:4
203203
// LAYOUT-NEXT: ]>
204204

205205
struct zero_bitfield {
@@ -221,7 +221,7 @@ struct zero_bitfield_ok {
221221
int b : 24;
222222
} st19;
223223
// LAYOUT-LABEL: LLVMType:%struct.zero_bitfield_ok =
224-
// LAYOUT-SAME: type { i16, i24 }
224+
// LAYOUT-SAME: type { i16, i32 }
225225
// LAYOUT: BitFields:[
226226
// LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:8 IsSigned:1 StorageSize:16 StorageOffset:0
227227
// LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:8 IsSigned:1 StorageSize:16 StorageOffset:0

clang/test/CodeGen/aapcs-bitfield.c

Lines changed: 624 additions & 1296 deletions
Large diffs are not rendered by default.
Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
// RUN: %clang_cc1 -triple arm-none-eabi -fdump-record-layouts-simple -ffreestanding -emit-llvm -o %t %s | FileCheck %s -check-prefix=LAYOUT
2-
// RUN: FileCheck %s -check-prefix=IR <%t
3-
// RUN: %clang_cc1 -triple aarch64 -fdump-record-layouts-simple -ffreestanding -emit-llvm -o %t %s | FileCheck %s -check-prefix=LAYOUT
4-
// RUN: FileCheck %s -check-prefix=IR <%t
1+
// RUN: %clang_cc1 -triple arm-none-eabi -fdump-record-layouts-simple -ffreestanding -emit-llvm -o %t %s | FileCheck %s -check-prefixes=LAYOUT,LAYOUT-32
2+
// RUN: FileCheck %s -check-prefixes=IR,IR-32 <%t
3+
// RUN: %clang_cc1 -triple aarch64 -fdump-record-layouts-simple -ffreestanding -emit-llvm -o %t %s | FileCheck %s -check-prefixes=LAYOUT,LAYOUT-64
4+
// RUN: FileCheck %s -check-prefixes=IR,IR-64 <%t
55

66
extern struct T {
77
int b0 : 8;
@@ -14,12 +14,17 @@ int func(void) {
1414
}
1515

1616
// IR: @g = external global %struct.T, align 4
17-
// IR: %{{.*}} = load i64, ptr @g, align 4
17+
// IR-32: %{{.*}} = load i32, ptr @g, align 4
18+
// IR-64: %{{.*}} = load i64, ptr @g, align 4
1819

1920
// LAYOUT-LABEL: LLVMType:%struct.T =
20-
// LAYOUT-SAME: type { i40 }
21+
// LAYOUT-32-SAME: type { i32, i8 }
22+
// LAYOUT-64-SAME: type { i64 }
2123
// LAYOUT: BitFields:[
22-
// LAYOUT-NEXT: <CGBitFieldInfo Offset:0 Size:8 IsSigned:1 StorageSize:64 StorageOffset:0
23-
// LAYOUT-NEXT: <CGBitFieldInfo Offset:8 Size:24 IsSigned:1 StorageSize:64 StorageOffset:0
24-
// LAYOUT-NEXT: <CGBitFieldInfo Offset:32 Size:1 IsSigned:1 StorageSize:64 StorageOffset:0
24+
// LAYOUT-32-NEXT: <CGBitFieldInfo Offset:0 Size:8 IsSigned:1 StorageSize:32 StorageOffset:0
25+
// LAYOUT-32-NEXT: <CGBitFieldInfo Offset:8 Size:24 IsSigned:1 StorageSize:32 StorageOffset:0
26+
// LAYOUT-32-NEXT: <CGBitFieldInfo Offset:0 Size:1 IsSigned:1 StorageSize:8 StorageOffset:4
27+
// LAYOUT-64-NEXT: <CGBitFieldInfo Offset:0 Size:8 IsSigned:1 StorageSize:64 StorageOffset:0
28+
// LAYOUT-64-NEXT: <CGBitFieldInfo Offset:8 Size:24 IsSigned:1 StorageSize:64 StorageOffset:0
29+
// LAYOUT-64-NEXT: <CGBitFieldInfo Offset:32 Size:1 IsSigned:1 StorageSize:64 StorageOffset:0
2530
// LAYOUT-NEXT: ]>

clang/test/CodeGen/arm64-be-bitfield.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,18 @@ struct bt3 { signed b2:10; signed b3:10; } b16;
77
signed callee_b0f(struct bt3 bp11) {
88
// IR: callee_b0f(i64 [[ARG:%.*]])
99
// IR: [[BP11:%.*]] = alloca %struct.bt3, align 4
10-
// IR: store i64 [[ARG]], ptr [[PTR:%.*]], align 8
11-
// IR: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[BP11]], ptr align 8 [[PTR]], i64 4
10+
// IR: [[COERCE_DIVE:%.*]] = getelementptr inbounds %struct.bt3, ptr [[BP11]], i32 0, i32 0
11+
// IR: [[COERCE_HIGHBITS:%.*]] = lshr i64 [[ARG]], 32
12+
// IR: [[COERCE_VAL_II:%.*]] = trunc i64 [[COERCE_HIGHBITS]] to i32
13+
// IR: store i32 [[COERCE_VAL_II]], ptr [[COERCE_DIVE]], align 4
1214
// IR: [[BF_LOAD:%.*]] = load i32, ptr [[BP11]], align 4
1315
// IR: [[BF_ASHR:%.*]] = ashr i32 [[BF_LOAD]], 22
1416
// IR: ret i32 [[BF_ASHR]]
1517
return bp11.b2;
1618
}
1719

1820
// LAYOUT-LABEL: LLVMType:%struct.bt3 =
19-
// LAYOUT-SAME: type { i24 }
21+
// LAYOUT-SAME: type { i32 }
2022
// LAYOUT: BitFields:[
2123
// LAYOUT-NEXT: <CGBitFieldInfo Offset:22 Size:10 IsSigned:1 StorageSize:32 StorageOffset:0
2224
// LAYOUT-NEXT: <CGBitFieldInfo Offset:12 Size:10 IsSigned:1 StorageSize:32 StorageOffset:0

clang/test/CodeGen/bitfield-2.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -271,11 +271,11 @@ _Bool test_6(void) {
271271
// CHECK-RECORD: *** Dumping IRgen Record Layout
272272
// CHECK-RECORD: Record: RecordDecl{{.*}}s7
273273
// CHECK-RECORD: Layout: <CGRecordLayout
274-
// CHECK-RECORD: LLVMType:%struct.s7 = type { i32, i32, i32, i8, i32, [12 x i8] }
274+
// CHECK-RECORD: LLVMType:%struct.s7 = type <{ i32, i32, i32, i64, [12 x i8] }>
275275
// CHECK-RECORD: IsZeroInitializable:1
276276
// CHECK-RECORD: BitFields:[
277-
// CHECK-RECORD: <CGBitFieldInfo Offset:0 Size:5 IsSigned:1 StorageSize:8 StorageOffset:12
278-
// CHECK-RECORD: <CGBitFieldInfo Offset:0 Size:29 IsSigned:1 StorageSize:32 StorageOffset:16
277+
// CHECK-RECORD: <CGBitFieldInfo Offset:0 Size:5 IsSigned:1 StorageSize:64 StorageOffset:12
278+
// CHECK-RECORD: <CGBitFieldInfo Offset:32 Size:29 IsSigned:1 StorageSize:64 StorageOffset:12
279279

280280
struct __attribute__((aligned(16))) s7 {
281281
int a, b, c;

0 commit comments

Comments
 (0)