[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / LoopReroll / basic.ll
blobc49dc9e364c96f0f77dd3e6b4ba7f8edac5858bd
1 ; RUN: opt < %s -loop-reroll -S | FileCheck %s
2 ; RUN: opt < %s -passes=loop-reroll -S | FileCheck %s
3 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"
4 target triple = "x86_64-unknown-linux-gnu"
6 ; int foo(int a);
7 ; void bar(int *x) {
8 ;   for (int i = 0; i < 500; i += 3) {
9 ;     foo(i);
10 ;     foo(i+1);
11 ;     foo(i+2);
12 ;   }
13 ; }
15 ; Function Attrs: nounwind uwtable
16 define void @bar(i32* nocapture readnone %x) #0 {
17 entry:
18   br label %for.body
20 for.body:                                         ; preds = %for.body, %entry
21   %i.08 = phi i32 [ 0, %entry ], [ %add3, %for.body ]
22   %call = tail call i32 @foo(i32 %i.08) #1
23   %add = add nsw i32 %i.08, 1
24   %call1 = tail call i32 @foo(i32 %add) #1
25   %add2 = add nsw i32 %i.08, 2
26   %call3 = tail call i32 @foo(i32 %add2) #1
27   %add3 = add nsw i32 %i.08, 3
28   %exitcond = icmp sge i32 %add3, 500
29   br i1 %exitcond, label %for.end, label %for.body
31 ; CHECK-LABEL: @bar
33 ; CHECK: for.body:
34 ; CHECK: %indvar = phi i32 [ %indvar.next, %for.body ], [ 0, %entry ]
35 ; CHECK: %call = tail call i32 @foo(i32 %indvar) #1
36 ; CHECK: %indvar.next = add i32 %indvar, 1
37 ; CHECK: %exitcond1 = icmp eq i32 %indvar, 500
38 ; CHECK: br i1 %exitcond1, label %for.end, label %for.body
40 ; CHECK: ret
42 for.end:                                          ; preds = %for.body
43   ret void
46 declare i32 @foo(i32)
48 ; void hi1(int *x) {
49 ;   for (int i = 0; i < 1500; i += 3) {
50 ;     x[i] = foo(0);
51 ;     x[i+1] = foo(0);
52 ;     x[i+2] = foo(0);
53 ;   }
54 ; }
56 ; Function Attrs: nounwind uwtable
57 define void @hi1(i32* nocapture %x) #0 {
58 entry:
59   br label %for.body
61 for.body:                                         ; preds = %entry, %for.body
62   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
63   %call = tail call i32 @foo(i32 0) #1
64   %arrayidx = getelementptr inbounds i32, i32* %x, i64 %indvars.iv
65   store i32 %call, i32* %arrayidx, align 4
66   %call1 = tail call i32 @foo(i32 0) #1
67   %0 = add nsw i64 %indvars.iv, 1
68   %arrayidx3 = getelementptr inbounds i32, i32* %x, i64 %0
69   store i32 %call1, i32* %arrayidx3, align 4
70   %call4 = tail call i32 @foo(i32 0) #1
71   %1 = add nsw i64 %indvars.iv, 2
72   %arrayidx7 = getelementptr inbounds i32, i32* %x, i64 %1
73   store i32 %call4, i32* %arrayidx7, align 4
74   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 3
75   %2 = trunc i64 %indvars.iv.next to i32
76   %cmp = icmp slt i32 %2, 1500
77   br i1 %cmp, label %for.body, label %for.end
79 ; CHECK-LABEL: @hi1
81 ; CHECK: for.body:
82 ; CHECK: %indvar = phi i64 [ %indvar.next, %for.body ], [ 0, %entry ]
83 ; CHECK: %0 = trunc i64 %indvar to i32
84 ; CHECK: %call = tail call i32 @foo(i32 0) #1
85 ; CHECK: %arrayidx = getelementptr inbounds i32, i32* %x, i64 %indvar
86 ; CHECK: store i32 %call, i32* %arrayidx, align 4
87 ; CHECK: %indvar.next = add i64 %indvar, 1
88 ; CHECK: %exitcond = icmp eq i32 %0, 1499
89 ; CHECK: br i1 %exitcond, label %for.end, label %for.body
91 ; CHECK: ret
93 for.end:                                          ; preds = %for.body
94   ret void
97 ; void hi2(int *x) {
98 ;   for (int i = 0; i < 500; ++i) {
99 ;     x[3*i] = foo(0);
100 ;     x[3*i+1] = foo(0);
101 ;     x[3*i+2] = foo(0);
102 ;   }
103 ; }
105 ; Function Attrs: nounwind uwtable
106 define void @hi2(i32* nocapture %x) #0 {
107 entry:
108   br label %for.body
110 for.body:                                         ; preds = %for.body, %entry
111   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
112   %call = tail call i32 @foo(i32 0) #1
113   %0 = mul nsw i64 %indvars.iv, 3
114   %arrayidx = getelementptr inbounds i32, i32* %x, i64 %0
115   store i32 %call, i32* %arrayidx, align 4
116   %call1 = tail call i32 @foo(i32 0) #1
117   %1 = add nsw i64 %0, 1
118   %arrayidx4 = getelementptr inbounds i32, i32* %x, i64 %1
119   store i32 %call1, i32* %arrayidx4, align 4
120   %call5 = tail call i32 @foo(i32 0) #1
121   %2 = add nsw i64 %0, 2
122   %arrayidx9 = getelementptr inbounds i32, i32* %x, i64 %2
123   store i32 %call5, i32* %arrayidx9, align 4
124   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
125   %exitcond = icmp eq i64 %indvars.iv.next, 500
126   br i1 %exitcond, label %for.end, label %for.body
128 ; CHECK-LABEL: @hi2
130 ; CHECK: for.body:
131 ; CHECK: %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
132 ; CHECK: %call = tail call i32 @foo(i32 0) #1
133 ; CHECK: %arrayidx = getelementptr inbounds i32, i32* %x, i64 %indvars.iv
134 ; CHECK: store i32 %call, i32* %arrayidx, align 4
135 ; CHECK: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
136 ; CHECK: %exitcond1 = icmp eq i64 %indvars.iv, 1499
137 ; CHECK: br i1 %exitcond1, label %for.end, label %for.body
139 ; CHECK: ret
141 for.end:                                          ; preds = %for.body
142   ret void
145 ; void goo(float alpha, float *a, float *b) {
146 ;   for (int i = 0; i < 3200; i += 5) {
147 ;     a[i] += alpha * b[i];
148 ;     a[i + 1] += alpha * b[i + 1];
149 ;     a[i + 2] += alpha * b[i + 2];
150 ;     a[i + 3] += alpha * b[i + 3];
151 ;     a[i + 4] += alpha * b[i + 4];
152 ;   }
153 ; }
155 ; Function Attrs: nounwind uwtable
156 define void @goo(float %alpha, float* nocapture %a, float* nocapture readonly %b) #0 {
157 entry:
158   br label %for.body
160 for.body:                                         ; preds = %entry, %for.body
161   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
162   %arrayidx = getelementptr inbounds float, float* %b, i64 %indvars.iv
163   %0 = load float, float* %arrayidx, align 4
164   %mul = fmul float %0, %alpha
165   %arrayidx2 = getelementptr inbounds float, float* %a, i64 %indvars.iv
166   %1 = load float, float* %arrayidx2, align 4
167   %add = fadd float %1, %mul
168   store float %add, float* %arrayidx2, align 4
169   %2 = add nsw i64 %indvars.iv, 1
170   %arrayidx5 = getelementptr inbounds float, float* %b, i64 %2
171   %3 = load float, float* %arrayidx5, align 4
172   %mul6 = fmul float %3, %alpha
173   %arrayidx9 = getelementptr inbounds float, float* %a, i64 %2
174   %4 = load float, float* %arrayidx9, align 4
175   %add10 = fadd float %4, %mul6
176   store float %add10, float* %arrayidx9, align 4
177   %5 = add nsw i64 %indvars.iv, 2
178   %arrayidx13 = getelementptr inbounds float, float* %b, i64 %5
179   %6 = load float, float* %arrayidx13, align 4
180   %mul14 = fmul float %6, %alpha
181   %arrayidx17 = getelementptr inbounds float, float* %a, i64 %5
182   %7 = load float, float* %arrayidx17, align 4
183   %add18 = fadd float %7, %mul14
184   store float %add18, float* %arrayidx17, align 4
185   %8 = add nsw i64 %indvars.iv, 3
186   %arrayidx21 = getelementptr inbounds float, float* %b, i64 %8
187   %9 = load float, float* %arrayidx21, align 4
188   %mul22 = fmul float %9, %alpha
189   %arrayidx25 = getelementptr inbounds float, float* %a, i64 %8
190   %10 = load float, float* %arrayidx25, align 4
191   %add26 = fadd float %10, %mul22
192   store float %add26, float* %arrayidx25, align 4
193   %11 = add nsw i64 %indvars.iv, 4
194   %arrayidx29 = getelementptr inbounds float, float* %b, i64 %11
195   %12 = load float, float* %arrayidx29, align 4
196   %mul30 = fmul float %12, %alpha
197   %arrayidx33 = getelementptr inbounds float, float* %a, i64 %11
198   %13 = load float, float* %arrayidx33, align 4
199   %add34 = fadd float %13, %mul30
200   store float %add34, float* %arrayidx33, align 4
201   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 5
202   %14 = trunc i64 %indvars.iv.next to i32
203   %cmp = icmp slt i32 %14, 3200
204   br i1 %cmp, label %for.body, label %for.end
206 ; CHECK-LABEL: @goo
208 ; CHECK: for.body:
209 ; CHECK: %indvar = phi i64 [ %indvar.next, %for.body ], [ 0, %entry ]
210 ; CHECK: %0 = trunc i64 %indvar to i32
211 ; CHECK: %arrayidx = getelementptr inbounds float, float* %b, i64 %indvar
212 ; CHECK: %1 = load float, float* %arrayidx, align 4
213 ; CHECK: %mul = fmul float %1, %alpha
214 ; CHECK: %arrayidx2 = getelementptr inbounds float, float* %a, i64 %indvar
215 ; CHECK: %2 = load float, float* %arrayidx2, align 4
216 ; CHECK: %add = fadd float %2, %mul
217 ; CHECK: store float %add, float* %arrayidx2, align 4
218 ; CHECK: %indvar.next = add i64 %indvar, 1
219 ; CHECK: %exitcond = icmp eq i32 %0, 3199
220 ; CHECK: br i1 %exitcond, label %for.end, label %for.body
222 ; CHECK: ret
224 for.end:                                          ; preds = %for.body
225   ret void
228 ; void hoo(float alpha, float *a, float *b, int *ip) {
229 ;   for (int i = 0; i < 3200; i += 5) {
230 ;     a[i] += alpha * b[ip[i]];
231 ;     a[i + 1] += alpha * b[ip[i + 1]];
232 ;     a[i + 2] += alpha * b[ip[i + 2]];
233 ;     a[i + 3] += alpha * b[ip[i + 3]];
234 ;     a[i + 4] += alpha * b[ip[i + 4]];
235 ;   }
236 ; }
238 ; Function Attrs: nounwind uwtable
239 define void @hoo(float %alpha, float* nocapture %a, float* nocapture readonly %b, i32* nocapture readonly %ip) #0 {
240 entry:
241   br label %for.body
243 for.body:                                         ; preds = %entry, %for.body
244   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
245   %arrayidx = getelementptr inbounds i32, i32* %ip, i64 %indvars.iv
246   %0 = load i32, i32* %arrayidx, align 4
247   %idxprom1 = sext i32 %0 to i64
248   %arrayidx2 = getelementptr inbounds float, float* %b, i64 %idxprom1
249   %1 = load float, float* %arrayidx2, align 4
250   %mul = fmul float %1, %alpha
251   %arrayidx4 = getelementptr inbounds float, float* %a, i64 %indvars.iv
252   %2 = load float, float* %arrayidx4, align 4
253   %add = fadd float %2, %mul
254   store float %add, float* %arrayidx4, align 4
255   %3 = add nsw i64 %indvars.iv, 1
256   %arrayidx7 = getelementptr inbounds i32, i32* %ip, i64 %3
257   %4 = load i32, i32* %arrayidx7, align 4
258   %idxprom8 = sext i32 %4 to i64
259   %arrayidx9 = getelementptr inbounds float, float* %b, i64 %idxprom8
260   %5 = load float, float* %arrayidx9, align 4
261   %mul10 = fmul float %5, %alpha
262   %arrayidx13 = getelementptr inbounds float, float* %a, i64 %3
263   %6 = load float, float* %arrayidx13, align 4
264   %add14 = fadd float %6, %mul10
265   store float %add14, float* %arrayidx13, align 4
266   %7 = add nsw i64 %indvars.iv, 2
267   %arrayidx17 = getelementptr inbounds i32, i32* %ip, i64 %7
268   %8 = load i32, i32* %arrayidx17, align 4
269   %idxprom18 = sext i32 %8 to i64
270   %arrayidx19 = getelementptr inbounds float, float* %b, i64 %idxprom18
271   %9 = load float, float* %arrayidx19, align 4
272   %mul20 = fmul float %9, %alpha
273   %arrayidx23 = getelementptr inbounds float, float* %a, i64 %7
274   %10 = load float, float* %arrayidx23, align 4
275   %add24 = fadd float %10, %mul20
276   store float %add24, float* %arrayidx23, align 4
277   %11 = add nsw i64 %indvars.iv, 3
278   %arrayidx27 = getelementptr inbounds i32, i32* %ip, i64 %11
279   %12 = load i32, i32* %arrayidx27, align 4
280   %idxprom28 = sext i32 %12 to i64
281   %arrayidx29 = getelementptr inbounds float, float* %b, i64 %idxprom28
282   %13 = load float, float* %arrayidx29, align 4
283   %mul30 = fmul float %13, %alpha
284   %arrayidx33 = getelementptr inbounds float, float* %a, i64 %11
285   %14 = load float, float* %arrayidx33, align 4
286   %add34 = fadd float %14, %mul30
287   store float %add34, float* %arrayidx33, align 4
288   %15 = add nsw i64 %indvars.iv, 4
289   %arrayidx37 = getelementptr inbounds i32, i32* %ip, i64 %15
290   %16 = load i32, i32* %arrayidx37, align 4
291   %idxprom38 = sext i32 %16 to i64
292   %arrayidx39 = getelementptr inbounds float, float* %b, i64 %idxprom38
293   %17 = load float, float* %arrayidx39, align 4
294   %mul40 = fmul float %17, %alpha
295   %arrayidx43 = getelementptr inbounds float, float* %a, i64 %15
296   %18 = load float, float* %arrayidx43, align 4
297   %add44 = fadd float %18, %mul40
298   store float %add44, float* %arrayidx43, align 4
299   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 5
300   %19 = trunc i64 %indvars.iv.next to i32
301   %cmp = icmp slt i32 %19, 3200
302   br i1 %cmp, label %for.body, label %for.end
304 ; CHECK-LABEL: @hoo
306 ; CHECK: for.body:
307 ; CHECK: %indvar = phi i64 [ %indvar.next, %for.body ], [ 0, %entry ]
308 ; CHECK: %0 = trunc i64 %indvar to i32
309 ; CHECK: %arrayidx = getelementptr inbounds i32, i32* %ip, i64 %indvar
310 ; CHECK: %1 = load i32, i32* %arrayidx, align 4
311 ; CHECK: %idxprom1 = sext i32 %1 to i64
312 ; CHECK: %arrayidx2 = getelementptr inbounds float, float* %b, i64 %idxprom1
313 ; CHECK: %2 = load float, float* %arrayidx2, align 4
314 ; CHECK: %mul = fmul float %2, %alpha
315 ; CHECK: %arrayidx4 = getelementptr inbounds float, float* %a, i64 %indvar
316 ; CHECK: %3 = load float, float* %arrayidx4, align 4
317 ; CHECK: %add = fadd float %3, %mul
318 ; CHECK: store float %add, float* %arrayidx4, align 4
319 ; CHECK: %indvar.next = add i64 %indvar, 1
320 ; CHECK: %exitcond = icmp eq i32 %0, 3199
321 ; CHECK: br i1 %exitcond, label %for.end, label %for.body
323 ; CHECK: ret
325 for.end:                                          ; preds = %for.body
326   ret void
329 ; void multi1(int *x) {
330 ;   y = foo(0)
331 ;   for (int i = 0; i < 500; ++i) {
332 ;     x[3*i] = y;
333 ;     x[3*i+1] = y;
334 ;     x[3*i+2] = y;
335 ;     x[3*i+6] = y;
336 ;     x[3*i+7] = y;
337 ;     x[3*i+8] = y;
338 ;   }
339 ; }
341 ; Function Attrs: nounwind uwtable
342 define void @multi1(i32* nocapture %x) #0 {
343 entry:
344   %call = tail call i32 @foo(i32 0) #1
345   br label %for.body
347 for.body:                                         ; preds = %for.body, %entry
348   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
349   %0 = mul nsw i64 %indvars.iv, 3
350   %arrayidx = getelementptr inbounds i32, i32* %x, i64 %0
351   store i32 %call, i32* %arrayidx, align 4
352   %1 = add nsw i64 %0, 1
353   %arrayidx4 = getelementptr inbounds i32, i32* %x, i64 %1
354   store i32 %call, i32* %arrayidx4, align 4
355   %2 = add nsw i64 %0, 2
356   %arrayidx9 = getelementptr inbounds i32, i32* %x, i64 %2
357   store i32 %call, i32* %arrayidx9, align 4
358   %3 = add nsw i64 %0, 6
359   %arrayidx6 = getelementptr inbounds i32, i32* %x, i64 %3
360   store i32 %call, i32* %arrayidx6, align 4
361   %4 = add nsw i64 %0, 7
362   %arrayidx7 = getelementptr inbounds i32, i32* %x, i64 %4
363   store i32 %call, i32* %arrayidx7, align 4
364   %5 = add nsw i64 %0, 8
365   %arrayidx8 = getelementptr inbounds i32, i32* %x, i64 %5
366   store i32 %call, i32* %arrayidx8, align 4
367   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
368   %exitcond = icmp eq i64 %indvars.iv.next, 500
369   br i1 %exitcond, label %for.end, label %for.body
371 ; CHECK-LABEL: @multi1
373 ; CHECK:for.body:
374 ; CHECK:  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
375 ; CHECK:  %0 = add i64 %indvars.iv, 6
376 ; CHECK:  %arrayidx = getelementptr inbounds i32, i32* %x, i64 %indvars.iv
377 ; CHECK:  store i32 %call, i32* %arrayidx, align 4
378 ; CHECK:  %arrayidx6 = getelementptr inbounds i32, i32* %x, i64 %0
379 ; CHECK:  store i32 %call, i32* %arrayidx6, align 4
380 ; CHECK:  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
381 ; CHECK:  %exitcond1 = icmp eq i64 %indvars.iv, 1499
382 ; CHECK:  br i1 %exitcond1, label %for.end, label %for.body
384 for.end:                                          ; preds = %for.body
385   ret void
388 ; void multi2(int *x) {
389 ;   y = foo(0)
390 ;   for (int i = 0; i < 500; ++i) {
391 ;     x[3*i] = y;
392 ;     x[3*i+1] = y;
393 ;     x[3*i+2] = y;
394 ;     x[3*(i+1)] = y;
395 ;     x[3*(i+1)+1] = y;
396 ;     x[3*(i+1)+2] = y;
397 ;   }
398 ; }
400 ; Function Attrs: nounwind uwtable
401 define void @multi2(i32* nocapture %x) #0 {
402 entry:
403   %call = tail call i32 @foo(i32 0) #1
404   br label %for.body
406 for.body:                                         ; preds = %for.body, %entry
407   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
408   %0 = mul nsw i64 %indvars.iv, 3
409   %add = add nsw i64 %indvars.iv, 1
410   %newmul = mul nsw i64 %add, 3
411   %arrayidx = getelementptr inbounds i32, i32* %x, i64 %0
412   store i32 %call, i32* %arrayidx, align 4
413   %1 = add nsw i64 %0, 1
414   %arrayidx4 = getelementptr inbounds i32, i32* %x, i64 %1
415   store i32 %call, i32* %arrayidx4, align 4
416   %2 = add nsw i64 %0, 2
417   %arrayidx9 = getelementptr inbounds i32, i32* %x, i64 %2
418   store i32 %call, i32* %arrayidx9, align 4
419   %arrayidx6 = getelementptr inbounds i32, i32* %x, i64 %newmul
420   store i32 %call, i32* %arrayidx6, align 4
421   %3 = add nsw i64 %newmul, 1
422   %arrayidx7 = getelementptr inbounds i32, i32* %x, i64 %3
423   store i32 %call, i32* %arrayidx7, align 4
424   %4 = add nsw i64 %newmul, 2
425   %arrayidx8 = getelementptr inbounds i32, i32* %x, i64 %4
426   store i32 %call, i32* %arrayidx8, align 4
427   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
428   %exitcond = icmp eq i64 %indvars.iv.next, 500
429   br i1 %exitcond, label %for.end, label %for.body
431 ; CHECK-LABEL: @multi2
433 ; CHECK:for.body:
434 ; CHECK:  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
435 ; CHECK:  %0 = add i64 %indvars.iv, 3
436 ; CHECK:  %arrayidx = getelementptr inbounds i32, i32* %x, i64 %indvars.iv
437 ; CHECK:  store i32 %call, i32* %arrayidx, align 4
438 ; CHECK:  %arrayidx6 = getelementptr inbounds i32, i32* %x, i64 %0
439 ; CHECK:  store i32 %call, i32* %arrayidx6, align 4
440 ; CHECK:  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
441 ; CHECK:  %exitcond1 = icmp eq i64 %indvars.iv, 1499
442 ; CHECK:  br i1 %exitcond1, label %for.end, label %for.body
444 for.end:                                          ; preds = %for.body
445   ret void
448 ; void multi3(int *x) {
449 ;   y = foo(0)
450 ;   for (int i = 0; i < 500; ++i) {
451 ;     // Note: No zero index
452 ;     x[3*i+3] = y;
453 ;     x[3*i+4] = y;
454 ;     x[3*i+5] = y;
455 ;   }
456 ; }
458 ; Function Attrs: nounwind uwtable
459 define void @multi3(i32* nocapture %x) #0 {
460 entry:
461   %call = tail call i32 @foo(i32 0) #1
462   br label %for.body
464 for.body:                                         ; preds = %for.body, %entry
465   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
466   %0 = mul nsw i64 %indvars.iv, 3
467   %x0 = add nsw i64 %0, 3
468   %add = add nsw i64 %indvars.iv, 1
469   %arrayidx = getelementptr inbounds i32, i32* %x, i64 %x0
470   store i32 %call, i32* %arrayidx, align 4
471   %1 = add nsw i64 %0, 4
472   %arrayidx4 = getelementptr inbounds i32, i32* %x, i64 %1
473   store i32 %call, i32* %arrayidx4, align 4
474   %2 = add nsw i64 %0, 5
475   %arrayidx9 = getelementptr inbounds i32, i32* %x, i64 %2
476   store i32 %call, i32* %arrayidx9, align 4
477   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
478   %exitcond = icmp eq i64 %indvars.iv.next, 500
479   br i1 %exitcond, label %for.end, label %for.body
481 ; CHECK-LABEL: @multi3
482 ; CHECK: for.body:
483 ; CHECK:   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
484 ; CHECK:   %0 = add i64 %indvars.iv, 3
485 ; CHECK:   %arrayidx = getelementptr inbounds i32, i32* %x, i64 %0
486 ; CHECK:   store i32 %call, i32* %arrayidx, align 4
487 ; CHECK:   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
488 ; CHECK:   %exitcond1 = icmp eq i64 %indvars.iv, 1499
489 ; CHECK:   br i1 %exitcond1, label %for.end, label %for.body
491 for.end:                                          ; preds = %for.body
492   ret void
495 ; int foo(int a);
496 ; void bar2(int *x, int y, int z) {
497 ;   for (int i = 0; i < 500; i += 3) {
498 ;     foo(i+y+i*z); // Slightly reordered instruction order
499 ;     foo(i+1+y+(i+1)*z);
500 ;     foo(i+2+y+(i+2)*z);
501 ;   }
502 ; }
504 ; Function Attrs: nounwind uwtable
505 define void @bar2(i32* nocapture readnone %x, i32 %y, i32 %z) #0 {
506 entry:
507   br label %for.body
509 for.body:                                         ; preds = %for.body, %entry
510   %i.08 = phi i32 [ 0, %entry ], [ %add3, %for.body ]
512   %tmp1 = add i32 %i.08, %y
513   %tmp2 = mul i32 %i.08, %z
514   %tmp3 = add i32 %tmp2, %tmp1
515   %call = tail call i32 @foo(i32 %tmp3) #1
517   %add = add nsw i32 %i.08, 1
518   %tmp2a = mul i32 %add, %z
519   %tmp1a = add i32 %add, %y
520   %tmp3a = add i32 %tmp2a, %tmp1a
521   %calla = tail call i32 @foo(i32 %tmp3a) #1
522   
523   %add2 = add nsw i32 %i.08, 2
524   %tmp2b = mul i32 %add2, %z
525   %tmp1b = add i32 %add2, %y
526   %tmp3b = add i32 %tmp2b, %tmp1b
527   %callb = tail call i32 @foo(i32 %tmp3b) #1
529   %add3 = add nsw i32 %i.08, 3
531   %exitcond = icmp sge i32 %add3, 500
532   br i1 %exitcond, label %for.end, label %for.body
534 ; CHECK-LABEL: @bar2
536 ; CHECK: for.body:
537 ; CHECK: %indvar = phi i32 [ %indvar.next, %for.body ], [ 0, %entry ]
538 ; CHECK: %tmp1 = add i32 %indvar, %y
539 ; CHECK: %tmp2 = mul i32 %indvar, %z
540 ; CHECK: %tmp3 = add i32 %tmp2, %tmp1
541 ; CHECK: %call = tail call i32 @foo(i32 %tmp3) #1
542 ; CHECK: %indvar.next = add i32 %indvar, 1
543 ; CHECK: %exitcond1 = icmp eq i32 %indvar, 500
544 ; CHECK: br i1 %exitcond1, label %for.end, label %for.body
546 ; CHECK: ret
548 for.end:                                          ; preds = %for.body
549   ret void
552 %struct.s = type { i32, i32 }
554 ; Function Attrs: nounwind uwtable
555 define void @gep1(%struct.s* nocapture %x) #0 {
556 entry:
557   %call = tail call i32 @foo(i32 0) #1
558   br label %for.body
560 for.body:                                         ; preds = %for.body, %entry
561   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
562   %0 = mul nsw i64 %indvars.iv, 3
563   %arrayidx = getelementptr inbounds %struct.s, %struct.s* %x, i64 %0, i32 0
564   store i32 %call, i32* %arrayidx, align 4
565   %1 = add nsw i64 %0, 1
566   %arrayidx4 = getelementptr inbounds %struct.s, %struct.s* %x, i64 %1, i32 0
567   store i32 %call, i32* %arrayidx4, align 4
568   %2 = add nsw i64 %0, 2
569   %arrayidx9 = getelementptr inbounds %struct.s, %struct.s* %x, i64 %2, i32 0
570   store i32 %call, i32* %arrayidx9, align 4
571   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
572   %exitcond = icmp eq i64 %indvars.iv.next, 500
573   br i1 %exitcond, label %for.end, label %for.body
575 ; CHECK-LABEL: @gep1
576 ; This test is a crash test only.
577 ; CHECK: ret
578 for.end:                                          ; preds = %for.body
579   ret void
582 define void @gep-indexing(i32* nocapture %x) {
583 entry:
584   %call = tail call i32 @foo(i32 0) #1
585   br label %for.body
587 for.body:                                         ; preds = %for.body, %entry
588   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
589   %0 = mul nsw i64 %indvars.iv, 3
590   %arrayidx = getelementptr inbounds i32, i32* %x, i64 %0
591   store i32 %call, i32* %arrayidx, align 4
592   %arrayidx4 = getelementptr inbounds i32, i32* %arrayidx, i64 1
593   store i32 %call, i32* %arrayidx4, align 4
594   %arrayidx9 = getelementptr inbounds i32, i32* %arrayidx, i64 2
595   store i32 %call, i32* %arrayidx9, align 4
596   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
597   %exitcond = icmp eq i64 %indvars.iv.next, 500
598   br i1 %exitcond, label %for.end, label %for.body
600 ; CHECK-LABEL: @gep-indexing
601 ; CHECK:      for.body:
602 ; CHECK-NEXT:   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
603 ; CHECK-NEXT:   %scevgep = getelementptr i32, i32* %x, i64 %indvars.iv
604 ; CHECK-NEXT:   store i32 %call, i32* %scevgep, align 4
605 ; CHECK-NEXT:   %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
606 ; CHECK-NEXT:   %exitcond1 = icmp eq i64 %indvars.iv, 1499
607 ; CHECK-NEXT:   br i1 %exitcond1, label %for.end, label %for.body
609 for.end:                                          ; preds = %for.body
610   ret void
614 define void @unordered_atomic_ops(i32* noalias %buf_0, i32* noalias %buf_1) {
615 ; CHECK-LABEL: @unordered_atomic_ops(
617 ; CHECK: for.body:
618 ; CHECK-NEXT:   %indvar = phi i32 [ %indvar.next, %for.body ], [ 0, %entry ]
619 ; CHECK-NEXT:   %buf0_a = getelementptr i32, i32* %buf_0, i32 %indvar
620 ; CHECK-NEXT:   %buf1_a = getelementptr i32, i32* %buf_1, i32 %indvar
621 ; CHECK-NEXT:   %va = load atomic i32, i32* %buf0_a unordered, align 4
622 ; CHECK-NEXT:   store atomic i32 %va, i32* %buf1_a unordered, align 4
623 ; CHECK-NEXT:   %indvar.next = add i32 %indvar, 1
624 ; CHECK-NEXT:   %exitcond = icmp eq i32 %indvar, 3199
625 ; CHECK-NEXT:   br i1 %exitcond, label %for.end, label %for.body
627 entry:
628   br label %for.body
630 for.body:
631   %indvars.iv = phi i32 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
632   %indvars.iv.next = add i32 %indvars.iv, 2
633   %indvars.mid = add i32 %indvars.iv, 1
634   %buf0_a = getelementptr i32, i32* %buf_0, i32 %indvars.iv
635   %buf0_b = getelementptr i32, i32* %buf_0, i32 %indvars.mid
636   %buf1_a = getelementptr i32, i32* %buf_1, i32 %indvars.iv
637   %buf1_b = getelementptr i32, i32* %buf_1, i32 %indvars.mid
638   %va = load atomic i32, i32* %buf0_a unordered, align 4
639   %vb = load atomic i32, i32* %buf0_b unordered, align 4
640   store atomic i32 %va, i32* %buf1_a unordered, align 4
641   store atomic i32 %vb, i32* %buf1_b unordered, align 4
642   %cmp = icmp slt i32 %indvars.iv.next, 3200
643   br i1 %cmp, label %for.body, label %for.end
645 for.end:
646   ret void
649 define void @unordered_atomic_ops_nomatch(i32* noalias %buf_0, i32* noalias %buf_1) {
650 ; Negative test
652 ; CHECK-LABEL: @unordered_atomic_ops_nomatch(
653 entry:
654   br label %for.body
656 for.body:
657 ; CHECK: for.body:
658 ; CHECK:   %indvars.iv.next = add i32 %indvars.iv, 2
659 ; CHECK:   %indvars.mid = add i32 %indvars.iv, 1
660 ; CHECK:   %cmp = icmp slt i32 %indvars.iv.next, 3200
661 ; CHECK:   br i1 %cmp, label %for.body, label %for.end
663   %indvars.iv = phi i32 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
664   %indvars.iv.next = add i32 %indvars.iv, 2
665   %indvars.mid = add i32 %indvars.iv, 1
666   %buf0_a = getelementptr i32, i32* %buf_0, i32 %indvars.iv
667   %buf0_b = getelementptr i32, i32* %buf_0, i32 %indvars.mid
668   %buf1_a = getelementptr i32, i32* %buf_1, i32 %indvars.iv
669   %buf1_b = getelementptr i32, i32* %buf_1, i32 %indvars.mid
670   %va = load atomic i32, i32* %buf0_a unordered, align 4
671   %vb = load atomic i32, i32* %buf0_b unordered, align 4
672   store i32 %va, i32* %buf1_a, align 4  ;; Not atomic
673   store atomic i32 %vb, i32* %buf1_b unordered, align 4
674   %cmp = icmp slt i32 %indvars.iv.next, 3200
675   br i1 %cmp, label %for.body, label %for.end
677 for.end:
678   ret void
681 define void @ordered_atomic_ops(i32* noalias %buf_0, i32* noalias %buf_1) {
682 ; Negative test
684 ; CHECK-LABEL: @ordered_atomic_ops(
685 entry:
686   br label %for.body
688 for.body:
689 ; CHECK: for.body:
690 ; CHECK:   %indvars.iv.next = add i32 %indvars.iv, 2
691 ; CHECK:   %indvars.mid = add i32 %indvars.iv, 1
692 ; CHECK:   %cmp = icmp slt i32 %indvars.iv.next, 3200
693 ; CHECK:   br i1 %cmp, label %for.body, label %for.end
695   %indvars.iv = phi i32 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
696   %indvars.iv.next = add i32 %indvars.iv, 2
697   %indvars.mid = add i32 %indvars.iv, 1
698   %buf0_a = getelementptr i32, i32* %buf_0, i32 %indvars.iv
699   %buf0_b = getelementptr i32, i32* %buf_0, i32 %indvars.mid
700   %buf1_a = getelementptr i32, i32* %buf_1, i32 %indvars.iv
701   %buf1_b = getelementptr i32, i32* %buf_1, i32 %indvars.mid
702   %va = load atomic i32, i32* %buf0_a acquire, align 4
703   %vb = load atomic i32, i32* %buf0_b acquire, align 4
704   store atomic i32 %va, i32* %buf1_a release, align 4
705   store atomic i32 %vb, i32* %buf1_b release, align 4
706   %cmp = icmp slt i32 %indvars.iv.next, 3200
707   br i1 %cmp, label %for.body, label %for.end
709 for.end:
710   ret void
713 define void @unordered_atomic_ops_with_fence(i32* noalias %buf_0, i32* noalias %buf_1) {
714 ; CHECK-LABEL: @unordered_atomic_ops_with_fence(
715 entry:
716   br label %for.body
718 for.body:
719 ; CHECK: for.body:
720 ; CHECK:  %va = load atomic i32, i32* %buf0_a unordered, align 4
721 ; CHECK-NEXT:  %vb = load atomic i32, i32* %buf0_b unordered, align 4
722 ; CHECK-NEXT:  fence seq_cst
723 ; CHECK-NEXT:  store atomic i32 %va, i32* %buf1_a unordered, align 4
724 ; CHECK-NEXT:  store atomic i32 %vb, i32* %buf1_b unordered, align 4
726   %indvars.iv = phi i32 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
727   %indvars.iv.next = add i32 %indvars.iv, 2
728   %indvars.mid = add i32 %indvars.iv, 1
729   %buf0_a = getelementptr i32, i32* %buf_0, i32 %indvars.iv
730   %buf0_b = getelementptr i32, i32* %buf_0, i32 %indvars.mid
731   %buf1_a = getelementptr i32, i32* %buf_1, i32 %indvars.iv
732   %buf1_b = getelementptr i32, i32* %buf_1, i32 %indvars.mid
733   %va = load atomic i32, i32* %buf0_a unordered, align 4
734   %vb = load atomic i32, i32* %buf0_b unordered, align 4
735   fence seq_cst
736   store atomic i32 %va, i32* %buf1_a unordered, align 4
737   store atomic i32 %vb, i32* %buf1_b unordered, align 4
738   %cmp = icmp slt i32 %indvars.iv.next, 3200
739   br i1 %cmp, label %for.body, label %for.end
741 for.end:
742   ret void
745 define void @pointer_bitcast_baseinst(i16* %arg, i8* %arg1, i64 %arg2) {
746 ; CHECK-LABEL: @pointer_bitcast_baseinst(
747 ; CHECK:       bb3:
748 ; CHECK-NEXT:    %indvar = phi i64 [ %indvar.next, %bb3 ], [ 0, %bb ]
749 ; CHECK-NEXT:    %4 = shl nuw i64 %indvar, 3
750 ; CHECK-NEXT:    %5 = add i64 %4, 1
751 ; CHECK-NEXT:    %tmp5 = shl nuw i64 %5, 1
752 ; CHECK-NEXT:    %tmp6 = getelementptr i8, i8* %arg1, i64 %tmp5
753 ; CHECK-NEXT:    %tmp7 = bitcast i8* %tmp6 to <8 x i16>*
754 ; CHECK-NEXT:    %tmp8 = load <8 x i16>, <8 x i16>* %tmp7, align 2
755 ; CHECK-NEXT:    %tmp13 = getelementptr i16, i16* %arg, i64 %5
756 ; CHECK-NEXT:    %tmp14 = bitcast i16* %tmp13 to <8 x i16>*
757 ; CHECK-NEXT:    store <8 x i16> %tmp8, <8 x i16>* %tmp14, align 2
758 ; CHECK-NEXT:    %indvar.next = add i64 %indvar, 1
759 ; CHECK-NEXT:    %exitcond = icmp eq i64 %indvar, %3
760 ; CHECK-NEXT:    br i1 %exitcond, label %bb19, label %bb3
762   br label %bb3
764 bb3:                                              ; preds = %bb3, %bb
765   %tmp = phi i64 [ 1, %bb ], [ %tmp17, %bb3 ]
766   %tmp4 = add nuw i64 %tmp, 8
767   %tmp5 = shl nuw i64 %tmp, 1
768   %tmp6 = getelementptr i8, i8* %arg1, i64 %tmp5
769   %tmp7 = bitcast i8* %tmp6 to <8 x i16>*
770   %tmp8 = load <8 x i16>, <8 x i16>* %tmp7, align 2
771   %tmp9 = shl i64 %tmp4, 1
772   %tmp10 = getelementptr i8, i8* %arg1, i64 %tmp9
773   %tmp11 = bitcast i8* %tmp10 to <8 x i16>*
774   %tmp12 = load <8 x i16>, <8 x i16>* %tmp11, align 2
775   %tmp13 = getelementptr i16, i16* %arg, i64 %tmp
776   %tmp14 = bitcast i16* %tmp13 to <8 x i16>*
777   store <8 x i16> %tmp8, <8 x i16>* %tmp14, align 2
778   %tmp15 = getelementptr i16, i16* %arg, i64 %tmp4
779   %tmp16 = bitcast i16* %tmp15 to <8 x i16>*
780   store <8 x i16> %tmp12, <8 x i16>* %tmp16, align 2
781   %tmp17 = add nuw nsw i64 %tmp, 16
782   %tmp18 = icmp eq i64 %tmp17, %arg2
783   br i1 %tmp18, label %bb19, label %bb3
785 bb19:                                             ; preds = %bb3
786   ret void
789 define void @bad_step(i32* nocapture readnone %x) #0 {
790 entry:
791   br label %for.body
793 for.body:                                         ; preds = %for.body, %entry
794   %i.08 = phi i32 [ 0, %entry ], [ %add3, %for.body ]
795   %call = tail call i32 @foo(i32 %i.08) #1
796   %add = add nsw i32 %i.08, 2
797   %call1 = tail call i32 @foo(i32 %add) #1
798   %add2 = add nsw i32 %i.08, 3
799   %call3 = tail call i32 @foo(i32 %add2) #1
800   %add3 = add nsw i32 %i.08, 6
801   %exitcond = icmp sge i32 %add3, 500
802   br i1 %exitcond, label %for.end, label %for.body
804 ; CHECK-LABEL: @bad_step
805 ; CHECK: %add = add nsw i32 %i.08, 2
806 ; CHECK: %add2 = add nsw i32 %i.08, 3
807 ; CHECK: %add3 = add nsw i32 %i.08, 6
809 for.end:                                          ; preds = %for.body
810   ret void
813 @a = external global [2 x [512 x i64]], align 16
814 @b = external global [512 x [4 x i64]], align 16
816 define void @ptr_step_crash() {
817 ; CHECK-LABEL: @ptr_step_crash(
818 entry:
819   br label %for.body42.3
821 for.body42.3:                                     ; preds = %for.body42.3, %entry
822   %k.2207.3 = phi i32 [ -512, %entry ], [ %inc63.3, %for.body42.3 ]
823   %sub46.3 = add nsw i32 %k.2207.3, 512
824   %idxprom47.3 = zext i32 %sub46.3 to i64
825   %arrayidx48.3 = getelementptr inbounds [2 x [512 x i64]], [2 x [512 x i64]]* @a, i64 0, i64 0, i64 %idxprom47.3
826   %arrayidx55.3 = getelementptr inbounds [512 x [4 x i64]], [512 x [4 x i64]]* @b, i64 0, i64 %idxprom47.3, i64 3
827   %0 = load i64, i64* %arrayidx55.3, align 8
828   %inc63.3 = add nsw i32 %k.2207.3, 1
829   br i1 undef, label %for.inc65.3, label %for.body42.3
831 for.inc65.3:                                      ; preds = %for.body42.3
832   ret void
835 attributes #0 = { nounwind uwtable }
836 attributes #1 = { nounwind }