Allow GlobalValues to vectorize with AliasAnalysis
[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 mayAlias01 (int a) {
59 ;   int i;
60 ;   for (i=0; i<SIZE; i++)
61 ;     Foo.A[i] = Foo.B[SIZE-i-1] + a;
62 ;   return Foo.A[a];
63 ; }
64 ; CHECK: define i32 @mayAlias01
65 ; CHECK-NOT: add nsw <4 x i32>
66 ; CHECK ret
67
68 define i32 @mayAlias01(i32 %a) nounwind {
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, 100
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   %sub = sub nsw i32 100, %1
84   %sub1 = sub nsw i32 %sub, 1
85   %arrayidx = getelementptr inbounds [100 x i32]* getelementptr inbounds (%struct.anon* @Foo, i32 0, i32 2), i32 0, i32 %sub1
86   %2 = load i32* %arrayidx, align 4
87   %3 = load i32* %a.addr, align 4
88   %add = add nsw i32 %2, %3
89   %4 = load i32* %i, align 4
90   %arrayidx2 = getelementptr inbounds [100 x i32]* getelementptr inbounds (%struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %4
91   store i32 %add, i32* %arrayidx2, align 4
92   br label %for.inc
93
94 for.inc:                                          ; preds = %for.body
95   %5 = load i32* %i, align 4
96   %inc = add nsw i32 %5, 1
97   store i32 %inc, i32* %i, align 4
98   br label %for.cond
99
100 for.end:                                          ; preds = %for.cond
101   %6 = load i32* %a.addr, align 4
102   %arrayidx3 = getelementptr inbounds [100 x i32]* getelementptr inbounds (%struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %6
103   %7 = load i32* %arrayidx3, align 4
104   ret i32 %7
105 }
106
107 ; int mayAlias02 (int a) {
108 ;   int i;
109 ;   for (i=0; i<SIZE; i++)
110 ;     Foo.A[SIZE-i-1] = Foo.B[i] + a;
111 ;   return Foo.A[a];
112 ; }
113 ; CHECK: define i32 @mayAlias02
114 ; CHECK-NOT: add nsw <4 x i32>
115 ; CHECK ret
116
117 define i32 @mayAlias02(i32 %a) nounwind {
118 entry:
119   %a.addr = alloca i32, align 4
120   %i = alloca i32, align 4
121   store i32 %a, i32* %a.addr, align 4
122   store i32 0, i32* %i, align 4
123   br label %for.cond
124
125 for.cond:                                         ; preds = %for.inc, %entry
126   %0 = load i32* %i, align 4
127   %cmp = icmp slt i32 %0, 100
128   br i1 %cmp, label %for.body, label %for.end
129
130 for.body:                                         ; preds = %for.cond
131   %1 = load i32* %i, align 4
132   %arrayidx = getelementptr inbounds [100 x i32]* getelementptr inbounds (%struct.anon* @Foo, i32 0, i32 2), i32 0, i32 %1
133   %2 = load i32* %arrayidx, align 4
134   %3 = load i32* %a.addr, align 4
135   %add = add nsw i32 %2, %3
136   %4 = load i32* %i, align 4
137   %sub = sub nsw i32 100, %4
138   %sub1 = sub nsw i32 %sub, 1
139   %arrayidx2 = getelementptr inbounds [100 x i32]* getelementptr inbounds (%struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %sub1
140   store i32 %add, i32* %arrayidx2, align 4
141   br label %for.inc
142
143 for.inc:                                          ; preds = %for.body
144   %5 = load i32* %i, align 4
145   %inc = add nsw i32 %5, 1
146   store i32 %inc, i32* %i, align 4
147   br label %for.cond
148
149 for.end:                                          ; preds = %for.cond
150   %6 = load i32* %a.addr, align 4
151   %arrayidx3 = getelementptr inbounds [100 x i32]* getelementptr inbounds (%struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %6
152   %7 = load i32* %arrayidx3, align 4
153   ret i32 %7
154 }
155
156 ; int mayAlias03 (int a) {
157 ;   int i;
158 ;   for (i=0; i<SIZE; i++)
159 ;     *(PA+i) = *(PB+SIZE-i-1) + a;
160 ;   return *(PA+a);
161 ; }
162 ; CHECK: define i32 @mayAlias03
163 ; CHECK-NOT: add nsw <4 x i32>
164 ; CHECK ret
165
166 define i32 @mayAlias03(i32 %a) nounwind {
167 entry:
168   %a.addr = alloca i32, align 4
169   %i = alloca i32, align 4
170   store i32 %a, i32* %a.addr, align 4
171   store i32 0, i32* %i, align 4
172   br label %for.cond
173
174 for.cond:                                         ; preds = %for.inc, %entry
175   %0 = load i32* %i, align 4
176   %cmp = icmp slt i32 %0, 100
177   br i1 %cmp, label %for.body, label %for.end
178
179 for.body:                                         ; preds = %for.cond
180   %1 = load i32** @PB, align 4
181   %add.ptr = getelementptr inbounds i32* %1, i32 100
182   %2 = load i32* %i, align 4
183   %idx.neg = sub i32 0, %2
184   %add.ptr1 = getelementptr inbounds i32* %add.ptr, i32 %idx.neg
185   %add.ptr2 = getelementptr inbounds i32* %add.ptr1, i32 -1
186   %3 = load i32* %add.ptr2, align 4
187   %4 = load i32* %a.addr, align 4
188   %add = add nsw i32 %3, %4
189   %5 = load i32** @PA, align 4
190   %6 = load i32* %i, align 4
191   %add.ptr3 = getelementptr inbounds i32* %5, i32 %6
192   store i32 %add, i32* %add.ptr3, align 4
193   br label %for.inc
194
195 for.inc:                                          ; preds = %for.body
196   %7 = load i32* %i, align 4
197   %inc = add nsw i32 %7, 1
198   store i32 %inc, i32* %i, align 4
199   br label %for.cond
200
201 for.end:                                          ; preds = %for.cond
202   %8 = load i32** @PA, align 4
203   %9 = load i32* %a.addr, align 4
204   %add.ptr4 = getelementptr inbounds i32* %8, i32 %9
205   %10 = load i32* %add.ptr4, align 4
206   ret i32 %10
207 }
208
209 ; int mustAlias01 (int a) {
210 ;   int i;
211 ;   for (i=0; i<SIZE; i++)
212 ;     Foo.A[i+10] = Foo.B[SIZE-i-1] + a;
213 ;   return Foo.A[a];
214 ; }
215 ; CHECK: define i32 @mustAlias01
216 ; CHECK-NOT: add nsw <4 x i32>
217 ; CHECK ret
218
219 define i32 @mustAlias01(i32 %a) nounwind {
220 entry:
221   %a.addr = alloca i32, align 4
222   %i = alloca i32, align 4
223   store i32 %a, i32* %a.addr, align 4
224   store i32 0, i32* %i, align 4
225   br label %for.cond
226
227 for.cond:                                         ; preds = %for.inc, %entry
228   %0 = load i32* %i, align 4
229   %cmp = icmp slt i32 %0, 100
230   br i1 %cmp, label %for.body, label %for.end
231
232 for.body:                                         ; preds = %for.cond
233   %1 = load i32* %i, align 4
234   %sub = sub nsw i32 100, %1
235   %sub1 = sub nsw i32 %sub, 1
236   %arrayidx = getelementptr inbounds [100 x i32]* getelementptr inbounds (%struct.anon* @Foo, i32 0, i32 2), i32 0, i32 %sub1
237   %2 = load i32* %arrayidx, align 4
238   %3 = load i32* %a.addr, align 4
239   %add = add nsw i32 %2, %3
240   %4 = load i32* %i, align 4
241   %add2 = add nsw i32 %4, 10
242   %arrayidx3 = getelementptr inbounds [100 x i32]* getelementptr inbounds (%struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %add2
243   store i32 %add, i32* %arrayidx3, align 4
244   br label %for.inc
245
246 for.inc:                                          ; preds = %for.body
247   %5 = load i32* %i, align 4
248   %inc = add nsw i32 %5, 1
249   store i32 %inc, i32* %i, align 4
250   br label %for.cond
251
252 for.end:                                          ; preds = %for.cond
253   %6 = load i32* %a.addr, align 4
254   %arrayidx4 = getelementptr inbounds [100 x i32]* getelementptr inbounds (%struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %6
255   %7 = load i32* %arrayidx4, align 4
256   ret i32 %7
257 }
258
259 ; int mustAlias02 (int a) {
260 ;   int i;
261 ;   for (i=0; i<SIZE; i++)
262 ;     Foo.A[i] = Foo.B[SIZE-i-10] + a;
263 ;   return Foo.A[a];
264 ; }
265 ; CHECK: define i32 @mustAlias02
266 ; CHECK-NOT: add nsw <4 x i32>
267 ; CHECK ret
268
269 define i32 @mustAlias02(i32 %a) nounwind {
270 entry:
271   %a.addr = alloca i32, align 4
272   %i = alloca i32, align 4
273   store i32 %a, i32* %a.addr, align 4
274   store i32 0, i32* %i, align 4
275   br label %for.cond
276
277 for.cond:                                         ; preds = %for.inc, %entry
278   %0 = load i32* %i, align 4
279   %cmp = icmp slt i32 %0, 100
280   br i1 %cmp, label %for.body, label %for.end
281
282 for.body:                                         ; preds = %for.cond
283   %1 = load i32* %i, align 4
284   %sub = sub nsw i32 100, %1
285   %sub1 = sub nsw i32 %sub, 10
286   %arrayidx = getelementptr inbounds [100 x i32]* getelementptr inbounds (%struct.anon* @Foo, i32 0, i32 2), i32 0, i32 %sub1
287   %2 = load i32* %arrayidx, align 4
288   %3 = load i32* %a.addr, align 4
289   %add = add nsw i32 %2, %3
290   %4 = load i32* %i, align 4
291   %arrayidx2 = getelementptr inbounds [100 x i32]* getelementptr inbounds (%struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %4
292   store i32 %add, i32* %arrayidx2, align 4
293   br label %for.inc
294
295 for.inc:                                          ; preds = %for.body
296   %5 = load i32* %i, align 4
297   %inc = add nsw i32 %5, 1
298   store i32 %inc, i32* %i, align 4
299   br label %for.cond
300
301 for.end:                                          ; preds = %for.cond
302   %6 = load i32* %a.addr, align 4
303   %arrayidx3 = getelementptr inbounds [100 x i32]* getelementptr inbounds (%struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %6
304   %7 = load i32* %arrayidx3, align 4
305   ret i32 %7
306 }
307
308 ; int mustAlias03 (int a) {
309 ;   int i;
310 ;   for (i=0; i<SIZE; i++)
311 ;     Foo.A[i+10] = Foo.B[SIZE-i-10] + a;
312 ;   return Foo.A[a];
313 ; }
314 ; CHECK: define i32 @mustAlias03
315 ; CHECK-NOT: add nsw <4 x i32>
316 ; CHECK ret
317
318 define i32 @mustAlias03(i32 %a) nounwind {
319 entry:
320   %a.addr = alloca i32, align 4
321   %i = alloca i32, align 4
322   store i32 %a, i32* %a.addr, align 4
323   store i32 0, i32* %i, align 4
324   br label %for.cond
325
326 for.cond:                                         ; preds = %for.inc, %entry
327   %0 = load i32* %i, align 4
328   %cmp = icmp slt i32 %0, 100
329   br i1 %cmp, label %for.body, label %for.end
330
331 for.body:                                         ; preds = %for.cond
332   %1 = load i32* %i, align 4
333   %sub = sub nsw i32 100, %1
334   %sub1 = sub nsw i32 %sub, 10
335   %arrayidx = getelementptr inbounds [100 x i32]* getelementptr inbounds (%struct.anon* @Foo, i32 0, i32 2), i32 0, i32 %sub1
336   %2 = load i32* %arrayidx, align 4
337   %3 = load i32* %a.addr, align 4
338   %add = add nsw i32 %2, %3
339   %4 = load i32* %i, align 4
340   %add2 = add nsw i32 %4, 10
341   %arrayidx3 = getelementptr inbounds [100 x i32]* getelementptr inbounds (%struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %add2
342   store i32 %add, i32* %arrayidx3, align 4
343   br label %for.inc
344
345 for.inc:                                          ; preds = %for.body
346   %5 = load i32* %i, align 4
347   %inc = add nsw i32 %5, 1
348   store i32 %inc, i32* %i, align 4
349   br label %for.cond
350
351 for.end:                                          ; preds = %for.cond
352   %6 = load i32* %a.addr, align 4
353   %arrayidx4 = getelementptr inbounds [100 x i32]* getelementptr inbounds (%struct.anon* @Foo, i32 0, i32 0), i32 0, i32 %6
354   %7 = load i32* %arrayidx4, align 4
355   ret i32 %7
356 }