xref: /llvm-project/clang/test/CodeGen/linux-kernel-struct-union-initializer.c (revision 627746581b8fde4143533937130f420bbbdf9ddf)
1*62774658Syabinc // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-globals all --version 5
2*62774658Syabinc // RUN: %clang_cc1 -triple x86_64-unknown-unknown -std=gnu11 -verify -emit-llvm %s -o - | FileCheck %s
3*62774658Syabinc // expected-no-diagnostics
4*62774658Syabinc 
5*62774658Syabinc union U1 {
6*62774658Syabinc   int x;
7*62774658Syabinc   char y[16];
8*62774658Syabinc };
9*62774658Syabinc 
10*62774658Syabinc struct S1 {
11*62774658Syabinc   int x;
12*62774658Syabinc   union U1 y;
13*62774658Syabinc };
14*62774658Syabinc 
15*62774658Syabinc union U2 {
16*62774658Syabinc   int x;
17*62774658Syabinc   char y[16];
18*62774658Syabinc } __attribute__((__aligned__(32)));
19*62774658Syabinc 
20*62774658Syabinc struct S2 {
21*62774658Syabinc   int x;
22*62774658Syabinc   long long y;
23*62774658Syabinc   char z[8];
24*62774658Syabinc } __attribute__((__aligned__(32)));
25*62774658Syabinc 
26*62774658Syabinc struct S3 {
27*62774658Syabinc   char x;
28*62774658Syabinc   unsigned char y : 4;
29*62774658Syabinc   unsigned char z : 7;
30*62774658Syabinc } __attribute__((packed));
31*62774658Syabinc 
32*62774658Syabinc union U1 global_u1 = {};
33*62774658Syabinc 
34*62774658Syabinc union U1 global_u2 = {3};
35*62774658Syabinc 
36*62774658Syabinc union U1 global_u2_from_cast = (union U1)3;
37*62774658Syabinc 
38*62774658Syabinc struct S1 global_s1 = {};
39*62774658Syabinc 
40*62774658Syabinc struct S1 global_s2 = {
41*62774658Syabinc     .x = 3,
42*62774658Syabinc };
43*62774658Syabinc 
44*62774658Syabinc struct S1 global_s3 = {.x = 3, .y = {.x = 6}};
45*62774658Syabinc 
46*62774658Syabinc const union U1 global_const_u1 = {4};
47*62774658Syabinc struct S1 global_s3_from_const_u1 = {.y = global_const_u1};
48*62774658Syabinc 
49*62774658Syabinc union U2 global_u3 = {};
50*62774658Syabinc 
51*62774658Syabinc struct S2 global_s4 = {};
52*62774658Syabinc 
53*62774658Syabinc struct S2 global_s5 = {.x = 1};
54*62774658Syabinc 
55*62774658Syabinc struct S3 global_s6 = {101,  15, 123};
56*62774658Syabinc 
57*62774658Syabinc // Test empty initializer for union.
58*62774658Syabinc //.
59*62774658Syabinc // CHECK: @global_u1 = global %union.U1 zeroinitializer, align 4
60*62774658Syabinc // CHECK: @global_u2 = global %union.U1 { i32 3, [12 x i8] zeroinitializer }, align 4
61*62774658Syabinc // CHECK: @global_u2_from_cast = global { i32, [12 x i8] } { i32 3, [12 x i8] zeroinitializer }, align 4
62*62774658Syabinc // CHECK: @global_s1 = global %struct.S1 zeroinitializer, align 4
63*62774658Syabinc // CHECK: @global_s2 = global %struct.S1 { i32 3, %union.U1 zeroinitializer }, align 4
64*62774658Syabinc // CHECK: @global_s3 = global %struct.S1 { i32 3, %union.U1 { i32 6, [12 x i8] zeroinitializer } }, align 4
65*62774658Syabinc // CHECK: @global_const_u1 = constant %union.U1 { i32 4, [12 x i8] zeroinitializer }, align 4
66*62774658Syabinc // CHECK: @global_s3_from_const_u1 = global %struct.S1 { i32 0, %union.U1 { i32 4, [12 x i8] zeroinitializer } }, align 4
67*62774658Syabinc // CHECK: @global_u3 = global %union.U2 zeroinitializer, align 32
68*62774658Syabinc // CHECK: @global_s4 = global { i32, [4 x i8], i64, [8 x i8], [8 x i8] } zeroinitializer, align 32
69*62774658Syabinc // CHECK: @global_s5 = global { i32, [4 x i8], i64, [8 x i8], [8 x i8] } { i32 1, [4 x i8] zeroinitializer, i64 0, [8 x i8] zeroinitializer, [8 x i8] zeroinitializer }, align 32
70*62774658Syabinc // CHECK: @global_s6 = global { i8, i8, i8 } { i8 101, i8 -65, i8 7 }, align 1
71*62774658Syabinc // CHECK: @test2.a = internal global %union.U1 zeroinitializer, align 4
72*62774658Syabinc // CHECK: @__const.test3.a = private unnamed_addr constant %union.U1 { i32 3, [12 x i8] zeroinitializer }, align 4
73*62774658Syabinc // CHECK: @test4.a = internal global %union.U1 { i32 3, [12 x i8] zeroinitializer }, align 4
74*62774658Syabinc // CHECK: @test6.s = internal global %struct.S1 zeroinitializer, align 4
75*62774658Syabinc // CHECK: @__const.test7.s = private unnamed_addr constant %struct.S1 { i32 3, %union.U1 zeroinitializer }, align 4
76*62774658Syabinc // CHECK: @test8.s = internal global %struct.S1 { i32 3, %union.U1 zeroinitializer }, align 4
77*62774658Syabinc // CHECK: @__const.test9.s = private unnamed_addr constant %struct.S1 { i32 3, %union.U1 { i32 6, [12 x i8] zeroinitializer } }, align 4
78*62774658Syabinc // CHECK: @test10.s = internal global %struct.S1 { i32 3, %union.U1 { i32 6, [12 x i8] zeroinitializer } }, align 4
79*62774658Syabinc // CHECK: @test12.a = internal global %union.U2 zeroinitializer, align 32
80*62774658Syabinc // CHECK: @test14.s = internal global { i32, [4 x i8], i64, [8 x i8], [8 x i8] } zeroinitializer, align 32
81*62774658Syabinc // CHECK: @__const.test15.s = private unnamed_addr constant { i32, [4 x i8], i64, [8 x i8], [8 x i8] } { i32 1, [4 x i8] zeroinitializer, i64 0, [8 x i8] zeroinitializer, [8 x i8] zeroinitializer }, align 32
82*62774658Syabinc // CHECK: @test16.s = internal global { i32, [4 x i8], i64, [8 x i8], [8 x i8] } { i32 1, [4 x i8] zeroinitializer, i64 0, [8 x i8] zeroinitializer, [8 x i8] zeroinitializer }, align 32
83*62774658Syabinc //.
84*62774658Syabinc // CHECK-LABEL: define dso_local void @test1(
85*62774658Syabinc // CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
86*62774658Syabinc // CHECK-NEXT:  [[ENTRY:.*:]]
87*62774658Syabinc // CHECK-NEXT:    [[A:%.*]] = alloca [[UNION_U1:%.*]], align 4
88*62774658Syabinc // CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 4 [[A]], i8 0, i64 16, i1 false)
89*62774658Syabinc // CHECK-NEXT:    ret void
90*62774658Syabinc //
91*62774658Syabinc void test1() {
92*62774658Syabinc   union U1 a = {};
93*62774658Syabinc }
94*62774658Syabinc 
95*62774658Syabinc // Test empty initializer for union. Use static variable.
96*62774658Syabinc // CHECK-LABEL: define dso_local void @test2(
97*62774658Syabinc // CHECK-SAME: ) #[[ATTR0]] {
98*62774658Syabinc // CHECK-NEXT:  [[ENTRY:.*:]]
99*62774658Syabinc // CHECK-NEXT:    ret void
100*62774658Syabinc //
101*62774658Syabinc void test2() {
102*62774658Syabinc   static union U1 a = {};
103*62774658Syabinc }
104*62774658Syabinc 
105*62774658Syabinc // Test only initializing a small field for union.
106*62774658Syabinc // CHECK-LABEL: define dso_local void @test3(
107*62774658Syabinc // CHECK-SAME: ) #[[ATTR0]] {
108*62774658Syabinc // CHECK-NEXT:  [[ENTRY:.*:]]
109*62774658Syabinc // CHECK-NEXT:    [[A:%.*]] = alloca [[UNION_U1:%.*]], align 4
110*62774658Syabinc // CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[A]], ptr align 4 @__const.test3.a, i64 16, i1 false)
111*62774658Syabinc // CHECK-NEXT:    ret void
112*62774658Syabinc //
113*62774658Syabinc void test3() {
114*62774658Syabinc   union U1 a = {3};
115*62774658Syabinc }
116*62774658Syabinc 
117*62774658Syabinc // Test only initializing a small field for union. Use static variable.
118*62774658Syabinc // CHECK-LABEL: define dso_local void @test4(
119*62774658Syabinc // CHECK-SAME: ) #[[ATTR0]] {
120*62774658Syabinc // CHECK-NEXT:  [[ENTRY:.*:]]
121*62774658Syabinc // CHECK-NEXT:    ret void
122*62774658Syabinc //
123*62774658Syabinc void test4() {
124*62774658Syabinc   static union U1 a = {3};
125*62774658Syabinc }
126*62774658Syabinc 
127*62774658Syabinc // Test union in struct. Use empty initializer for the struct.
128*62774658Syabinc // CHECK-LABEL: define dso_local void @test5(
129*62774658Syabinc // CHECK-SAME: ) #[[ATTR0]] {
130*62774658Syabinc // CHECK-NEXT:  [[ENTRY:.*:]]
131*62774658Syabinc // CHECK-NEXT:    [[S:%.*]] = alloca [[STRUCT_S1:%.*]], align 4
132*62774658Syabinc // CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 4 [[S]], i8 0, i64 20, i1 false)
133*62774658Syabinc // CHECK-NEXT:    ret void
134*62774658Syabinc //
135*62774658Syabinc void test5() {
136*62774658Syabinc   struct S1 s = {};
137*62774658Syabinc }
138*62774658Syabinc 
139*62774658Syabinc // Test union in struct. Use empty initializer for the struct. Use static variable.
140*62774658Syabinc // CHECK-LABEL: define dso_local void @test6(
141*62774658Syabinc // CHECK-SAME: ) #[[ATTR0]] {
142*62774658Syabinc // CHECK-NEXT:  [[ENTRY:.*:]]
143*62774658Syabinc // CHECK-NEXT:    ret void
144*62774658Syabinc //
145*62774658Syabinc void test6() {
146*62774658Syabinc   static struct S1 s = {};
147*62774658Syabinc }
148*62774658Syabinc 
149*62774658Syabinc // Test union in struct. Initialize other fields of the struct.
150*62774658Syabinc // CHECK-LABEL: define dso_local void @test7(
151*62774658Syabinc // CHECK-SAME: ) #[[ATTR0]] {
152*62774658Syabinc // CHECK-NEXT:  [[ENTRY:.*:]]
153*62774658Syabinc // CHECK-NEXT:    [[S:%.*]] = alloca [[STRUCT_S1:%.*]], align 4
154*62774658Syabinc // CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[S]], ptr align 4 @__const.test7.s, i64 20, i1 false)
155*62774658Syabinc // CHECK-NEXT:    ret void
156*62774658Syabinc //
157*62774658Syabinc void test7() {
158*62774658Syabinc   struct S1 s = {
159*62774658Syabinc       .x = 3,
160*62774658Syabinc   };
161*62774658Syabinc }
162*62774658Syabinc 
163*62774658Syabinc // Test union in struct. Initialize other fields of the struct. Use static variable.
164*62774658Syabinc // CHECK-LABEL: define dso_local void @test8(
165*62774658Syabinc // CHECK-SAME: ) #[[ATTR0]] {
166*62774658Syabinc // CHECK-NEXT:  [[ENTRY:.*:]]
167*62774658Syabinc // CHECK-NEXT:    ret void
168*62774658Syabinc //
169*62774658Syabinc void test8() {
170*62774658Syabinc   static struct S1 s = {
171*62774658Syabinc       .x = 3,
172*62774658Syabinc   };
173*62774658Syabinc }
174*62774658Syabinc 
175*62774658Syabinc // Test union in struct. Initialize a small field for union.
176*62774658Syabinc // CHECK-LABEL: define dso_local void @test9(
177*62774658Syabinc // CHECK-SAME: ) #[[ATTR0]] {
178*62774658Syabinc // CHECK-NEXT:  [[ENTRY:.*:]]
179*62774658Syabinc // CHECK-NEXT:    [[S:%.*]] = alloca [[STRUCT_S1:%.*]], align 4
180*62774658Syabinc // CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[S]], ptr align 4 @__const.test9.s, i64 20, i1 false)
181*62774658Syabinc // CHECK-NEXT:    ret void
182*62774658Syabinc //
183*62774658Syabinc void test9() {
184*62774658Syabinc   struct S1 s = {.x = 3,
185*62774658Syabinc                 .y = {
186*62774658Syabinc                     .x = 6,
187*62774658Syabinc                 }};
188*62774658Syabinc }
189*62774658Syabinc 
190*62774658Syabinc // Test union in struct. Initialize a small field for union. Use static variable.
191*62774658Syabinc // CHECK-LABEL: define dso_local void @test10(
192*62774658Syabinc // CHECK-SAME: ) #[[ATTR0]] {
193*62774658Syabinc // CHECK-NEXT:  [[ENTRY:.*:]]
194*62774658Syabinc // CHECK-NEXT:    ret void
195*62774658Syabinc //
196*62774658Syabinc void test10() {
197*62774658Syabinc   static struct S1 s = {.x = 3,
198*62774658Syabinc                        .y = {
199*62774658Syabinc                            .x = 6,
200*62774658Syabinc                        }};
201*62774658Syabinc }
202*62774658Syabinc 
203*62774658Syabinc // Test empty initializer for union with padding.
204*62774658Syabinc // CHECK-LABEL: define dso_local void @test11(
205*62774658Syabinc // CHECK-SAME: ) #[[ATTR0]] {
206*62774658Syabinc // CHECK-NEXT:  [[ENTRY:.*:]]
207*62774658Syabinc // CHECK-NEXT:    [[A:%.*]] = alloca [[UNION_U2:%.*]], align 32
208*62774658Syabinc // CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 32 [[A]], i8 0, i64 32, i1 false)
209*62774658Syabinc // CHECK-NEXT:    ret void
210*62774658Syabinc //
211*62774658Syabinc void test11() {
212*62774658Syabinc   union U2 a = {};
213*62774658Syabinc }
214*62774658Syabinc 
215*62774658Syabinc // Test empty initializer for union with padding. Use static variable.
216*62774658Syabinc // CHECK-LABEL: define dso_local void @test12(
217*62774658Syabinc // CHECK-SAME: ) #[[ATTR0]] {
218*62774658Syabinc // CHECK-NEXT:  [[ENTRY:.*:]]
219*62774658Syabinc // CHECK-NEXT:    ret void
220*62774658Syabinc //
221*62774658Syabinc void test12() {
222*62774658Syabinc   static union U2 a = {};
223*62774658Syabinc }
224*62774658Syabinc 
225*62774658Syabinc // Test empty initializer for struct with padding.
226*62774658Syabinc // CHECK-LABEL: define dso_local void @test13(
227*62774658Syabinc // CHECK-SAME: ) #[[ATTR0]] {
228*62774658Syabinc // CHECK-NEXT:  [[ENTRY:.*:]]
229*62774658Syabinc // CHECK-NEXT:    [[S:%.*]] = alloca [[STRUCT_S2:%.*]], align 32
230*62774658Syabinc // CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 32 [[S]], i8 0, i64 32, i1 false)
231*62774658Syabinc // CHECK-NEXT:    ret void
232*62774658Syabinc //
233*62774658Syabinc void test13() {
234*62774658Syabinc   struct S2 s = {};
235*62774658Syabinc }
236*62774658Syabinc 
237*62774658Syabinc // Test empty initializer for struct with padding. Use static variable.
238*62774658Syabinc // CHECK-LABEL: define dso_local void @test14(
239*62774658Syabinc // CHECK-SAME: ) #[[ATTR0]] {
240*62774658Syabinc // CHECK-NEXT:  [[ENTRY:.*:]]
241*62774658Syabinc // CHECK-NEXT:    ret void
242*62774658Syabinc //
243*62774658Syabinc void test14() {
244*62774658Syabinc   static struct S2 s = {};
245*62774658Syabinc }
246*62774658Syabinc 
247*62774658Syabinc // Test partial initialization for struct with padding.
248*62774658Syabinc // CHECK-LABEL: define dso_local void @test15(
249*62774658Syabinc // CHECK-SAME: ) #[[ATTR0]] {
250*62774658Syabinc // CHECK-NEXT:  [[ENTRY:.*:]]
251*62774658Syabinc // CHECK-NEXT:    [[S:%.*]] = alloca [[STRUCT_S2:%.*]], align 32
252*62774658Syabinc // CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 32 [[S]], ptr align 32 @__const.test15.s, i64 32, i1 false)
253*62774658Syabinc // CHECK-NEXT:    ret void
254*62774658Syabinc //
255*62774658Syabinc void test15() {
256*62774658Syabinc   struct S2 s = {.x = 1};
257*62774658Syabinc }
258*62774658Syabinc 
259*62774658Syabinc // Test partial initialization for struct with padding. Use static variable.
260*62774658Syabinc // CHECK-LABEL: define dso_local void @test16(
261*62774658Syabinc // CHECK-SAME: ) #[[ATTR0]] {
262*62774658Syabinc // CHECK-NEXT:  [[ENTRY:.*:]]
263*62774658Syabinc // CHECK-NEXT:    ret void
264*62774658Syabinc //
265*62774658Syabinc void test16() {
266*62774658Syabinc   static struct S2 s = {.x = 1};
267*62774658Syabinc }
268*62774658Syabinc //.
269*62774658Syabinc // CHECK: attributes #[[ATTR0]] = { noinline nounwind optnone "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
270*62774658Syabinc // CHECK: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) }
271*62774658Syabinc // CHECK: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
272*62774658Syabinc //.
273*62774658Syabinc // CHECK: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
274*62774658Syabinc // CHECK: [[META1:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"}
275*62774658Syabinc //.
276