1 // RUN: %clang_cc1 -no-opaque-pointers -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 15 void f1(void) { 16 // Scalars in braces. 17 int a = { 1 }; 18 } 19 20 void f2(void) { 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; }; 32 void f3(void) { 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; 40 int f4(void) { 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; 50 vec3 f5(vec3 value) { 51 return (vec3) {{ 52 .x = value.x 53 }}; 54 } 55 56 // rdar://problem/8154689 57 void f6(void) { 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 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 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 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 143 void nonzeroMemseti8(void) { 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 151 void nonzeroMemseti16(void) { 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 159 void nonzeroMemseti32(void) { 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 167 void nonzeroMemseti64(void) { 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 175 void nonzeroMemsetf32(void) { 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 183 void nonzeroMemsetf64(void) { 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 191 void nonzeroPaddedUnionMemset(void) { 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 200 void nonzeroNestedMemset(void) { 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 }; 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 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( 240 void PR20473(void) { 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 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