1 // RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s
2
3 struct I { int k[3]; };
4 struct M { struct I o[2]; };
5 struct M v1[1] = { [0].o[0 ... 1].k[0 ... 1] = 4, 5 };
6 unsigned 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
f1()15 void f1() {
16 // Scalars in braces.
17 int a = { 1 };
18 }
19
f2()20 void 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
29 typedef void (* F)(void);
30 extern void foo(void);
31 struct S { F f; };
f3()32 void 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
39 const int g3 = 10;
f4()40 int f4() {
41 static const int g4 = 12;
42 return g4;
43 }
44
45 // PR6537
46 typedef union vec3 {
47 struct { double x, y, z; };
48 double component[3];
49 } vec3;
f5(vec3 value)50 vec3 f5(vec3 value) {
51 return (vec3) {{
52 .x = value.x
53 }};
54 }
55
56 // rdar://problem/8154689
f6()57 void 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
67 struct a7 {
68 int b;
69 char v[];
70 };
71
72 struct 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 }>
76 int 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 }> }
79 struct 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 }>
85 const char large_array_with_zeroes[1000] = {
86 'a', 'b', 'c', 1, 2, 3, 'x', 'y', 'z', 'z', 'y', [20] = 'q'
87 };
88
89 char 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 }>
92 const 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 }>
96 const void *large_array_with_zeroes_3[1000] = {
97 [9] = &global
98 };
99
100 // PR279 comment #3
test8(int X)101 char 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
113 void bar(void*);
114
115 // PR279
test9(int X)116 void 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
125 struct a {
126 int a, b, c, d, e, f, g, h, i, j, k, *p;
127 };
128
129 struct b {
130 struct a a,b,c,d,e,f,g;
131 };
132
test10(int X)133 void 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
nonzeroMemseti8()143 void 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
nonzeroMemseti16()151 void 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
nonzeroMemseti32()159 void 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
nonzeroMemseti64()167 void 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
nonzeroMemsetf32()175 void 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
nonzeroMemsetf64()183 void 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
nonzeroPaddedUnionMemset()191 void 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
nonzeroNestedMemset()200 void 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
211 struct test11S {
212 int A[10];
213 };
test11(struct test11S * P)214 void 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.
227 struct test12 {
228 struct test12 (*p)(void);
229 } test12g;
230
231
test13(int x)232 void 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(
PR20473()240 void 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.
249 struct S14 { int a[16]; };
250
test14(struct S14 * s14)251 void 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