xref: /llvm-project/clang/test/CodeGenCXX/bitfield-access-tail.cpp (revision 617cf8a72d2ab568bf0e84452faf4e35a322b32f)
1a8ca4abfSNathan Sidwell // Check we use tail padding if it is known to be safe
2a8ca4abfSNathan Sidwell 
3a8ca4abfSNathan Sidwell // Configs that have cheap unaligned access
4a8ca4abfSNathan Sidwell // Little Endian
5*ee994750SNathan Sidwell // RUN: %clang_cc1 -triple=aarch64-apple-darwin %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT64 %s
6*ee994750SNathan Sidwell // RUN: %clang_cc1 -triple=aarch64-linux-gnu %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT64 %s
7a8ca4abfSNathan Sidwell // RUN: %clang_cc1 -triple=arm-apple-darwin %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT-DWN32 %s
8*ee994750SNathan Sidwell // RUN: %clang_cc1 -triple=arm-none-eabi %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s
9*ee994750SNathan Sidwell // RUN: %clang_cc1 -triple=i686-linux-gnu %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s
10*ee994750SNathan Sidwell // RUN: %clang_cc1 -triple=loongarch64-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT64 %s
11*ee994750SNathan Sidwell // RUN: %clang_cc1 -triple=powerpcle-linux-gnu %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s
12*ee994750SNathan Sidwell // RUN: %clang_cc1 -triple=ve-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT64 %s
13*ee994750SNathan Sidwell // RUN: %clang_cc1 -triple=wasm32 %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s
14*ee994750SNathan Sidwell // RUN: %clang_cc1 -triple=wasm64 %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT64 %s
15*ee994750SNathan Sidwell // RUN: %clang_cc1 -triple=x86_64-linux-gnu %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT64 %s
16a8ca4abfSNathan Sidwell 
17a8ca4abfSNathan Sidwell // Big Endian
18*ee994750SNathan Sidwell // RUN: %clang_cc1 -triple=powerpc-linux-gnu %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s
19*ee994750SNathan Sidwell // RUN: %clang_cc1 -triple=powerpc64-linux-gnu %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT64 %s
20*ee994750SNathan Sidwell // RUN: %clang_cc1 -triple=systemz %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT64 %s
21a8ca4abfSNathan Sidwell 
22a8ca4abfSNathan Sidwell // Configs that have expensive unaligned access
23a8ca4abfSNathan Sidwell // Little Endian
24*ee994750SNathan Sidwell // RUN: %clang_cc1 -triple=amdgcn-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT64 %s
25*ee994750SNathan Sidwell // RUN: %clang_cc1 -triple=arc-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s
26*ee994750SNathan Sidwell // RUN: %clang_cc1 -triple=bpf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT64 %s
27*ee994750SNathan Sidwell // RUN: %clang_cc1 -triple=csky %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s
28*ee994750SNathan Sidwell // RUN: %clang_cc1 -triple=hexagon-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s
29*ee994750SNathan Sidwell // RUN: %clang_cc1 -triple=loongarch32-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s
30*ee994750SNathan Sidwell // RUN: %clang_cc1 -triple=nvptx-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s
31*ee994750SNathan Sidwell // RUN: %clang_cc1 -triple=riscv32 %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s
32*ee994750SNathan Sidwell // RUN: %clang_cc1 -triple=riscv64 %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT64 %s
33*ee994750SNathan Sidwell // RUN: %clang_cc1 -triple=spir-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s
34*ee994750SNathan Sidwell // RUN: %clang_cc1 -triple=xcore-none-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s
35a8ca4abfSNathan Sidwell 
36a8ca4abfSNathan Sidwell // Big endian
37*ee994750SNathan Sidwell // RUN: %clang_cc1 -triple=lanai-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s
38*ee994750SNathan Sidwell // RUN: %clang_cc1 -triple=m68k-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s
39*ee994750SNathan Sidwell // RUN: %clang_cc1 -triple=mips-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s
40*ee994750SNathan Sidwell // RUN: %clang_cc1 -triple=mips64-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT64 %s
41*ee994750SNathan Sidwell // RUN: %clang_cc1 -triple=sparc-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s
42*ee994750SNathan Sidwell // RUN: %clang_cc1 -triple=tce-elf %s -emit-llvm -o /dev/null -fdump-record-layouts-simple | FileCheck --check-prefixes CHECK,LAYOUT,LAYOUT32 %s
43a8ca4abfSNathan Sidwell 
44a8ca4abfSNathan Sidwell // Can use tail padding
45a8ca4abfSNathan Sidwell struct Pod {
46a8ca4abfSNathan Sidwell   int a : 16;
47a8ca4abfSNathan Sidwell   int b : 8;
48a8ca4abfSNathan Sidwell } P;
49a8ca4abfSNathan Sidwell // CHECK-LABEL: LLVMType:%struct.Pod =
5049839f97SNathan Sidwell // LAYOUT-SAME: type { i32 }
5149839f97SNathan Sidwell // LAYOUT-DWN32-SAME: type <{ i16, i8 }>
52a8ca4abfSNathan Sidwell // CHECK-NEXT: NonVirtualBaseLLVMType:%struct.Pod =
53a8ca4abfSNathan Sidwell // CHECK: BitFields:[
54a8ca4abfSNathan Sidwell // LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:16 IsSigned:1 StorageSize:32 StorageOffset:0
55a8ca4abfSNathan Sidwell // LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:8 IsSigned:1 StorageSize:32 StorageOffset:0
56a8ca4abfSNathan Sidwell 
5749839f97SNathan Sidwell // LAYOUT-DWN32-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:16 IsSigned:1 StorageSize:16 StorageOffset:0
5849839f97SNathan Sidwell // LAYOUT-DWN32-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:8 IsSigned:1 StorageSize:8 StorageOffset:2
59a8ca4abfSNathan Sidwell // CHECK-NEXT: ]>
60a8ca4abfSNathan Sidwell 
61a8ca4abfSNathan Sidwell // No tail padding
62a8ca4abfSNathan Sidwell struct __attribute__((packed)) PPod {
63a8ca4abfSNathan Sidwell   int a : 16;
64a8ca4abfSNathan Sidwell   int b : 8;
65a8ca4abfSNathan Sidwell } PP;
66a8ca4abfSNathan Sidwell // CHECK-LABEL: LLVMType:%struct.PPod =
6749839f97SNathan Sidwell // LAYOUT-SAME: type <{ i16, i8 }>
6849839f97SNathan Sidwell // LAYOUT-DWN32-SAME: type <{ i16, i8 }>
69a8ca4abfSNathan Sidwell // CHECK-NEXT: NonVirtualBaseLLVMType:%struct.PPod =
70a8ca4abfSNathan Sidwell // CHECK: BitFields:[
7149839f97SNathan Sidwell // LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:16 IsSigned:1 StorageSize:16 StorageOffset:0
7249839f97SNathan Sidwell // LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:8 IsSigned:1 StorageSize:8 StorageOffset:2
73a8ca4abfSNathan Sidwell 
7449839f97SNathan Sidwell // LAYOUT-DWN32-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:16 IsSigned:1 StorageSize:16 StorageOffset:0
7549839f97SNathan Sidwell // LAYOUT-DWN32-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:8 IsSigned:1 StorageSize:8 StorageOffset:2
76a8ca4abfSNathan Sidwell // CHECK-NEXT: ]>
77a8ca4abfSNathan Sidwell 
78a8ca4abfSNathan Sidwell // Cannot use tail padding
79a8ca4abfSNathan Sidwell struct NonPod {
80a8ca4abfSNathan Sidwell   ~NonPod();
81a8ca4abfSNathan Sidwell   int a : 16;
82a8ca4abfSNathan Sidwell   int b : 8;
83a8ca4abfSNathan Sidwell } NP;
84a8ca4abfSNathan Sidwell // CHECK-LABEL: LLVMType:%struct.NonPod =
8549839f97SNathan Sidwell // LAYOUT-SAME: type <{ i16, i8, i8 }>
8649839f97SNathan Sidwell // LAYOUT-DWN32-SAME: type <{ i16, i8 }>
87a8ca4abfSNathan Sidwell // CHECK-NEXT: NonVirtualBaseLLVMType:%struct.
8849839f97SNathan Sidwell // LAYOUT-SAME: NonPod.base = type <{ i16, i8 }>
8949839f97SNathan Sidwell // LAYOUT-DWN32-SAME: NonPod = type <{ i16, i8 }>
90a8ca4abfSNathan Sidwell // CHECK: BitFields:[
9149839f97SNathan Sidwell // LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:16 IsSigned:1 StorageSize:16 StorageOffset:0
9249839f97SNathan Sidwell // LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:8 IsSigned:1 StorageSize:8 StorageOffset:2
93a8ca4abfSNathan Sidwell 
9449839f97SNathan Sidwell // LAYOUT-DWN32-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:16 IsSigned:1 StorageSize:16 StorageOffset:0
9549839f97SNathan Sidwell // LAYOUT-DWN32-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:8 IsSigned:1 StorageSize:8 StorageOffset:2
96a8ca4abfSNathan Sidwell // CHECK-NEXT: ]>
97a8ca4abfSNathan Sidwell 
98a8ca4abfSNathan Sidwell // No tail padding
99a8ca4abfSNathan Sidwell struct __attribute__((packed)) PNonPod {
100a8ca4abfSNathan Sidwell   ~PNonPod();
101a8ca4abfSNathan Sidwell   int a : 16;
102a8ca4abfSNathan Sidwell   int b : 8;
103a8ca4abfSNathan Sidwell } PNP;
104a8ca4abfSNathan Sidwell // CHECK-LABEL: LLVMType:%struct.PNonPod =
10549839f97SNathan Sidwell // LAYOUT-SAME: type <{ i16, i8 }>
10649839f97SNathan Sidwell // LAYOUT-DWN32-SAME: type <{ i16, i8 }>
107a8ca4abfSNathan Sidwell // CHECK-NEXT: NonVirtualBaseLLVMType:%struct.PNonPod =
108a8ca4abfSNathan Sidwell // CHECK: BitFields:[
10949839f97SNathan Sidwell // LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:16 IsSigned:1 StorageSize:16 StorageOffset:0
11049839f97SNathan Sidwell // LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:8 IsSigned:1 StorageSize:8 StorageOffset:2
111a8ca4abfSNathan Sidwell 
11249839f97SNathan Sidwell // LAYOUT-DWN32-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:16 IsSigned:1 StorageSize:16 StorageOffset:0
11349839f97SNathan Sidwell // LAYOUT-DWN32-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:8 IsSigned:1 StorageSize:8 StorageOffset:2
114a8ca4abfSNathan Sidwell // CHECK-NEXT: ]>
115*ee994750SNathan Sidwell 
116*ee994750SNathan Sidwell struct __attribute__((aligned(4))) Empty {} empty;
117*ee994750SNathan Sidwell 
118*ee994750SNathan Sidwell struct Char { char a; } cbase;
119*ee994750SNathan Sidwell struct D : virtual Char {
120*ee994750SNathan Sidwell   [[no_unique_address]] Empty e0;
121*ee994750SNathan Sidwell   [[no_unique_address]] Empty e1;
122*ee994750SNathan Sidwell   unsigned a : 24; // keep as 24bits
123*ee994750SNathan Sidwell } d;
124*ee994750SNathan Sidwell // CHECK-LABEL: LLVMType:%struct.D =
125*ee994750SNathan Sidwell // LAYOUT64-SAME: type <{ ptr, [3 x i8], %struct.Char, [4 x i8] }>
126*ee994750SNathan Sidwell // LAYOUT32-SAME: type { ptr, [3 x i8], %struct.Char }
127*ee994750SNathan Sidwell // LAYOUT-DWN32-SAME: type { ptr, [3 x i8], %struct.Char }
128*ee994750SNathan Sidwell // CHECK-NEXT: NonVirtualBaseLLVMType:
129*ee994750SNathan Sidwell // LAYOUT64-SAME: %struct.D.base = type <{ ptr, i32 }>
130*ee994750SNathan Sidwell // LAYOUT32-SAME: %struct.D = type { ptr, [3 x i8], %struct.Char }
131*ee994750SNathan Sidwell // LAYOUT-DWN32-SAME: %struct.D = type { ptr, [3 x i8], %struct.Char }
132*ee994750SNathan Sidwell // CHECK: BitFields:[
133*ee994750SNathan Sidwell // LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:24 IsSigned:0 StorageSize:24 StorageOffset:{{(4|8)}}
134*ee994750SNathan Sidwell 
135*ee994750SNathan Sidwell // LAYOUT-DWN32-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:24 IsSigned:0 StorageSize:24 StorageOffset:{{(4|8)}}
136*ee994750SNathan Sidwell // CHECK-NEXT: ]>
137*ee994750SNathan Sidwell 
138*ee994750SNathan Sidwell struct Int { int a; } ibase;
139*ee994750SNathan Sidwell struct E : virtual Int {
140*ee994750SNathan Sidwell   [[no_unique_address]] Empty e0;
141*ee994750SNathan Sidwell   [[no_unique_address]] Empty e1;
142*ee994750SNathan Sidwell   unsigned a : 24; // expand to 32
143*ee994750SNathan Sidwell } e;
144*ee994750SNathan Sidwell // CHECK-LABEL: LLVMType:%struct.E =
145*ee994750SNathan Sidwell // LAYOUT64-SAME: type <{ ptr, i32, %struct.Int }>
146*ee994750SNathan Sidwell // LAYOUT32-SAME: type { ptr, i32, %struct.Int }
147*ee994750SNathan Sidwell // LAYOUT-DWN32-SAME: type { ptr, i32, %struct.Int }
148*ee994750SNathan Sidwell // CHECK-NEXT: NonVirtualBaseLLVMType:%struct.E.base =
149*ee994750SNathan Sidwell // LAYOUT64-SAME: type <{ ptr, i32 }>
150*ee994750SNathan Sidwell // LAYOUT32-SAME: type { ptr, i32 }
151*ee994750SNathan Sidwell // LAYOUT-DWN32-SAME: type { ptr, i32 }
152*ee994750SNathan Sidwell // CHECK: BitFields:[
153*ee994750SNathan Sidwell // LAYOUT-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:24 IsSigned:0 StorageSize:32 StorageOffset:{{(4|8)}}
154*ee994750SNathan Sidwell 
155*ee994750SNathan Sidwell // LAYOUT-DWN32-NEXT: <CGBitFieldInfo Offset:{{[0-9]+}} Size:24 IsSigned:0 StorageSize:32 StorageOffset:{{(4|8)}}
156*ee994750SNathan Sidwell // CHECK-NEXT: ]>
157