Clang Project

clang_source_code/test/CodeGen/init.c
1// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s
2
3struct I { int k[3]; };
4struct M { struct I o[2]; };
5struct M v1[1] = { [0].o[0 ... 1].k[0 ... 1] = 4, 5 };
6unsigned v2[2][3] = {[0 ... 1][0 ... 1] = 2222, 3333};
7
8// CHECK-DAG: %struct.M = type { [2 x %struct.I] }
9// CHECK-DAG: %struct.I = type { [3 x i32] }
10
11// CHECK-DAG: [1 x %struct.M] [%struct.M { [2 x %struct.I] [%struct.I { [3 x i32] [i32 4, i32 4, i32 0] }, %struct.I { [3 x i32] [i32 4, i32 4, i32 5] }] }],
12// CHECK-DAG: [2 x [3 x i32]] {{[[][[]}}3 x i32] [i32 2222, i32 2222, i32 0], [3 x i32] [i32 2222, i32 2222, i32 3333]],
13// CHECK-DAG: [[INIT14:.*]] = private global [16 x i32] [i32 0, i32 0, i32 0, i32 0, i32 0, i32 17, i32 17, i32 17, i32 17, i32 17, i32 17, i32 17, i32 0, i32 0, i32 0, i32 0], align 4
14
15void f1() {
16  // Scalars in braces.
17  int a = { 1 };
18}
19
20void f2() {
21  int a[2][2] = { { 1, 2 }, { 3, 4 } };
22  int b[3][3] = { { 1, 2 }, { 3, 4 } };
23  int *c[2] = { &a[1][1], &b[2][2] };
24  int *d[2][2] = { {&a[1][1], &b[2][2]}, {&a[0][0], &b[1][1]} };
25  int *e[3][3] = { {&a[1][1], &b[2][2]}, {&a[0][0], &b[1][1]} };
26  char ext[3][3] = {".Y",".U",".V"};
27}
28
29typedef void (* F)(void);
30extern void foo(void);
31struct S { F f; };
32void f3() {
33  struct S a[1] = { { foo } };
34}
35
36// Constants
37// CHECK-DAG: @g3 = constant i32 10
38// CHECK-DAG: @f4.g4 = internal constant i32 12
39const int g3 = 10;
40int f4() {
41  static const int g4 = 12;
42  return g4;
43}
44
45// PR6537
46typedef union vec3 {
47  struct { double x, y, z; };
48  double component[3];
49} vec3;
50vec3 f5(vec3 value) {
51  return (vec3) {{
52    .x = value.x
53  }};
54}
55
56// rdar://problem/8154689
57void f6() {
58  int x;
59  long ids[] = { (long) &x };  
60}
61
62
63
64
65// CHECK-DAG: @test7 = global{{.*}}{ i32 0, [4 x i8] c"bar\00" }
66// PR8217
67struct a7 {
68  int  b;
69  char v[];
70};
71
72struct a7 test7 = { .b = 0, .v = "bar" };
73
74
75// CHECK-DAG: @huge_array = global {{.*}} <{ i32 1, i32 0, i32 2, i32 0, i32 3, [999999995 x i32] zeroinitializer }>
76int huge_array[1000000000] = {1, 0, 2, 0, 3, 0, 0, 0};
77
78// CHECK-DAG: @huge_struct = global {{.*}} { i32 1, <{ i32, [999999999 x i32] }> <{ i32 2, [999999999 x i32] zeroinitializer }> }
79struct Huge {
80  int a;
81  int arr[1000 * 1000 * 1000];
82} huge_struct = {1, {2, 0, 0, 0}};
83
84// CHECK-DAG: @large_array_with_zeroes = constant <{ [21 x i8], [979 x i8] }> <{ [21 x i8] c"abc\01\02\03xyzzy\00\00\00\00\00\00\00\00\00q", [979 x i8] zeroinitializer }>
85const char large_array_with_zeroes[1000] = {
86  'a', 'b', 'c', 1, 2, 3, 'x', 'y', 'z', 'z', 'y', [20] = 'q'
87};
88
89char global;
90
91// CHECK-DAG: @large_array_with_zeroes_2 = global <{ [10 x i8*], [90 x i8*] }> <{ [10 x i8*] [i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* @global], [90 x i8*] zeroinitializer }>
92const void *large_array_with_zeroes_2[100] = {
93  [9] = &global
94};
95// CHECK-DAG: @large_array_with_zeroes_3 = global <{ [10 x i8*], [990 x i8*] }> <{ [10 x i8*] [i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* @global], [990 x i8*] zeroinitializer }>
96const void *large_array_with_zeroes_3[1000] = {
97  [9] = &global
98};
99
100// PR279 comment #3
101char test8(int X) {
102  char str[100000] = "abc"; // tail should be memset.
103  return str[X];
104  // CHECK-LABEL: @test8(
105  // CHECK: call void @llvm.memset
106  // CHECK: store i8 97, i8* %{{[0-9]*}}, align 1
107  // CHECK: store i8 98, i8* %{{[0-9]*}}, align 1
108  // CHECK: store i8 99, i8* %{{[0-9]*}}, align 1
109  // CHECK-NOT: getelementptr
110  // CHECK: load
111}
112
113void bar(void*);
114
115// PR279
116void test9(int X) {
117  int Arr[100] = { X };     // Should use memset
118  bar(Arr);
119  // CHECK-LABEL: @test9(
120  // CHECK: call void @llvm.memset
121  // CHECK-NOT: store i32 0
122  // CHECK: call void @bar
123}
124
125struct a {
126  int a, b, c, d, e, f, g, h, i, j, k, *p;
127};
128
129struct b {
130  struct a a,b,c,d,e,f,g;
131};
132
133void test10(int X) {
134  struct b S = { .a.a = X, .d.e = X, .f.e = 0, .f.f = 0, .f.p = 0 };
135  bar(&S);
136
137  // CHECK-LABEL: @test10(
138  // CHECK: call void @llvm.memset
139  // CHECK-NOT: store i32 0
140  // CHECK: call void @bar
141}
142
143void nonzeroMemseti8() {
144  char arr[33] = { 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, };
145  // CHECK-LABEL: @nonzeroMemseti8(
146  // CHECK-NOT: store
147  // CHECK-NOT: memcpy
148  // CHECK: call void @llvm.memset.p0i8.i32(i8* {{.*}}, i8 42, i32 33, i1 false)
149}
150
151void nonzeroMemseti16() {
152  unsigned short arr[17] = { 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, };
153  // CHECK-LABEL: @nonzeroMemseti16(
154  // CHECK-NOT: store
155  // CHECK-NOT: memcpy
156  // CHECK: call void @llvm.memset.p0i8.i32(i8* {{.*}}, i8 66, i32 34, i1 false)
157}
158
159void nonzeroMemseti32() {
160  unsigned arr[9] = { 0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0, };
161  // CHECK-LABEL: @nonzeroMemseti32(
162  // CHECK-NOT: store
163  // CHECK-NOT: memcpy
164  // CHECK: call void @llvm.memset.p0i8.i32(i8* {{.*}}, i8 -16, i32 36, i1 false)
165}
166
167void nonzeroMemseti64() {
168  unsigned long long arr[7] = { 0xAAAAAAAAAAAAAAAA, 0xAAAAAAAAAAAAAAAA, 0xAAAAAAAAAAAAAAAA, 0xAAAAAAAAAAAAAAAA, 0xAAAAAAAAAAAAAAAA,  0xAAAAAAAAAAAAAAAA,  0xAAAAAAAAAAAAAAAA,  };
169  // CHECK-LABEL: @nonzeroMemseti64(
170  // CHECK-NOT: store
171  // CHECK-NOT: memcpy
172  // CHECK: call void @llvm.memset.p0i8.i32(i8* {{.*}}, i8 -86, i32 56, i1 false)
173}
174
175void nonzeroMemsetf32() {
176  float arr[9] = { 0x1.cacacap+75, 0x1.cacacap+75, 0x1.cacacap+75, 0x1.cacacap+75, 0x1.cacacap+75, 0x1.cacacap+75, 0x1.cacacap+75, 0x1.cacacap+75, 0x1.cacacap+75, };
177  // CHECK-LABEL: @nonzeroMemsetf32(
178  // CHECK-NOT: store
179  // CHECK-NOT: memcpy
180  // CHECK: call void @llvm.memset.p0i8.i32(i8* {{.*}}, i8 101, i32 36, i1 false)
181}
182
183void nonzeroMemsetf64() {
184  double arr[7] = { 0x1.4444444444444p+69, 0x1.4444444444444p+69, 0x1.4444444444444p+69, 0x1.4444444444444p+69, 0x1.4444444444444p+69, 0x1.4444444444444p+69, 0x1.4444444444444p+69, };
185  // CHECK-LABEL: @nonzeroMemsetf64(
186  // CHECK-NOT: store
187  // CHECK-NOT: memcpy
188  // CHECK: call void @llvm.memset.p0i8.i32(i8* {{.*}}, i8 68, i32 56, i1 false)
189}
190
191void nonzeroPaddedUnionMemset() {
192  union U { char c; int i; };
193  union U arr[9] = { 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, };
194  // CHECK-LABEL: @nonzeroPaddedUnionMemset(
195  // CHECK-NOT: store
196  // CHECK-NOT: memcpy
197  // CHECK: call void @llvm.memset.p0i8.i32(i8* {{.*}}, i8 -16, i32 36, i1 false)
198}
199
200void nonzeroNestedMemset() {
201  union U { char c; int i; };
202  struct S { union U u; short i; };
203  struct S arr[5] = { { {0xF0}, 0xF0F0 }, { {0xF0}, 0xF0F0 }, { {0xF0}, 0xF0F0 }, { {0xF0}, 0xF0F0 }, { {0xF0}, 0xF0F0 }, };
204  // CHECK-LABEL: @nonzeroNestedMemset(
205  // CHECK-NOT: store
206  // CHECK-NOT: memcpy
207  // CHECK: call void @llvm.memset.p0i8.i32(i8* {{.*}}, i8 -16, i32 40, i1 false)
208}
209
210// PR9257
211struct test11S {
212  int A[10];
213};
214void test11(struct test11S *P) {
215  *P = (struct test11S) { .A = { [0 ... 3] = 4 } };
216  // CHECK-LABEL: @test11(
217  // CHECK: store i32 4, i32* %{{.*}}, align 4
218  // CHECK: store i32 4, i32* %{{.*}}, align 4
219  // CHECK: store i32 4, i32* %{{.*}}, align 4
220  // CHECK: store i32 4, i32* %{{.*}}, align 4
221  // CHECK: ret void
222}
223
224
225// Verify that we can convert a recursive struct with a memory that returns
226// an instance of the struct we're converting.
227struct test12 {
228  struct test12 (*p)(void);
229} test12g;
230
231
232void test13(int x) {
233  struct X { int a; int b : 10; int c; };
234  struct X y = {.c = x};
235  // CHECK-LABEL: @test13(
236  // CHECK: and i16 {{.*}}, -1024
237}
238
239// CHECK-LABEL: @PR20473(
240void PR20473() {
241  // CHECK: memcpy{{.*}}getelementptr inbounds ([2 x i8], [2 x i8]* @
242  bar((char[2]) {""});
243  // CHECK: memcpy{{.*}}getelementptr inbounds ([3 x i8], [3 x i8]* @
244  bar((char[3]) {""});
245}
246
247// Test that we initialize large member arrays by copying from a global and not
248// with a series of stores.
249struct S14 { int a[16]; };
250
251void test14(struct S14 *s14) {
252  // CHECK-LABEL: @test14(
253  // CHECK: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 {{.*}}, i8* align 4 {{.*}} [[INIT14]] {{.*}}, i32 64, i1 false)
254  // CHECK-NOT: store
255  // CHECK: ret void
256  *s14 = (struct S14) { { [5 ... 11] = 17 } };
257}
258