More tests to global struct vectorizer
[oota-llvm.git] / test / Transforms / LoopVectorize / global_alias.ll
1 ; RUN: opt < %s -O3 -loop-vectorize -force-vector-unroll=1 -force-vector-width=4 -dce -instcombine -S | FileCheck %s
2
3 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:128-a0:0:64-n32-S64"
4
5 %struct.anon = type { [100 x i32], i32, [100 x i32] }
6
7 @Foo = common global %struct.anon zeroinitializer, align 4
8 @PB = external global i32*
9 @PA = external global i32*
10
11 ; int noAlias01 (int a) {
12 ;   int i;
13 ;   for (i=0; i<SIZE; i++)
14 ;     Foo.A[i] = Foo.B[i] + a;
15 ;   return Foo.A[a];
16 ; }
17 ; CHECK: define i32 @noAlias01
18 ; CHECK: add nsw <4 x i32>
19 ; CHECK ret
20
21 define i32 @noAlias01(i32 %a) nounwind {
22 entry:
23   %a.addr = alloca i32, align 4
24   %i = alloca i32, align 4
25   store i32 %a, i32* %a.addr, align 4
26   store i32 0, i32* %i, align 4
27   br label %for.cond
28
29 for.cond:                                         ; preds = %for.inc, %entry
30   %0 = load i32* %i, align 4
31   %cmp = icmp slt i32 %0, 100
32   br i1 %cmp, label %for.body, label %for.end
33
34 for.body:                                         ; preds = %for.cond
35   %1 = load i32* %i, align 4
36   %arrayidx = getelementptr inbounds [100 x i32]* getelementptr inbounds (%struct.anon* @Foo, i32 0, i32 2), i32 0, i32 %1
37   %2 = load i32* %arrayidx, align 4
38   %3 = load i32* %a.addr, align 4
39   %add = add nsw i32 %2, %3
40   %4 = load i32* %i, align 4
41   %arrayidx1 = getelementptr inbounds [100 x i32]* getelementptr inbounds (%struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %4
42   store i32 %add, i32* %arrayidx1, align 4
43   br label %for.inc
44
45 for.inc:                                          ; preds = %for.body
46   %5 = load i32* %i, align 4
47   %inc = add nsw i32 %5, 1
48   store i32 %inc, i32* %i, align 4
49   br label %for.cond
50
51 for.end:                                          ; preds = %for.cond
52   %6 = load i32* %a.addr, align 4
53   %arrayidx2 = getelementptr inbounds [100 x i32]* getelementptr inbounds (%struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %6
54   %7 = load i32* %arrayidx2, align 4
55   ret i32 %7
56 }
57
58 ; int noAlias02 (int a) {
59 ;   int i;
60 ;   for (i=0; i<SIZE-10; i++)
61 ;     Foo.A[i] = Foo.B[i+10] + a;
62 ;   return Foo.A[a];
63 ; }
64 ; CHECK: define i32 @noAlias02
65 ; CHECK: add nsw <4 x i32>
66 ; CHECK ret
67
68 define i32 @noAlias02(i32 %a) {
69 entry:
70   %a.addr = alloca i32, align 4
71   %i = alloca i32, align 4
72   store i32 %a, i32* %a.addr, align 4
73   store i32 0, i32* %i, align 4
74   br label %for.cond
75
76 for.cond:                                         ; preds = %for.inc, %entry
77   %0 = load i32* %i, align 4
78   %cmp = icmp slt i32 %0, 90
79   br i1 %cmp, label %for.body, label %for.end
80
81 for.body:                                         ; preds = %for.cond
82   %1 = load i32* %i, align 4
83   %add = add nsw i32 %1, 10
84   %arrayidx = getelementptr inbounds [100 x i32]* getelementptr inbounds (%struct.anon* @Foo, i32 0, i32 2), i32 0, i32 %add
85   %2 = load i32* %arrayidx, align 4
86   %3 = load i32* %a.addr, align 4
87   %add1 = add nsw i32 %2, %3
88   %4 = load i32* %i, align 4
89   %arrayidx2 = getelementptr inbounds [100 x i32]* getelementptr inbounds (%struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %4
90   store i32 %add1, i32* %arrayidx2, align 4
91   br label %for.inc
92
93 for.inc:                                          ; preds = %for.body
94   %5 = load i32* %i, align 4
95   %inc = add nsw i32 %5, 1
96   store i32 %inc, i32* %i, align 4
97   br label %for.cond
98
99 for.end:                                          ; preds = %for.cond
100   %6 = load i32* %a.addr, align 4
101   %arrayidx3 = getelementptr inbounds [100 x i32]* getelementptr inbounds (%struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %6
102   %7 = load i32* %arrayidx3, align 4
103   ret i32 %7
104 }
105
106 ; int noAlias03 (int a) {
107 ;   int i;
108 ;   for (i=0; i<SIZE; i++)
109 ;     Foo.A[i+10] = Foo.B[i] + a;
110 ;   return Foo.A[a];
111 ; }
112 ; CHECK: define i32 @noAlias03
113 ; CHECK: add nsw <4 x i32>
114 ; CHECK ret
115
116 define i32 @noAlias03(i32 %a) {
117 entry:
118   %a.addr = alloca i32, align 4
119   %i = alloca i32, align 4
120   store i32 %a, i32* %a.addr, align 4
121   store i32 0, i32* %i, align 4
122   br label %for.cond
123
124 for.cond:                                         ; preds = %for.inc, %entry
125   %0 = load i32* %i, align 4
126   %cmp = icmp slt i32 %0, 100
127   br i1 %cmp, label %for.body, label %for.end
128
129 for.body:                                         ; preds = %for.cond
130   %1 = load i32* %i, align 4
131   %arrayidx = getelementptr inbounds [100 x i32]* getelementptr inbounds (%struct.anon* @Foo, i32 0, i32 2), i32 0, i32 %1
132   %2 = load i32* %arrayidx, align 4
133   %3 = load i32* %a.addr, align 4
134   %add = add nsw i32 %2, %3
135   %4 = load i32* %i, align 4
136   %add1 = add nsw i32 %4, 10
137   %arrayidx2 = getelementptr inbounds [100 x i32]* getelementptr inbounds (%struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %add1
138   store i32 %add, i32* %arrayidx2, align 4
139   br label %for.inc
140
141 for.inc:                                          ; preds = %for.body
142   %5 = load i32* %i, align 4
143   %inc = add nsw i32 %5, 1
144   store i32 %inc, i32* %i, align 4
145   br label %for.cond
146
147 for.end:                                          ; preds = %for.cond
148   %6 = load i32* %a.addr, align 4
149   %arrayidx3 = getelementptr inbounds [100 x i32]* getelementptr inbounds (%struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %6
150   %7 = load i32* %arrayidx3, align 4
151   ret i32 %7
152 }
153
154 ; int mayAlias01 (int a) {
155 ;   int i;
156 ;   for (i=0; i<SIZE; i++)
157 ;     Foo.A[i] = Foo.B[SIZE-i-1] + a;
158 ;   return Foo.A[a];
159 ; }
160 ; CHECK: define i32 @mayAlias01
161 ; CHECK-NOT: add nsw <4 x i32>
162 ; CHECK ret
163
164 define i32 @mayAlias01(i32 %a) nounwind {
165 entry:
166   %a.addr = alloca i32, align 4
167   %i = alloca i32, align 4
168   store i32 %a, i32* %a.addr, align 4
169   store i32 0, i32* %i, align 4
170   br label %for.cond
171
172 for.cond:                                         ; preds = %for.inc, %entry
173   %0 = load i32* %i, align 4
174   %cmp = icmp slt i32 %0, 100
175   br i1 %cmp, label %for.body, label %for.end
176
177 for.body:                                         ; preds = %for.cond
178   %1 = load i32* %i, align 4
179   %sub = sub nsw i32 100, %1
180   %sub1 = sub nsw i32 %sub, 1
181   %arrayidx = getelementptr inbounds [100 x i32]* getelementptr inbounds (%struct.anon* @Foo, i32 0, i32 2), i32 0, i32 %sub1
182   %2 = load i32* %arrayidx, align 4
183   %3 = load i32* %a.addr, align 4
184   %add = add nsw i32 %2, %3
185   %4 = load i32* %i, align 4
186   %arrayidx2 = getelementptr inbounds [100 x i32]* getelementptr inbounds (%struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %4
187   store i32 %add, i32* %arrayidx2, align 4
188   br label %for.inc
189
190 for.inc:                                          ; preds = %for.body
191   %5 = load i32* %i, align 4
192   %inc = add nsw i32 %5, 1
193   store i32 %inc, i32* %i, align 4
194   br label %for.cond
195
196 for.end:                                          ; preds = %for.cond
197   %6 = load i32* %a.addr, align 4
198   %arrayidx3 = getelementptr inbounds [100 x i32]* getelementptr inbounds (%struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %6
199   %7 = load i32* %arrayidx3, align 4
200   ret i32 %7
201 }
202
203 ; int mayAlias04 (int a) {
204 ;   int i;
205 ;   for (i=0; i<SIZE; i++)
206 ;     *(PA+i) = *(PB+i) + a;
207 ;   return Foo.A[a];
208 ; }
209 ; CHECK: define i32 @mayAlias04
210 ; CHECK-NOT: add nsw <4 x i32>
211 ; CHECK ret
212
213 define i32 @mayAlias04(i32 %a) {
214 entry:
215   %a.addr = alloca i32, align 4
216   %i = alloca i32, align 4
217   store i32 %a, i32* %a.addr, align 4
218   store i32 0, i32* %i, align 4
219   br label %for.cond
220
221 for.cond:                                         ; preds = %for.inc, %entry
222   %0 = load i32* %i, align 4
223   %cmp = icmp slt i32 %0, 100
224   br i1 %cmp, label %for.body, label %for.end
225
226 for.body:                                         ; preds = %for.cond
227   %1 = load i32** @PB, align 4
228   %2 = load i32* %i, align 4
229   %add.ptr = getelementptr inbounds i32* %1, i32 %2
230   %3 = load i32* %add.ptr, align 4
231   %4 = load i32* %a.addr, align 4
232   %add = add nsw i32 %3, %4
233   %5 = load i32** @PA, align 4
234   %6 = load i32* %i, align 4
235   %add.ptr1 = getelementptr inbounds i32* %5, i32 %6
236   store i32 %add, i32* %add.ptr1, align 4
237   br label %for.inc
238
239 for.inc:                                          ; preds = %for.body
240   %7 = load i32* %i, align 4
241   %inc = add nsw i32 %7, 1
242   store i32 %inc, i32* %i, align 4
243   br label %for.cond
244
245 for.end:                                          ; preds = %for.cond
246   %8 = load i32** @PA, align 4
247   %9 = load i32* %a.addr, align 4
248   %add.ptr2 = getelementptr inbounds i32* %8, i32 %9
249   %10 = load i32* %add.ptr2, align 4
250   ret i32 %10
251 }
252
253 ; int mayAlias02 (int a) {
254 ;   int i;
255 ;   for (i=0; i<SIZE; i++)
256 ;     Foo.A[SIZE-i-1] = Foo.B[i] + a;
257 ;   return Foo.A[a];
258 ; }
259 ; CHECK: define i32 @mayAlias02
260 ; CHECK-NOT: add nsw <4 x i32>
261 ; CHECK ret
262
263 define i32 @mayAlias02(i32 %a) nounwind {
264 entry:
265   %a.addr = alloca i32, align 4
266   %i = alloca i32, align 4
267   store i32 %a, i32* %a.addr, align 4
268   store i32 0, i32* %i, align 4
269   br label %for.cond
270
271 for.cond:                                         ; preds = %for.inc, %entry
272   %0 = load i32* %i, align 4
273   %cmp = icmp slt i32 %0, 100
274   br i1 %cmp, label %for.body, label %for.end
275
276 for.body:                                         ; preds = %for.cond
277   %1 = load i32* %i, align 4
278   %arrayidx = getelementptr inbounds [100 x i32]* getelementptr inbounds (%struct.anon* @Foo, i32 0, i32 2), i32 0, i32 %1
279   %2 = load i32* %arrayidx, align 4
280   %3 = load i32* %a.addr, align 4
281   %add = add nsw i32 %2, %3
282   %4 = load i32* %i, align 4
283   %sub = sub nsw i32 100, %4
284   %sub1 = sub nsw i32 %sub, 1
285   %arrayidx2 = getelementptr inbounds [100 x i32]* getelementptr inbounds (%struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %sub1
286   store i32 %add, i32* %arrayidx2, align 4
287   br label %for.inc
288
289 for.inc:                                          ; preds = %for.body
290   %5 = load i32* %i, align 4
291   %inc = add nsw i32 %5, 1
292   store i32 %inc, i32* %i, align 4
293   br label %for.cond
294
295 for.end:                                          ; preds = %for.cond
296   %6 = load i32* %a.addr, align 4
297   %arrayidx3 = getelementptr inbounds [100 x i32]* getelementptr inbounds (%struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %6
298   %7 = load i32* %arrayidx3, align 4
299   ret i32 %7
300 }
301
302 ; int mayAlias03 (int a) {
303 ;   int i;
304 ;   for (i=0; i<SIZE; i++)
305 ;     *(PA+i) = *(PB+SIZE-i-1) + a;
306 ;   return *(PA+a);
307 ; }
308 ; CHECK: define i32 @mayAlias03
309 ; CHECK-NOT: add nsw <4 x i32>
310 ; CHECK ret
311
312 define i32 @mayAlias03(i32 %a) nounwind {
313 entry:
314   %a.addr = alloca i32, align 4
315   %i = alloca i32, align 4
316   store i32 %a, i32* %a.addr, align 4
317   store i32 0, i32* %i, align 4
318   br label %for.cond
319
320 for.cond:                                         ; preds = %for.inc, %entry
321   %0 = load i32* %i, align 4
322   %cmp = icmp slt i32 %0, 100
323   br i1 %cmp, label %for.body, label %for.end
324
325 for.body:                                         ; preds = %for.cond
326   %1 = load i32** @PB, align 4
327   %add.ptr = getelementptr inbounds i32* %1, i32 100
328   %2 = load i32* %i, align 4
329   %idx.neg = sub i32 0, %2
330   %add.ptr1 = getelementptr inbounds i32* %add.ptr, i32 %idx.neg
331   %add.ptr2 = getelementptr inbounds i32* %add.ptr1, i32 -1
332   %3 = load i32* %add.ptr2, align 4
333   %4 = load i32* %a.addr, align 4
334   %add = add nsw i32 %3, %4
335   %5 = load i32** @PA, align 4
336   %6 = load i32* %i, align 4
337   %add.ptr3 = getelementptr inbounds i32* %5, i32 %6
338   store i32 %add, i32* %add.ptr3, align 4
339   br label %for.inc
340
341 for.inc:                                          ; preds = %for.body
342   %7 = load i32* %i, align 4
343   %inc = add nsw i32 %7, 1
344   store i32 %inc, i32* %i, align 4
345   br label %for.cond
346
347 for.end:                                          ; preds = %for.cond
348   %8 = load i32** @PA, align 4
349   %9 = load i32* %a.addr, align 4
350   %add.ptr4 = getelementptr inbounds i32* %8, i32 %9
351   %10 = load i32* %add.ptr4, align 4
352   ret i32 %10
353 }
354
355 ; int mustAlias01 (int a) {
356 ;   int i;
357 ;   for (i=0; i<SIZE; i++)
358 ;     Foo.A[i+10] = Foo.B[SIZE-i-1] + a;
359 ;   return Foo.A[a];
360 ; }
361 ; CHECK: define i32 @mustAlias01
362 ; CHECK-NOT: add nsw <4 x i32>
363 ; CHECK ret
364
365 define i32 @mustAlias01(i32 %a) nounwind {
366 entry:
367   %a.addr = alloca i32, align 4
368   %i = alloca i32, align 4
369   store i32 %a, i32* %a.addr, align 4
370   store i32 0, i32* %i, align 4
371   br label %for.cond
372
373 for.cond:                                         ; preds = %for.inc, %entry
374   %0 = load i32* %i, align 4
375   %cmp = icmp slt i32 %0, 100
376   br i1 %cmp, label %for.body, label %for.end
377
378 for.body:                                         ; preds = %for.cond
379   %1 = load i32* %i, align 4
380   %sub = sub nsw i32 100, %1
381   %sub1 = sub nsw i32 %sub, 1
382   %arrayidx = getelementptr inbounds [100 x i32]* getelementptr inbounds (%struct.anon* @Foo, i32 0, i32 2), i32 0, i32 %sub1
383   %2 = load i32* %arrayidx, align 4
384   %3 = load i32* %a.addr, align 4
385   %add = add nsw i32 %2, %3
386   %4 = load i32* %i, align 4
387   %add2 = add nsw i32 %4, 10
388   %arrayidx3 = getelementptr inbounds [100 x i32]* getelementptr inbounds (%struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %add2
389   store i32 %add, i32* %arrayidx3, align 4
390   br label %for.inc
391
392 for.inc:                                          ; preds = %for.body
393   %5 = load i32* %i, align 4
394   %inc = add nsw i32 %5, 1
395   store i32 %inc, i32* %i, align 4
396   br label %for.cond
397
398 for.end:                                          ; preds = %for.cond
399   %6 = load i32* %a.addr, align 4
400   %arrayidx4 = getelementptr inbounds [100 x i32]* getelementptr inbounds (%struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %6
401   %7 = load i32* %arrayidx4, align 4
402   ret i32 %7
403 }
404
405 ; int mustAlias02 (int a) {
406 ;   int i;
407 ;   for (i=0; i<SIZE; i++)
408 ;     Foo.A[i] = Foo.B[SIZE-i-10] + a;
409 ;   return Foo.A[a];
410 ; }
411 ; CHECK: define i32 @mustAlias02
412 ; CHECK-NOT: add nsw <4 x i32>
413 ; CHECK ret
414
415 define i32 @mustAlias02(i32 %a) nounwind {
416 entry:
417   %a.addr = alloca i32, align 4
418   %i = alloca i32, align 4
419   store i32 %a, i32* %a.addr, align 4
420   store i32 0, i32* %i, align 4
421   br label %for.cond
422
423 for.cond:                                         ; preds = %for.inc, %entry
424   %0 = load i32* %i, align 4
425   %cmp = icmp slt i32 %0, 100
426   br i1 %cmp, label %for.body, label %for.end
427
428 for.body:                                         ; preds = %for.cond
429   %1 = load i32* %i, align 4
430   %sub = sub nsw i32 100, %1
431   %sub1 = sub nsw i32 %sub, 10
432   %arrayidx = getelementptr inbounds [100 x i32]* getelementptr inbounds (%struct.anon* @Foo, i32 0, i32 2), i32 0, i32 %sub1
433   %2 = load i32* %arrayidx, align 4
434   %3 = load i32* %a.addr, align 4
435   %add = add nsw i32 %2, %3
436   %4 = load i32* %i, align 4
437   %arrayidx2 = getelementptr inbounds [100 x i32]* getelementptr inbounds (%struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %4
438   store i32 %add, i32* %arrayidx2, align 4
439   br label %for.inc
440
441 for.inc:                                          ; preds = %for.body
442   %5 = load i32* %i, align 4
443   %inc = add nsw i32 %5, 1
444   store i32 %inc, i32* %i, align 4
445   br label %for.cond
446
447 for.end:                                          ; preds = %for.cond
448   %6 = load i32* %a.addr, align 4
449   %arrayidx3 = getelementptr inbounds [100 x i32]* getelementptr inbounds (%struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %6
450   %7 = load i32* %arrayidx3, align 4
451   ret i32 %7
452 }
453
454 ; int mustAlias03 (int a) {
455 ;   int i;
456 ;   for (i=0; i<SIZE; i++)
457 ;     Foo.A[i+10] = Foo.B[SIZE-i-10] + a;
458 ;   return Foo.A[a];
459 ; }
460 ; CHECK: define i32 @mustAlias03
461 ; CHECK-NOT: add nsw <4 x i32>
462 ; CHECK ret
463
464 define i32 @mustAlias03(i32 %a) nounwind {
465 entry:
466   %a.addr = alloca i32, align 4
467   %i = alloca i32, align 4
468   store i32 %a, i32* %a.addr, align 4
469   store i32 0, i32* %i, align 4
470   br label %for.cond
471
472 for.cond:                                         ; preds = %for.inc, %entry
473   %0 = load i32* %i, align 4
474   %cmp = icmp slt i32 %0, 100
475   br i1 %cmp, label %for.body, label %for.end
476
477 for.body:                                         ; preds = %for.cond
478   %1 = load i32* %i, align 4
479   %sub = sub nsw i32 100, %1
480   %sub1 = sub nsw i32 %sub, 10
481   %arrayidx = getelementptr inbounds [100 x i32]* getelementptr inbounds (%struct.anon* @Foo, i32 0, i32 2), i32 0, i32 %sub1
482   %2 = load i32* %arrayidx, align 4
483   %3 = load i32* %a.addr, align 4
484   %add = add nsw i32 %2, %3
485   %4 = load i32* %i, align 4
486   %add2 = add nsw i32 %4, 10
487   %arrayidx3 = getelementptr inbounds [100 x i32]* getelementptr inbounds (%struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %add2
488   store i32 %add, i32* %arrayidx3, align 4
489   br label %for.inc
490
491 for.inc:                                          ; preds = %for.body
492   %5 = load i32* %i, align 4
493   %inc = add nsw i32 %5, 1
494   store i32 %inc, i32* %i, align 4
495   br label %for.cond
496
497 for.end:                                          ; preds = %for.cond
498   %6 = load i32* %a.addr, align 4
499   %arrayidx4 = getelementptr inbounds [100 x i32]* getelementptr inbounds (%struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %6
500   %7 = load i32* %arrayidx4, align 4
501   ret i32 %7
502 }