xref: /minix3/external/bsd/llvm/dist/clang/test/CodeGen/vla.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc // RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s
2f4a2713aSLionel Sambuc 
3f4a2713aSLionel Sambuc int b(char* x);
4f4a2713aSLionel Sambuc 
5f4a2713aSLionel Sambuc // Extremely basic VLA test
a(int x)6f4a2713aSLionel Sambuc void a(int x) {
7f4a2713aSLionel Sambuc   char arry[x];
8f4a2713aSLionel Sambuc   arry[0] = 10;
9f4a2713aSLionel Sambuc   b(arry);
10f4a2713aSLionel Sambuc }
11f4a2713aSLionel Sambuc 
c(int n)12f4a2713aSLionel Sambuc int c(int n)
13f4a2713aSLionel Sambuc {
14f4a2713aSLionel Sambuc   return sizeof(int[n]);
15f4a2713aSLionel Sambuc }
16f4a2713aSLionel Sambuc 
f0(int x)17f4a2713aSLionel Sambuc int f0(int x) {
18f4a2713aSLionel Sambuc   int vla[x];
19f4a2713aSLionel Sambuc   return vla[x-1];
20f4a2713aSLionel Sambuc }
21f4a2713aSLionel Sambuc 
22f4a2713aSLionel Sambuc void
f(int count)23f4a2713aSLionel Sambuc f(int count)
24f4a2713aSLionel Sambuc {
25f4a2713aSLionel Sambuc  int a[count];
26f4a2713aSLionel Sambuc 
27f4a2713aSLionel Sambuc   do {  } while (0);
28f4a2713aSLionel Sambuc 
29f4a2713aSLionel Sambuc   if (a[0] != 3) {
30f4a2713aSLionel Sambuc   }
31f4a2713aSLionel Sambuc }
32f4a2713aSLionel Sambuc 
g(int count)33f4a2713aSLionel Sambuc void g(int count) {
34f4a2713aSLionel Sambuc   // Make sure we emit sizes correctly in some obscure cases
35f4a2713aSLionel Sambuc   int (*a[5])[count];
36f4a2713aSLionel Sambuc   int (*b)[][count];
37f4a2713aSLionel Sambuc }
38f4a2713aSLionel Sambuc 
39f4a2713aSLionel Sambuc // rdar://8403108
40f4a2713aSLionel Sambuc // CHECK-LABEL: define void @f_8403108
f_8403108(unsigned x)41f4a2713aSLionel Sambuc void f_8403108(unsigned x) {
42f4a2713aSLionel Sambuc   // CHECK: call i8* @llvm.stacksave()
43f4a2713aSLionel Sambuc   char s1[x];
44f4a2713aSLionel Sambuc   while (1) {
45f4a2713aSLionel Sambuc     // CHECK: call i8* @llvm.stacksave()
46f4a2713aSLionel Sambuc     char s2[x];
47f4a2713aSLionel Sambuc     if (1)
48f4a2713aSLionel Sambuc       break;
49f4a2713aSLionel Sambuc   // CHECK: call void @llvm.stackrestore(i8*
50f4a2713aSLionel Sambuc   }
51f4a2713aSLionel Sambuc   // CHECK: call void @llvm.stackrestore(i8*
52f4a2713aSLionel Sambuc }
53f4a2713aSLionel Sambuc 
54f4a2713aSLionel Sambuc // pr7827
function(short width,int data[][width])55f4a2713aSLionel Sambuc void function(short width, int data[][width]) {} // expected-note {{passing argument to parameter 'data' here}}
56f4a2713aSLionel Sambuc 
test()57f4a2713aSLionel Sambuc void test() {
58f4a2713aSLionel Sambuc      int bork[4][13];
59f4a2713aSLionel Sambuc      // CHECK: call void @function(i16 signext 1, i32* null)
60f4a2713aSLionel Sambuc      function(1, 0);
61f4a2713aSLionel Sambuc      // CHECK: call void @function(i16 signext 1, i32* inttoptr
62f4a2713aSLionel Sambuc      function(1, 0xbadbeef); // expected-warning {{incompatible integer to pointer conversion passing}}
63f4a2713aSLionel Sambuc      // CHECK: call void @function(i16 signext 1, i32* {{.*}})
64f4a2713aSLionel Sambuc      function(1, bork);
65f4a2713aSLionel Sambuc }
66f4a2713aSLionel Sambuc 
function1(short width,int data[][width][width])67f4a2713aSLionel Sambuc void function1(short width, int data[][width][width]) {}
test1()68f4a2713aSLionel Sambuc void test1() {
69f4a2713aSLionel Sambuc      int bork[4][13][15];
70f4a2713aSLionel Sambuc      // CHECK: call void @function1(i16 signext 1, i32* {{.*}})
71f4a2713aSLionel Sambuc      function1(1, bork);
72f4a2713aSLionel Sambuc      // CHECK: call void @function(i16 signext 1, i32* {{.*}})
73f4a2713aSLionel Sambuc      function(1, bork[2]);
74f4a2713aSLionel Sambuc }
75f4a2713aSLionel Sambuc 
76f4a2713aSLionel Sambuc // rdar://8476159
77f4a2713aSLionel Sambuc static int GLOB;
test2(int n)78f4a2713aSLionel Sambuc int test2(int n)
79f4a2713aSLionel Sambuc {
80f4a2713aSLionel Sambuc   GLOB = 0;
81f4a2713aSLionel Sambuc   char b[1][n+3];			/* Variable length array.  */
82f4a2713aSLionel Sambuc   // CHECK:  [[tmp_1:%.*]] = load i32* @GLOB, align 4
83f4a2713aSLionel Sambuc   // CHECK-NEXT: add nsw i32 [[tmp_1]], 1
84f4a2713aSLionel Sambuc   __typeof__(b[GLOB++]) c;
85f4a2713aSLionel Sambuc   return GLOB;
86f4a2713aSLionel Sambuc }
87f4a2713aSLionel Sambuc 
88f4a2713aSLionel Sambuc // http://llvm.org/PR8567
89f4a2713aSLionel Sambuc // CHECK-LABEL: define double @test_PR8567
test_PR8567(int n,double (* p)[n][5])90f4a2713aSLionel Sambuc double test_PR8567(int n, double (*p)[n][5]) {
91f4a2713aSLionel Sambuc   // CHECK:      [[NV:%.*]] = alloca i32, align 4
92f4a2713aSLionel Sambuc   // CHECK-NEXT: [[PV:%.*]] = alloca [5 x double]*, align 4
93f4a2713aSLionel Sambuc   // CHECK-NEXT: store
94f4a2713aSLionel Sambuc   // CHECK-NEXT: store
95f4a2713aSLionel Sambuc   // CHECK-NEXT: [[N:%.*]] = load i32* [[NV]], align 4
96f4a2713aSLionel Sambuc   // CHECK-NEXT: [[P:%.*]] = load [5 x double]** [[PV]], align 4
97f4a2713aSLionel Sambuc   // CHECK-NEXT: [[T0:%.*]] = mul nsw i32 1, [[N]]
98f4a2713aSLionel Sambuc   // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [5 x double]* [[P]], i32 [[T0]]
99f4a2713aSLionel Sambuc   // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [5 x double]* [[T1]], i32 2
100f4a2713aSLionel Sambuc   // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds [5 x double]* [[T2]], i32 0, i32 3
101f4a2713aSLionel Sambuc   // CHECK-NEXT: [[T4:%.*]] = load double* [[T3]]
102f4a2713aSLionel Sambuc   // CHECK-NEXT: ret double [[T4]]
103f4a2713aSLionel Sambuc  return p[1][2][3];
104f4a2713aSLionel Sambuc }
105f4a2713aSLionel Sambuc 
test4(unsigned n,char (* p)[n][n+1][6])106f4a2713aSLionel Sambuc int test4(unsigned n, char (*p)[n][n+1][6]) {
107f4a2713aSLionel Sambuc   // CHECK-LABEL:    define i32 @test4(
108f4a2713aSLionel Sambuc   // CHECK:      [[N:%.*]] = alloca i32, align 4
109f4a2713aSLionel Sambuc   // CHECK-NEXT: [[P:%.*]] = alloca [6 x i8]*, align 4
110f4a2713aSLionel Sambuc   // CHECK-NEXT: [[P2:%.*]] = alloca [6 x i8]*, align 4
111f4a2713aSLionel Sambuc   // CHECK-NEXT: store i32
112f4a2713aSLionel Sambuc   // CHECK-NEXT: store [6 x i8]*
113f4a2713aSLionel Sambuc 
114f4a2713aSLionel Sambuc   // VLA captures.
115f4a2713aSLionel Sambuc   // CHECK-NEXT: [[DIM0:%.*]] = load i32* [[N]], align 4
116f4a2713aSLionel Sambuc   // CHECK-NEXT: [[T0:%.*]] = load i32* [[N]], align 4
117f4a2713aSLionel Sambuc   // CHECK-NEXT: [[DIM1:%.*]] = add i32 [[T0]], 1
118f4a2713aSLionel Sambuc 
119f4a2713aSLionel Sambuc   // CHECK-NEXT: [[T0:%.*]] = load [6 x i8]** [[P]], align 4
120f4a2713aSLionel Sambuc   // CHECK-NEXT: [[T1:%.*]] = load i32* [[N]], align 4
121f4a2713aSLionel Sambuc   // CHECK-NEXT: [[T2:%.*]] = udiv i32 [[T1]], 2
122f4a2713aSLionel Sambuc   // CHECK-NEXT: [[T3:%.*]] = mul nuw i32 [[DIM0]], [[DIM1]]
123f4a2713aSLionel Sambuc   // CHECK-NEXT: [[T4:%.*]] = mul nsw i32 [[T2]], [[T3]]
124f4a2713aSLionel Sambuc   // CHECK-NEXT: [[T5:%.*]] = getelementptr inbounds [6 x i8]* [[T0]], i32 [[T4]]
125f4a2713aSLionel Sambuc   // CHECK-NEXT: [[T6:%.*]] = load i32* [[N]], align 4
126f4a2713aSLionel Sambuc   // CHECK-NEXT: [[T7:%.*]] = udiv i32 [[T6]], 4
127f4a2713aSLionel Sambuc   // CHECK-NEXT: [[T8:%.*]] = sub i32 0, [[T7]]
128f4a2713aSLionel Sambuc   // CHECK-NEXT: [[T9:%.*]] = mul nuw i32 [[DIM0]], [[DIM1]]
129f4a2713aSLionel Sambuc   // CHECK-NEXT: [[T10:%.*]] = mul nsw i32 [[T8]], [[T9]]
130f4a2713aSLionel Sambuc   // CHECK-NEXT: [[T11:%.*]] = getelementptr inbounds [6 x i8]* [[T5]], i32 [[T10]]
131f4a2713aSLionel Sambuc   // CHECK-NEXT: store [6 x i8]* [[T11]], [6 x i8]** [[P2]], align 4
132f4a2713aSLionel Sambuc   __typeof(p) p2 = (p + n/2) - n/4;
133f4a2713aSLionel Sambuc 
134f4a2713aSLionel Sambuc   // CHECK-NEXT: [[T0:%.*]] = load [6 x i8]** [[P2]], align 4
135f4a2713aSLionel Sambuc   // CHECK-NEXT: [[T1:%.*]] = load [6 x i8]** [[P]], align 4
136f4a2713aSLionel Sambuc   // CHECK-NEXT: [[T2:%.*]] = ptrtoint [6 x i8]* [[T0]] to i32
137f4a2713aSLionel Sambuc   // CHECK-NEXT: [[T3:%.*]] = ptrtoint [6 x i8]* [[T1]] to i32
138f4a2713aSLionel Sambuc   // CHECK-NEXT: [[T4:%.*]] = sub i32 [[T2]], [[T3]]
139f4a2713aSLionel Sambuc   // CHECK-NEXT: [[T5:%.*]] = mul nuw i32 [[DIM0]], [[DIM1]]
140f4a2713aSLionel Sambuc   // CHECK-NEXT: [[T6:%.*]] = mul nuw i32 6, [[T5]]
141f4a2713aSLionel Sambuc   // CHECK-NEXT: [[T7:%.*]] = sdiv exact i32 [[T4]], [[T6]]
142f4a2713aSLionel Sambuc   // CHECK-NEXT: ret i32 [[T7]]
143f4a2713aSLionel Sambuc   return p2 - p;
144f4a2713aSLionel Sambuc }
145f4a2713aSLionel Sambuc 
146f4a2713aSLionel Sambuc // rdar://11485774
test5(void)147f4a2713aSLionel Sambuc void test5(void)
148f4a2713aSLionel Sambuc {
149f4a2713aSLionel Sambuc   // CHECK-LABEL: define void @test5(
150f4a2713aSLionel Sambuc   int a[5], i = 0;
151f4a2713aSLionel Sambuc   // CHECK: [[A:%.*]] = alloca [5 x i32], align 4
152f4a2713aSLionel Sambuc   // CHECK-NEXT: [[I:%.*]] = alloca i32, align 4
153f4a2713aSLionel Sambuc   // CHECK-NEXT: [[CL:%.*]] = alloca i32*, align 4
154f4a2713aSLionel Sambuc   // CHECK-NEXT: store i32 0, i32* [[I]], align 4
155f4a2713aSLionel Sambuc 
156f4a2713aSLionel Sambuc   (typeof(++i, (int (*)[i])a)){&a} += 0;
157f4a2713aSLionel Sambuc   // CHECK-NEXT: [[Z:%.*]] = load i32* [[I]], align 4
158f4a2713aSLionel Sambuc   // CHECK-NEXT: [[INC:%.*]]  = add nsw i32 [[Z]], 1
159f4a2713aSLionel Sambuc   // CHECK-NEXT: store i32 [[INC]], i32* [[I]], align 4
160f4a2713aSLionel Sambuc   // CHECK-NEXT: [[O:%.*]] = load i32* [[I]], align 4
161f4a2713aSLionel Sambuc   // CHECK-NEXT: [[AR:%.*]] = getelementptr inbounds [5 x i32]* [[A]], i32 0, i32 0
162f4a2713aSLionel Sambuc   // CHECK-NEXT: [[T:%.*]] = bitcast [5 x i32]* [[A]] to i32*
163f4a2713aSLionel Sambuc   // CHECK-NEXT: store i32* [[T]], i32** [[CL]]
164f4a2713aSLionel Sambuc   // CHECK-NEXT: [[TH:%.*]] = load i32** [[CL]]
165f4a2713aSLionel Sambuc   // CHECK-NEXT: [[VLAIX:%.*]] = mul nsw i32 0, [[O]]
166f4a2713aSLionel Sambuc   // CHECK-NEXT: [[ADDPTR:%.*]] = getelementptr inbounds i32* [[TH]], i32 [[VLAIX]]
167f4a2713aSLionel Sambuc   // CHECK-NEXT: store i32* [[ADDPTR]], i32** [[CL]]
168f4a2713aSLionel Sambuc }
169f4a2713aSLionel Sambuc 
test6(void)170f4a2713aSLionel Sambuc void test6(void)
171f4a2713aSLionel Sambuc {
172f4a2713aSLionel Sambuc   // CHECK-LABEL: define void @test6(
173f4a2713aSLionel Sambuc   int n = 20, **a, i=0;
174f4a2713aSLionel Sambuc   // CHECK: [[N:%.*]] = alloca i32, align 4
175f4a2713aSLionel Sambuc   // CHECK-NEXT: [[A:%.*]] = alloca i32**, align 4
176f4a2713aSLionel Sambuc   // CHECK-NEXT: [[I:%.*]] = alloca i32, align 4
177f4a2713aSLionel Sambuc  (int (**)[i]){&a}[0][1][5] = 0;
178f4a2713aSLionel Sambuc   // CHECK-NEXT: [[CL:%.*]] = alloca i32**, align 4
179f4a2713aSLionel Sambuc   // CHECK-NEXT: store i32 20, i32* [[N]], align 4
180f4a2713aSLionel Sambuc   // CHECK-NEXT: store i32 0, i32* [[I]], align 4
181f4a2713aSLionel Sambuc   // CHECK-NEXT: [[Z:%.*]] = load i32* [[I]], align 4
182f4a2713aSLionel Sambuc   // CHECK-NEXT: [[O:%.*]] = bitcast i32*** [[A]] to i32**
183f4a2713aSLionel Sambuc   // CHECK-NEXT: store i32** [[O]], i32*** [[CL]]
184f4a2713aSLionel Sambuc   // CHECK-NEXT: [[T:%.*]] = load i32*** [[CL]]
185f4a2713aSLionel Sambuc   // CHECK-NEXT: [[IX:%.*]] = getelementptr inbounds i32** [[T]], i32 0
186f4a2713aSLionel Sambuc   // CHECK-NEXT: [[TH:%.*]] = load i32** [[IX]], align 4
187f4a2713aSLionel Sambuc   // CHECK-NEXT: [[F:%.*]] = mul nsw i32 1, [[Z]]
188f4a2713aSLionel Sambuc   // CHECK-NEXT: [[IX1:%.*]] = getelementptr inbounds i32* [[TH]], i32 [[F]]
189f4a2713aSLionel Sambuc   // CHECK-NEXT: [[IX2:%.*]] = getelementptr inbounds i32* [[IX1]], i32 5
190f4a2713aSLionel Sambuc   // CHECK-NEXT: store i32 0, i32* [[IX2]], align 4
191f4a2713aSLionel Sambuc }
192f4a2713aSLionel Sambuc 
193f4a2713aSLionel Sambuc // Follow gcc's behavior for VLAs in parameter lists.  PR9559.
test7(int a[b (0)])194f4a2713aSLionel Sambuc void test7(int a[b(0)]) {
195f4a2713aSLionel Sambuc   // CHECK-LABEL: define void @test7(
196f4a2713aSLionel Sambuc   // CHECK: call i32 @b(i8* null)
197f4a2713aSLionel Sambuc }
198*0a6a1f1dSLionel Sambuc 
199*0a6a1f1dSLionel Sambuc // Make sure we emit dereferenceable or nonnull when the static keyword is
200*0a6a1f1dSLionel Sambuc // provided.
test8(int a[static3])201*0a6a1f1dSLionel Sambuc void test8(int a[static 3]) { }
202*0a6a1f1dSLionel Sambuc // CHECK: define void @test8(i32* dereferenceable(12) %a)
203*0a6a1f1dSLionel Sambuc 
test9(int n,int a[static n])204*0a6a1f1dSLionel Sambuc void test9(int n, int a[static n]) { }
205*0a6a1f1dSLionel Sambuc // CHECK: define void @test9(i32 %n, i32* nonnull %a)
206*0a6a1f1dSLionel Sambuc 
207