Merge r261331: avoid out of bounds loads for interleaved access vectorization
[oota-llvm.git] / test / Transforms / LoopReroll / basic.ll
1 ; RUN: opt < %s -loop-reroll -S | FileCheck %s
2 target datalayout = "e-p:64:64:64-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:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
3 target triple = "x86_64-unknown-linux-gnu"
4
5 ; int foo(int a);
6 ; void bar(int *x) {
7 ;   for (int i = 0; i < 500; i += 3) {
8 ;     foo(i);
9 ;     foo(i+1);
10 ;     foo(i+2);
11 ;   }
12 ; }
13
14 ; Function Attrs: nounwind uwtable
15 define void @bar(i32* nocapture readnone %x) #0 {
16 entry:
17   br label %for.body
18
19 for.body:                                         ; preds = %for.body, %entry
20   %i.08 = phi i32 [ 0, %entry ], [ %add3, %for.body ]
21   %call = tail call i32 @foo(i32 %i.08) #1
22   %add = add nsw i32 %i.08, 1
23   %call1 = tail call i32 @foo(i32 %add) #1
24   %add2 = add nsw i32 %i.08, 2
25   %call3 = tail call i32 @foo(i32 %add2) #1
26   %add3 = add nsw i32 %i.08, 3
27   %exitcond = icmp eq i32 %add3, 500
28   br i1 %exitcond, label %for.end, label %for.body
29
30 ; CHECK-LABEL: @bar
31
32 ; CHECK: for.body:
33 ; CHECK: %indvar = phi i32 [ %indvar.next, %for.body ], [ 0, %entry ]
34 ; CHECK: %call = tail call i32 @foo(i32 %indvar) #1
35 ; CHECK: %indvar.next = add i32 %indvar, 1
36 ; CHECK: %exitcond1 = icmp eq i32 %indvar, 497
37 ; CHECK: br i1 %exitcond1, label %for.end, label %for.body
38
39 ; CHECK: ret
40
41 for.end:                                          ; preds = %for.body
42   ret void
43 }
44
45 declare i32 @foo(i32)
46
47 ; void hi1(int *x) {
48 ;   for (int i = 0; i < 1500; i += 3) {
49 ;     x[i] = foo(0);
50 ;     x[i+1] = foo(0);
51 ;     x[i+2] = foo(0);
52 ;   }
53 ; }
54
55 ; Function Attrs: nounwind uwtable
56 define void @hi1(i32* nocapture %x) #0 {
57 entry:
58   br label %for.body
59
60 for.body:                                         ; preds = %entry, %for.body
61   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
62   %call = tail call i32 @foo(i32 0) #1
63   %arrayidx = getelementptr inbounds i32, i32* %x, i64 %indvars.iv
64   store i32 %call, i32* %arrayidx, align 4
65   %call1 = tail call i32 @foo(i32 0) #1
66   %0 = add nsw i64 %indvars.iv, 1
67   %arrayidx3 = getelementptr inbounds i32, i32* %x, i64 %0
68   store i32 %call1, i32* %arrayidx3, align 4
69   %call4 = tail call i32 @foo(i32 0) #1
70   %1 = add nsw i64 %indvars.iv, 2
71   %arrayidx7 = getelementptr inbounds i32, i32* %x, i64 %1
72   store i32 %call4, i32* %arrayidx7, align 4
73   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 3
74   %2 = trunc i64 %indvars.iv.next to i32
75   %cmp = icmp slt i32 %2, 1500
76   br i1 %cmp, label %for.body, label %for.end
77
78 ; CHECK-LABEL: @hi1
79
80 ; CHECK: for.body:
81 ; CHECK: %indvar = phi i64 [ %indvar.next, %for.body ], [ 0, %entry ]
82 ; CHECK: %call = tail call i32 @foo(i32 0) #1
83 ; CHECK: %arrayidx = getelementptr inbounds i32, i32* %x, i64 %indvar
84 ; CHECK: store i32 %call, i32* %arrayidx, align 4
85 ; CHECK: %indvar.next = add i64 %indvar, 1
86 ; CHECK: %exitcond = icmp eq i64 %indvar, 1499
87 ; CHECK: br i1 %exitcond, label %for.end, label %for.body
88
89 ; CHECK: ret
90
91 for.end:                                          ; preds = %for.body
92   ret void
93 }
94
95 ; void hi2(int *x) {
96 ;   for (int i = 0; i < 500; ++i) {
97 ;     x[3*i] = foo(0);
98 ;     x[3*i+1] = foo(0);
99 ;     x[3*i+2] = foo(0);
100 ;   }
101 ; }
102
103 ; Function Attrs: nounwind uwtable
104 define void @hi2(i32* nocapture %x) #0 {
105 entry:
106   br label %for.body
107
108 for.body:                                         ; preds = %for.body, %entry
109   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
110   %call = tail call i32 @foo(i32 0) #1
111   %0 = mul nsw i64 %indvars.iv, 3
112   %arrayidx = getelementptr inbounds i32, i32* %x, i64 %0
113   store i32 %call, i32* %arrayidx, align 4
114   %call1 = tail call i32 @foo(i32 0) #1
115   %1 = add nsw i64 %0, 1
116   %arrayidx4 = getelementptr inbounds i32, i32* %x, i64 %1
117   store i32 %call1, i32* %arrayidx4, align 4
118   %call5 = tail call i32 @foo(i32 0) #1
119   %2 = add nsw i64 %0, 2
120   %arrayidx9 = getelementptr inbounds i32, i32* %x, i64 %2
121   store i32 %call5, i32* %arrayidx9, align 4
122   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
123   %exitcond = icmp eq i64 %indvars.iv.next, 500
124   br i1 %exitcond, label %for.end, label %for.body
125
126 ; CHECK-LABEL: @hi2
127
128 ; CHECK: for.body:
129 ; CHECK: %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
130 ; CHECK: %call = tail call i32 @foo(i32 0) #1
131 ; CHECK: %arrayidx = getelementptr inbounds i32, i32* %x, i64 %indvars.iv
132 ; CHECK: store i32 %call, i32* %arrayidx, align 4
133 ; CHECK: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
134 ; CHECK: %exitcond1 = icmp eq i64 %indvars.iv, 1499
135 ; CHECK: br i1 %exitcond1, label %for.end, label %for.body
136
137 ; CHECK: ret
138
139 for.end:                                          ; preds = %for.body
140   ret void
141 }
142
143 ; void goo(float alpha, float *a, float *b) {
144 ;   for (int i = 0; i < 3200; i += 5) {
145 ;     a[i] += alpha * b[i];
146 ;     a[i + 1] += alpha * b[i + 1];
147 ;     a[i + 2] += alpha * b[i + 2];
148 ;     a[i + 3] += alpha * b[i + 3];
149 ;     a[i + 4] += alpha * b[i + 4];
150 ;   }
151 ; }
152
153 ; Function Attrs: nounwind uwtable
154 define void @goo(float %alpha, float* nocapture %a, float* nocapture readonly %b) #0 {
155 entry:
156   br label %for.body
157
158 for.body:                                         ; preds = %entry, %for.body
159   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
160   %arrayidx = getelementptr inbounds float, float* %b, i64 %indvars.iv
161   %0 = load float, float* %arrayidx, align 4
162   %mul = fmul float %0, %alpha
163   %arrayidx2 = getelementptr inbounds float, float* %a, i64 %indvars.iv
164   %1 = load float, float* %arrayidx2, align 4
165   %add = fadd float %1, %mul
166   store float %add, float* %arrayidx2, align 4
167   %2 = add nsw i64 %indvars.iv, 1
168   %arrayidx5 = getelementptr inbounds float, float* %b, i64 %2
169   %3 = load float, float* %arrayidx5, align 4
170   %mul6 = fmul float %3, %alpha
171   %arrayidx9 = getelementptr inbounds float, float* %a, i64 %2
172   %4 = load float, float* %arrayidx9, align 4
173   %add10 = fadd float %4, %mul6
174   store float %add10, float* %arrayidx9, align 4
175   %5 = add nsw i64 %indvars.iv, 2
176   %arrayidx13 = getelementptr inbounds float, float* %b, i64 %5
177   %6 = load float, float* %arrayidx13, align 4
178   %mul14 = fmul float %6, %alpha
179   %arrayidx17 = getelementptr inbounds float, float* %a, i64 %5
180   %7 = load float, float* %arrayidx17, align 4
181   %add18 = fadd float %7, %mul14
182   store float %add18, float* %arrayidx17, align 4
183   %8 = add nsw i64 %indvars.iv, 3
184   %arrayidx21 = getelementptr inbounds float, float* %b, i64 %8
185   %9 = load float, float* %arrayidx21, align 4
186   %mul22 = fmul float %9, %alpha
187   %arrayidx25 = getelementptr inbounds float, float* %a, i64 %8
188   %10 = load float, float* %arrayidx25, align 4
189   %add26 = fadd float %10, %mul22
190   store float %add26, float* %arrayidx25, align 4
191   %11 = add nsw i64 %indvars.iv, 4
192   %arrayidx29 = getelementptr inbounds float, float* %b, i64 %11
193   %12 = load float, float* %arrayidx29, align 4
194   %mul30 = fmul float %12, %alpha
195   %arrayidx33 = getelementptr inbounds float, float* %a, i64 %11
196   %13 = load float, float* %arrayidx33, align 4
197   %add34 = fadd float %13, %mul30
198   store float %add34, float* %arrayidx33, align 4
199   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 5
200   %14 = trunc i64 %indvars.iv.next to i32
201   %cmp = icmp slt i32 %14, 3200
202   br i1 %cmp, label %for.body, label %for.end
203
204 ; CHECK-LABEL: @goo
205
206 ; CHECK: for.body:
207 ; CHECK: %indvar = phi i64 [ %indvar.next, %for.body ], [ 0, %entry ]
208 ; CHECK: %arrayidx = getelementptr inbounds float, float* %b, i64 %indvar
209 ; CHECK: %0 = load float, float* %arrayidx, align 4
210 ; CHECK: %mul = fmul float %0, %alpha
211 ; CHECK: %arrayidx2 = getelementptr inbounds float, float* %a, i64 %indvar
212 ; CHECK: %1 = load float, float* %arrayidx2, align 4
213 ; CHECK: %add = fadd float %1, %mul
214 ; CHECK: store float %add, float* %arrayidx2, align 4
215 ; CHECK: %indvar.next = add i64 %indvar, 1
216 ; CHECK: %exitcond = icmp eq i64 %indvar, 3199
217 ; CHECK: br i1 %exitcond, label %for.end, label %for.body
218
219 ; CHECK: ret
220
221 for.end:                                          ; preds = %for.body
222   ret void
223 }
224
225 ; void hoo(float alpha, float *a, float *b, int *ip) {
226 ;   for (int i = 0; i < 3200; i += 5) {
227 ;     a[i] += alpha * b[ip[i]];
228 ;     a[i + 1] += alpha * b[ip[i + 1]];
229 ;     a[i + 2] += alpha * b[ip[i + 2]];
230 ;     a[i + 3] += alpha * b[ip[i + 3]];
231 ;     a[i + 4] += alpha * b[ip[i + 4]];
232 ;   }
233 ; }
234
235 ; Function Attrs: nounwind uwtable
236 define void @hoo(float %alpha, float* nocapture %a, float* nocapture readonly %b, i32* nocapture readonly %ip) #0 {
237 entry:
238   br label %for.body
239
240 for.body:                                         ; preds = %entry, %for.body
241   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
242   %arrayidx = getelementptr inbounds i32, i32* %ip, i64 %indvars.iv
243   %0 = load i32, i32* %arrayidx, align 4
244   %idxprom1 = sext i32 %0 to i64
245   %arrayidx2 = getelementptr inbounds float, float* %b, i64 %idxprom1
246   %1 = load float, float* %arrayidx2, align 4
247   %mul = fmul float %1, %alpha
248   %arrayidx4 = getelementptr inbounds float, float* %a, i64 %indvars.iv
249   %2 = load float, float* %arrayidx4, align 4
250   %add = fadd float %2, %mul
251   store float %add, float* %arrayidx4, align 4
252   %3 = add nsw i64 %indvars.iv, 1
253   %arrayidx7 = getelementptr inbounds i32, i32* %ip, i64 %3
254   %4 = load i32, i32* %arrayidx7, align 4
255   %idxprom8 = sext i32 %4 to i64
256   %arrayidx9 = getelementptr inbounds float, float* %b, i64 %idxprom8
257   %5 = load float, float* %arrayidx9, align 4
258   %mul10 = fmul float %5, %alpha
259   %arrayidx13 = getelementptr inbounds float, float* %a, i64 %3
260   %6 = load float, float* %arrayidx13, align 4
261   %add14 = fadd float %6, %mul10
262   store float %add14, float* %arrayidx13, align 4
263   %7 = add nsw i64 %indvars.iv, 2
264   %arrayidx17 = getelementptr inbounds i32, i32* %ip, i64 %7
265   %8 = load i32, i32* %arrayidx17, align 4
266   %idxprom18 = sext i32 %8 to i64
267   %arrayidx19 = getelementptr inbounds float, float* %b, i64 %idxprom18
268   %9 = load float, float* %arrayidx19, align 4
269   %mul20 = fmul float %9, %alpha
270   %arrayidx23 = getelementptr inbounds float, float* %a, i64 %7
271   %10 = load float, float* %arrayidx23, align 4
272   %add24 = fadd float %10, %mul20
273   store float %add24, float* %arrayidx23, align 4
274   %11 = add nsw i64 %indvars.iv, 3
275   %arrayidx27 = getelementptr inbounds i32, i32* %ip, i64 %11
276   %12 = load i32, i32* %arrayidx27, align 4
277   %idxprom28 = sext i32 %12 to i64
278   %arrayidx29 = getelementptr inbounds float, float* %b, i64 %idxprom28
279   %13 = load float, float* %arrayidx29, align 4
280   %mul30 = fmul float %13, %alpha
281   %arrayidx33 = getelementptr inbounds float, float* %a, i64 %11
282   %14 = load float, float* %arrayidx33, align 4
283   %add34 = fadd float %14, %mul30
284   store float %add34, float* %arrayidx33, align 4
285   %15 = add nsw i64 %indvars.iv, 4
286   %arrayidx37 = getelementptr inbounds i32, i32* %ip, i64 %15
287   %16 = load i32, i32* %arrayidx37, align 4
288   %idxprom38 = sext i32 %16 to i64
289   %arrayidx39 = getelementptr inbounds float, float* %b, i64 %idxprom38
290   %17 = load float, float* %arrayidx39, align 4
291   %mul40 = fmul float %17, %alpha
292   %arrayidx43 = getelementptr inbounds float, float* %a, i64 %15
293   %18 = load float, float* %arrayidx43, align 4
294   %add44 = fadd float %18, %mul40
295   store float %add44, float* %arrayidx43, align 4
296   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 5
297   %19 = trunc i64 %indvars.iv.next to i32
298   %cmp = icmp slt i32 %19, 3200
299   br i1 %cmp, label %for.body, label %for.end
300
301 ; CHECK-LABEL: @hoo
302
303 ; CHECK: for.body:
304 ; CHECK: %indvar = phi i64 [ %indvar.next, %for.body ], [ 0, %entry ]
305 ; CHECK: %arrayidx = getelementptr inbounds i32, i32* %ip, i64 %indvar
306 ; CHECK: %0 = load i32, i32* %arrayidx, align 4
307 ; CHECK: %idxprom1 = sext i32 %0 to i64
308 ; CHECK: %arrayidx2 = getelementptr inbounds float, float* %b, i64 %idxprom1
309 ; CHECK: %1 = load float, float* %arrayidx2, align 4
310 ; CHECK: %mul = fmul float %1, %alpha
311 ; CHECK: %arrayidx4 = getelementptr inbounds float, float* %a, i64 %indvar
312 ; CHECK: %2 = load float, float* %arrayidx4, align 4
313 ; CHECK: %add = fadd float %2, %mul
314 ; CHECK: store float %add, float* %arrayidx4, align 4
315 ; CHECK: %indvar.next = add i64 %indvar, 1
316 ; CHECK: %exitcond = icmp eq i64 %indvar, 3199
317 ; CHECK: br i1 %exitcond, label %for.end, label %for.body
318
319 ; CHECK: ret
320
321 for.end:                                          ; preds = %for.body
322   ret void
323 }
324
325 ; void multi1(int *x) {
326 ;   y = foo(0)
327 ;   for (int i = 0; i < 500; ++i) {
328 ;     x[3*i] = y;
329 ;     x[3*i+1] = y;
330 ;     x[3*i+2] = y;
331 ;     x[3*i+6] = y;
332 ;     x[3*i+7] = y;
333 ;     x[3*i+8] = y;
334 ;   }
335 ; }
336
337 ; Function Attrs: nounwind uwtable
338 define void @multi1(i32* nocapture %x) #0 {
339 entry:
340   %call = tail call i32 @foo(i32 0) #1
341   br label %for.body
342
343 for.body:                                         ; preds = %for.body, %entry
344   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
345   %0 = mul nsw i64 %indvars.iv, 3
346   %arrayidx = getelementptr inbounds i32, i32* %x, i64 %0
347   store i32 %call, i32* %arrayidx, align 4
348   %1 = add nsw i64 %0, 1
349   %arrayidx4 = getelementptr inbounds i32, i32* %x, i64 %1
350   store i32 %call, i32* %arrayidx4, align 4
351   %2 = add nsw i64 %0, 2
352   %arrayidx9 = getelementptr inbounds i32, i32* %x, i64 %2
353   store i32 %call, i32* %arrayidx9, align 4
354   %3 = add nsw i64 %0, 6
355   %arrayidx6 = getelementptr inbounds i32, i32* %x, i64 %3
356   store i32 %call, i32* %arrayidx6, align 4
357   %4 = add nsw i64 %0, 7
358   %arrayidx7 = getelementptr inbounds i32, i32* %x, i64 %4
359   store i32 %call, i32* %arrayidx7, align 4
360   %5 = add nsw i64 %0, 8
361   %arrayidx8 = getelementptr inbounds i32, i32* %x, i64 %5
362   store i32 %call, i32* %arrayidx8, align 4
363   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
364   %exitcond = icmp eq i64 %indvars.iv.next, 500
365   br i1 %exitcond, label %for.end, label %for.body
366
367 ; CHECK-LABEL: @multi1
368
369 ; CHECK:for.body:
370 ; CHECK:  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
371 ; CHECK:  %0 = add i64 %indvars.iv, 6
372 ; CHECK:  %arrayidx = getelementptr inbounds i32, i32* %x, i64 %indvars.iv
373 ; CHECK:  store i32 %call, i32* %arrayidx, align 4
374 ; CHECK:  %arrayidx6 = getelementptr inbounds i32, i32* %x, i64 %0
375 ; CHECK:  store i32 %call, i32* %arrayidx6, align 4
376 ; CHECK:  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
377 ; CHECK:  %exitcond2 = icmp eq i64 %0, 1505
378 ; CHECK:  br i1 %exitcond2, label %for.end, label %for.body
379
380 for.end:                                          ; preds = %for.body
381   ret void
382 }
383
384 ; void multi2(int *x) {
385 ;   y = foo(0)
386 ;   for (int i = 0; i < 500; ++i) {
387 ;     x[3*i] = y;
388 ;     x[3*i+1] = y;
389 ;     x[3*i+2] = y;
390 ;     x[3*(i+1)] = y;
391 ;     x[3*(i+1)+1] = y;
392 ;     x[3*(i+1)+2] = y;
393 ;   }
394 ; }
395
396 ; Function Attrs: nounwind uwtable
397 define void @multi2(i32* nocapture %x) #0 {
398 entry:
399   %call = tail call i32 @foo(i32 0) #1
400   br label %for.body
401
402 for.body:                                         ; preds = %for.body, %entry
403   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
404   %0 = mul nsw i64 %indvars.iv, 3
405   %add = add nsw i64 %indvars.iv, 1
406   %newmul = mul nsw i64 %add, 3
407   %arrayidx = getelementptr inbounds i32, i32* %x, i64 %0
408   store i32 %call, i32* %arrayidx, align 4
409   %1 = add nsw i64 %0, 1
410   %arrayidx4 = getelementptr inbounds i32, i32* %x, i64 %1
411   store i32 %call, i32* %arrayidx4, align 4
412   %2 = add nsw i64 %0, 2
413   %arrayidx9 = getelementptr inbounds i32, i32* %x, i64 %2
414   store i32 %call, i32* %arrayidx9, align 4
415   %arrayidx6 = getelementptr inbounds i32, i32* %x, i64 %newmul
416   store i32 %call, i32* %arrayidx6, align 4
417   %3 = add nsw i64 %newmul, 1
418   %arrayidx7 = getelementptr inbounds i32, i32* %x, i64 %3
419   store i32 %call, i32* %arrayidx7, align 4
420   %4 = add nsw i64 %newmul, 2
421   %arrayidx8 = getelementptr inbounds i32, i32* %x, i64 %4
422   store i32 %call, i32* %arrayidx8, align 4
423   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
424   %exitcond = icmp eq i64 %indvars.iv.next, 500
425   br i1 %exitcond, label %for.end, label %for.body
426
427 ; CHECK-LABEL: @multi2
428
429 ; CHECK:for.body:
430 ; CHECK:  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
431 ; CHECK:  %0 = add i64 %indvars.iv, 3
432 ; CHECK:  %arrayidx = getelementptr inbounds i32, i32* %x, i64 %indvars.iv
433 ; CHECK:  store i32 %call, i32* %arrayidx, align 4
434 ; CHECK:  %arrayidx6 = getelementptr inbounds i32, i32* %x, i64 %0
435 ; CHECK:  store i32 %call, i32* %arrayidx6, align 4
436 ; CHECK:  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
437 ; CHECK:  %exitcond2 = icmp eq i64 %indvars.iv, 1499
438 ; CHECK:  br i1 %exitcond2, label %for.end, label %for.body
439
440 for.end:                                          ; preds = %for.body
441   ret void
442 }
443
444 ; void multi3(int *x) {
445 ;   y = foo(0)
446 ;   for (int i = 0; i < 500; ++i) {
447 ;     // Note: No zero index
448 ;     x[3*i+3] = y;
449 ;     x[3*i+4] = y;
450 ;     x[3*i+5] = y;
451 ;   }
452 ; }
453
454 ; Function Attrs: nounwind uwtable
455 define void @multi3(i32* nocapture %x) #0 {
456 entry:
457   %call = tail call i32 @foo(i32 0) #1
458   br label %for.body
459
460 for.body:                                         ; preds = %for.body, %entry
461   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
462   %0 = mul nsw i64 %indvars.iv, 3
463   %x0 = add nsw i64 %0, 3
464   %add = add nsw i64 %indvars.iv, 1
465   %arrayidx = getelementptr inbounds i32, i32* %x, i64 %x0
466   store i32 %call, i32* %arrayidx, align 4
467   %1 = add nsw i64 %0, 4
468   %arrayidx4 = getelementptr inbounds i32, i32* %x, i64 %1
469   store i32 %call, i32* %arrayidx4, align 4
470   %2 = add nsw i64 %0, 5
471   %arrayidx9 = getelementptr inbounds i32, i32* %x, i64 %2
472   store i32 %call, i32* %arrayidx9, align 4
473   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
474   %exitcond = icmp eq i64 %indvars.iv.next, 500
475   br i1 %exitcond, label %for.end, label %for.body
476
477 ; CHECK-LABEL: @multi3
478 ; CHECK: for.body:
479 ; CHECK:   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
480 ; CHECK:   %0 = add i64 %indvars.iv, 3
481 ; CHECK:   %arrayidx = getelementptr inbounds i32, i32* %x, i64 %0
482 ; CHECK:   store i32 %call, i32* %arrayidx, align 4
483 ; CHECK:   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
484 ; CHECK:   %exitcond1 = icmp eq i64 %0, 1502
485 ; CHECK:   br i1 %exitcond1, label %for.end, label %for.body
486
487 for.end:                                          ; preds = %for.body
488   ret void
489 }
490
491 ; int foo(int a);
492 ; void bar2(int *x, int y, int z) {
493 ;   for (int i = 0; i < 500; i += 3) {
494 ;     foo(i+y+i*z); // Slightly reordered instruction order
495 ;     foo(i+1+y+(i+1)*z);
496 ;     foo(i+2+y+(i+2)*z);
497 ;   }
498 ; }
499
500 ; Function Attrs: nounwind uwtable
501 define void @bar2(i32* nocapture readnone %x, i32 %y, i32 %z) #0 {
502 entry:
503   br label %for.body
504
505 for.body:                                         ; preds = %for.body, %entry
506   %i.08 = phi i32 [ 0, %entry ], [ %add3, %for.body ]
507
508   %tmp1 = add i32 %i.08, %y
509   %tmp2 = mul i32 %i.08, %z
510   %tmp3 = add i32 %tmp2, %tmp1
511   %call = tail call i32 @foo(i32 %tmp3) #1
512
513   %add = add nsw i32 %i.08, 1
514   %tmp2a = mul i32 %add, %z
515   %tmp1a = add i32 %add, %y
516   %tmp3a = add i32 %tmp2a, %tmp1a
517   %calla = tail call i32 @foo(i32 %tmp3a) #1
518   
519   %add2 = add nsw i32 %i.08, 2
520   %tmp2b = mul i32 %add2, %z
521   %tmp1b = add i32 %add2, %y
522   %tmp3b = add i32 %tmp2b, %tmp1b
523   %callb = tail call i32 @foo(i32 %tmp3b) #1
524
525   %add3 = add nsw i32 %i.08, 3
526
527   %exitcond = icmp eq i32 %add3, 500
528   br i1 %exitcond, label %for.end, label %for.body
529
530 ; CHECK-LABEL: @bar2
531
532 ; CHECK: for.body:
533 ; CHECK: %indvar = phi i32 [ %indvar.next, %for.body ], [ 0, %entry ]
534 ; CHECK: %tmp1 = add i32 %indvar, %y
535 ; CHECK: %tmp2 = mul i32 %indvar, %z
536 ; CHECK: %tmp3 = add i32 %tmp2, %tmp1
537 ; CHECK: %call = tail call i32 @foo(i32 %tmp3) #1
538 ; CHECK: %indvar.next = add i32 %indvar, 1
539 ; CHECK: %exitcond1 = icmp eq i32 %indvar, 497
540 ; CHECK: br i1 %exitcond1, label %for.end, label %for.body
541
542 ; CHECK: ret
543
544 for.end:                                          ; preds = %for.body
545   ret void
546 }
547
548 %struct.s = type { i32, i32 }
549
550 ; Function Attrs: nounwind uwtable
551 define void @gep1(%struct.s* nocapture %x) #0 {
552 entry:
553   %call = tail call i32 @foo(i32 0) #1
554   br label %for.body
555
556 for.body:                                         ; preds = %for.body, %entry
557   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
558   %0 = mul nsw i64 %indvars.iv, 3
559   %arrayidx = getelementptr inbounds %struct.s, %struct.s* %x, i64 %0, i32 0
560   store i32 %call, i32* %arrayidx, align 4
561   %1 = add nsw i64 %0, 1
562   %arrayidx4 = getelementptr inbounds %struct.s, %struct.s* %x, i64 %1, i32 0
563   store i32 %call, i32* %arrayidx4, align 4
564   %2 = add nsw i64 %0, 2
565   %arrayidx9 = getelementptr inbounds %struct.s, %struct.s* %x, i64 %2, i32 0
566   store i32 %call, i32* %arrayidx9, align 4
567   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
568   %exitcond = icmp eq i64 %indvars.iv.next, 500
569   br i1 %exitcond, label %for.end, label %for.body
570
571 ; CHECK-LABEL: @gep1
572 ; This test is a crash test only.
573 ; CHECK: ret
574 for.end:                                          ; preds = %for.body
575   ret void
576 }
577
578
579 attributes #0 = { nounwind uwtable }
580 attributes #1 = { nounwind }
581