238 lines · c
1// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s2 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 constant [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 414 15void f1(void) {16 // Scalars in braces.17 int a = { 1 };18}19 20void 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 29typedef void (* F)(void);30extern void foo(void);31struct S { F f; };32void f3(void) {33 struct S a[1] = { { foo } };34}35 36// Constants37// CHECK-DAG: @g3 ={{.*}} constant i32 1038// CHECK-DAG: @f4.g4 = internal constant i32 1239const int g3 = 10;40int f4(void) {41 static const int g4 = 12;42 return g4;43}44 45// PR653746typedef union vec3 {47 struct { double x, y, z; };48 double component[3];49} vec3;50vec3 f5(vec3 value) {51 return (vec3) {{52 .x = value.x53 }};54}55 56void f6(void) {57 int x;58 long ids[] = { (long) &x }; 59}60 61 62 63 64// CHECK-DAG: @test7 ={{.*}} global{{.*}}{ i32 0, [4 x i8] c"bar\00" }65// PR821766struct a7 {67 int b;68 char v[];69};70 71struct a7 test7 = { .b = 0, .v = "bar" };72 73 74// CHECK-DAG: @huge_array ={{.*}} global {{.*}} <{ i32 1, i32 0, i32 2, i32 0, i32 3, [999999995 x i32] zeroinitializer }>75int huge_array[1000000000] = {1, 0, 2, 0, 3, 0, 0, 0};76 77// CHECK-DAG: @huge_struct ={{.*}} global {{.*}} { i32 1, <{ i32, [999999999 x i32] }> <{ i32 2, [999999999 x i32] zeroinitializer }> }78struct Huge {79 int a;80 int arr[1000 * 1000 * 1000];81} huge_struct = {1, {2, 0, 0, 0}};82 83// 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 }>84const char large_array_with_zeroes[1000] = {85 'a', 'b', 'c', 1, 2, 3, 'x', 'y', 'z', 'z', 'y', [20] = 'q'86};87 88char global;89 90// CHECK-DAG: @large_array_with_zeroes_2 ={{.*}} global <{ [10 x ptr], [90 x ptr] }> <{ [10 x ptr] [ptr null, ptr null, ptr null, ptr null, ptr null, ptr null, ptr null, ptr null, ptr null, ptr @global], [90 x ptr] zeroinitializer }>91const void *large_array_with_zeroes_2[100] = {92 [9] = &global93};94// CHECK-DAG: @large_array_with_zeroes_3 ={{.*}} global <{ [10 x ptr], [990 x ptr] }> <{ [10 x ptr] [ptr null, ptr null, ptr null, ptr null, ptr null, ptr null, ptr null, ptr null, ptr null, ptr @global], [990 x ptr] zeroinitializer }>95const void *large_array_with_zeroes_3[1000] = {96 [9] = &global97};98 99// PR279 comment #3100char test8(int X) {101 char str[100000] = "abc"; // tail should be memset.102 return str[X];103 // CHECK-LABEL: @test8(104 // CHECK: call void @llvm.memset105 // CHECK: store i8 97, ptr %{{[0-9]*}}, align 1106 // CHECK: store i8 98, ptr %{{[0-9]*}}, align 1107 // CHECK: store i8 99, ptr %{{[0-9]*}}, align 1108 // CHECK-NOT: getelementptr109 // CHECK: load110}111 112void bar(void*);113 114// PR279115void test9(int X) {116 int Arr[100] = { X }; // Should use memset117 bar(Arr);118 // CHECK-LABEL: @test9(119 // CHECK: call void @llvm.memset120 // CHECK-NOT: store i32 0121 // CHECK: call void @bar122}123 124struct a {125 int a, b, c, d, e, f, g, h, i, j, k, *p;126};127 128struct b {129 struct a a,b,c,d,e,f,g;130};131 132void test10(int X) {133 struct b S = { .a.a = X, .d.e = X, .f.e = 0, .f.f = 0, .f.p = 0 };134 bar(&S);135 136 // CHECK-LABEL: @test10(137 // CHECK: call void @llvm.memset138 // CHECK-NOT: store i32 0139 // CHECK: call void @bar140}141 142void nonzeroMemseti8(void) {143 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, };144 // CHECK-LABEL: @nonzeroMemseti8(145 // CHECK-NOT: store146 // CHECK-NOT: memcpy147 // CHECK: call void @llvm.memset.p0.i32(ptr {{.*}}, i8 42, i32 33, i1 false)148}149 150void nonzeroMemseti16(void) {151 unsigned short arr[17] = { 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, 0x4242, };152 // CHECK-LABEL: @nonzeroMemseti16(153 // CHECK-NOT: store154 // CHECK-NOT: memcpy155 // CHECK: call void @llvm.memset.p0.i32(ptr {{.*}}, i8 66, i32 34, i1 false)156}157 158void nonzeroMemseti32(void) {159 unsigned arr[9] = { 0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0, 0xF0F0F0F0, };160 // CHECK-LABEL: @nonzeroMemseti32(161 // CHECK-NOT: store162 // CHECK-NOT: memcpy163 // CHECK: call void @llvm.memset.p0.i32(ptr {{.*}}, i8 -16, i32 36, i1 false)164}165 166void nonzeroMemseti64(void) {167 unsigned long long arr[7] = { 0xAAAAAAAAAAAAAAAA, 0xAAAAAAAAAAAAAAAA, 0xAAAAAAAAAAAAAAAA, 0xAAAAAAAAAAAAAAAA, 0xAAAAAAAAAAAAAAAA, 0xAAAAAAAAAAAAAAAA, 0xAAAAAAAAAAAAAAAA, };168 // CHECK-LABEL: @nonzeroMemseti64(169 // CHECK-NOT: store170 // CHECK-NOT: memcpy171 // CHECK: call void @llvm.memset.p0.i32(ptr {{.*}}, i8 -86, i32 56, i1 false)172}173 174void nonzeroMemsetf32(void) {175 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, };176 // CHECK-LABEL: @nonzeroMemsetf32(177 // CHECK-NOT: store178 // CHECK-NOT: memcpy179 // CHECK: call void @llvm.memset.p0.i32(ptr {{.*}}, i8 101, i32 36, i1 false)180}181 182void nonzeroMemsetf64(void) {183 double arr[7] = { 0x1.4444444444444p+69, 0x1.4444444444444p+69, 0x1.4444444444444p+69, 0x1.4444444444444p+69, 0x1.4444444444444p+69, 0x1.4444444444444p+69, 0x1.4444444444444p+69, };184 // CHECK-LABEL: @nonzeroMemsetf64(185 // CHECK-NOT: store186 // CHECK-NOT: memcpy187 // CHECK: call void @llvm.memset.p0.i32(ptr {{.*}}, i8 68, i32 56, i1 false)188}189 190// PR9257191struct test11S {192 int A[10];193};194void test11(struct test11S *P) {195 *P = (struct test11S) { .A = { [0 ... 3] = 4 } };196 // CHECK-LABEL: @test11(197 // CHECK: store i32 4, ptr %{{.*}}, align 4198 // CHECK: store i32 4, ptr %{{.*}}, align 4199 // CHECK: store i32 4, ptr %{{.*}}, align 4200 // CHECK: store i32 4, ptr %{{.*}}, align 4201 // CHECK: ret void202}203 204 205// Verify that we can convert a recursive struct with a memory that returns206// an instance of the struct we're converting.207struct test12 {208 struct test12 (*p)(void);209} test12g;210 211 212void test13(int x) {213 struct X { int a; int b : 10; int c; };214 struct X y = {.c = x};215 // CHECK-LABEL: @test13(216 // CHECK: and i16 {{.*}}, -1024217}218 219// CHECK-LABEL: @PR20473(220void PR20473(void) {221 // CHECK: memcpy{{.*}}222 bar((char[2]) {""});223 // CHECK: memcpy{{.*}}224 bar((char[3]) {""});225}226 227// Test that we initialize large member arrays by copying from a global and not228// with a series of stores.229struct S14 { int a[16]; };230 231void test14(struct S14 *s14) {232 // CHECK-LABEL: @test14(233 // CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 {{.*}}, ptr align 4 [[INIT14]], i32 64, i1 false)234 // CHECK-NOT: store235 // CHECK: ret void236 *s14 = (struct S14) { { [5 ... 11] = 17 } };237}238