xref: /llvm-project/llvm/test/Transforms/LoopUnrollAndJam/disable.ll (revision 055fb7795aa219a3d274d280ec9129784f169f56)
1; RUN: opt -passes=loop-unroll-and-jam -allow-unroll-and-jam -unroll-and-jam-count=4 -pass-remarks=loop-unroll-and-jam < %s -S 2>&1 | FileCheck %s
2; RUN: opt -passes='loop-unroll-and-jam' -allow-unroll-and-jam -unroll-and-jam-count=4 -pass-remarks=loop-unroll-and-jam < %s -S 2>&1 | FileCheck %s
3
4target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
5
6;; Common check for all tests. None should be unroll and jammed
7; CHECK-NOT: remark: {{.*}} unroll and jammed
8
9
10; CHECK-LABEL: disabled1
11; Tests for(i) { sum = A[i]; for(j) sum += B[j]; A[i+1] = sum; }
12; A[i] to A[i+1] dependency should block unrollandjam
13define void @disabled1(i32 %I, i32 %J, ptr noalias nocapture %A, ptr noalias nocapture readonly %B) #0 {
14; CHECK: %i.029 = phi i32 [ %add10, %for.latch ], [ 0, %for.preheader ]
15; CHECK: %j.026 = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
16entry:
17  %cmp = icmp ne i32 %J, 0
18  %cmp127 = icmp ne i32 %I, 0
19  %or.cond = and i1 %cmp127, %cmp
20  br i1 %or.cond, label %for.preheader, label %return
21
22for.preheader:
23  br label %for.outer
24
25for.outer:
26  %i.029 = phi i32 [ %add10, %for.latch ], [ 0, %for.preheader ]
27  %b.028 = phi i32 [ %inc8, %for.latch ], [ 1, %for.preheader ]
28  %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.029
29  %0 = load i32, ptr %arrayidx, align 4
30  br label %for.inner
31
32for.inner:
33  %j.026 = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
34  %sum1.025 = phi i32 [ %0, %for.outer ], [ %add, %for.inner ]
35  %arrayidx6 = getelementptr inbounds i32, ptr %B, i32 %j.026
36  %1 = load i32, ptr %arrayidx6, align 4
37  %add = add i32 %1, %sum1.025
38  %inc = add nuw i32 %j.026, 1
39  %exitcond = icmp eq i32 %inc, %J
40  br i1 %exitcond, label %for.latch, label %for.inner
41
42for.latch:
43  %arrayidx7 = getelementptr inbounds i32, ptr %A, i32 %b.028
44  store i32 %add, ptr %arrayidx7, align 4
45  %inc8 = add nuw nsw i32 %b.028, 1
46  %add10 = add nuw nsw i32 %i.029, 1
47  %exitcond30 = icmp eq i32 %add10, %I
48  br i1 %exitcond30, label %return, label %for.outer
49
50return:
51  ret void
52}
53
54
55; CHECK-LABEL: disabled2
56; Tests an incompatible block layout (for.outer jumps past for.inner)
57; FIXME: Make this work
58define void @disabled2(i32 %I, i32 %J, ptr noalias nocapture %A, ptr noalias nocapture readonly %B) #0 {
59; CHECK: %i.032 = phi i32 [ %add13, %for.latch ], [ 0, %for.preheader ]
60; CHECK: %j.030 = phi i32 [ %inc, %for.inner ], [ 0, %for.inner.preheader ]
61entry:
62  %cmp = icmp ne i32 %J, 0
63  %cmp131 = icmp ne i32 %I, 0
64  %or.cond = and i1 %cmp131, %cmp
65  br i1 %or.cond, label %for.preheader, label %for.end14
66
67for.preheader:
68  br label %for.outer
69
70for.outer:
71  %i.032 = phi i32 [ %add13, %for.latch ], [ 0, %for.preheader ]
72  %arrayidx = getelementptr inbounds i32, ptr %B, i32 %i.032
73  %0 = load i32, ptr %arrayidx, align 4
74  %tobool = icmp eq i32 %0, 0
75  br i1 %tobool, label %for.latch, label %for.inner
76
77for.inner:
78  %j.030 = phi i32 [ %inc, %for.inner ], [ 0, %for.outer ]
79  %sum1.029 = phi i32 [ %sum1.1, %for.inner ], [ 0, %for.outer ]
80  %arrayidx6 = getelementptr inbounds i32, ptr %B, i32 %j.030
81  %1 = load i32, ptr %arrayidx6, align 4
82  %tobool7 = icmp eq i32 %1, 0
83  %sub = add i32 %sum1.029, 10
84  %add = sub i32 %sub, %1
85  %sum1.1 = select i1 %tobool7, i32 %sum1.029, i32 %add
86  %inc = add nuw i32 %j.030, 1
87  %exitcond = icmp eq i32 %inc, %J
88  br i1 %exitcond, label %for.latch, label %for.inner
89
90for.latch:
91  %sum1.1.lcssa = phi i32 [ 0, %for.outer ], [ %sum1.1, %for.inner ]
92  %arrayidx11 = getelementptr inbounds i32, ptr %A, i32 %i.032
93  store i32 %sum1.1.lcssa, ptr %arrayidx11, align 4
94  %add13 = add nuw i32 %i.032, 1
95  %exitcond33 = icmp eq i32 %add13, %I
96  br i1 %exitcond33, label %for.end14, label %for.outer
97
98for.end14:
99  ret void
100}
101
102
103; CHECK-LABEL: disabled3
104; Tests loop carry dependencies in an array S
105define void @disabled3(i32 %I, i32 %J, ptr noalias nocapture %A, ptr noalias nocapture readonly %B) #0 {
106; CHECK: %i.029 = phi i32 [ 0, %for.preheader ], [ %add12, %for.latch ]
107; CHECK: %j.027 = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
108entry:
109  %S = alloca [4 x i32], align 4
110  %cmp = icmp eq i32 %J, 0
111  br i1 %cmp, label %return, label %if.end
112
113if.end:
114  %cmp128 = icmp eq i32 %I, 0
115  br i1 %cmp128, label %for.cond.cleanup, label %for.preheader
116
117for.preheader:
118  br label %for.outer
119
120for.cond.cleanup:
121  br label %return
122
123for.outer:
124  %i.029 = phi i32 [ 0, %for.preheader ], [ %add12, %for.latch ]
125  br label %for.inner
126
127for.inner:
128  %j.027 = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
129  %arrayidx = getelementptr inbounds i32, ptr %B, i32 %j.027
130  %l2 = load i32, ptr %arrayidx, align 4
131  %add = add i32 %j.027, %i.029
132  %rem = urem i32 %add, %J
133  %arrayidx6 = getelementptr inbounds i32, ptr %B, i32 %rem
134  %l3 = load i32, ptr %arrayidx6, align 4
135  %mul = mul i32 %l3, %l2
136  %rem7 = urem i32 %j.027, 3
137  %arrayidx8 = getelementptr inbounds [4 x i32], ptr %S, i32 0, i32 %rem7
138  store i32 %mul, ptr %arrayidx8, align 4
139  %inc = add nuw i32 %j.027, 1
140  %exitcond = icmp eq i32 %inc, %J
141  br i1 %exitcond, label %for.latch, label %for.inner
142
143for.latch:
144  %l1 = load i32, ptr %S, align 4
145  %arrayidx10 = getelementptr inbounds i32, ptr %A, i32 %i.029
146  store i32 %l1, ptr %arrayidx10, align 4
147  %add12 = add nuw i32 %i.029, 1
148  %exitcond31 = icmp eq i32 %add12, %I
149  br i1 %exitcond31, label %for.cond.cleanup, label %for.outer
150
151return:
152  ret void
153}
154
155
156; CHECK-LABEL: disabled4
157; Inner looop induction variable is not consistent
158; ie for(i = 0..n) for (j = 0..i) sum+=B[j]
159define void @disabled4(i32 %I, i32 %J, ptr noalias nocapture %A, ptr noalias nocapture readonly %B) #0 {
160; CHECK: %indvars.iv = phi i32 [ %indvars.iv.next, %for.latch ], [ 1, %for.preheader ]
161; CHECK: %j.021 = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
162entry:
163  %cmp = icmp ne i32 %J, 0
164  %cmp122 = icmp ugt i32 %I, 1
165  %or.cond = and i1 %cmp122, %cmp
166  br i1 %or.cond, label %for.preheader, label %for.end9
167
168for.preheader:
169  br label %for.outer
170
171for.outer:
172  %indvars.iv = phi i32 [ %indvars.iv.next, %for.latch ], [ 1, %for.preheader ]
173  br label %for.inner
174
175for.inner:
176  %j.021 = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
177  %sum1.020 = phi i32 [ 0, %for.outer ], [ %add, %for.inner ]
178  %arrayidx = getelementptr inbounds i32, ptr %B, i32 %j.021
179  %0 = load i32, ptr %arrayidx, align 4
180  %add = add i32 %0, %sum1.020
181  %inc = add nuw i32 %j.021, 1
182  %exitcond = icmp eq i32 %inc, %indvars.iv
183  br i1 %exitcond, label %for.latch, label %for.inner
184
185for.latch:
186  %arrayidx6 = getelementptr inbounds i32, ptr %A, i32 %indvars.iv
187  store i32 %add, ptr %arrayidx6, align 4
188  %indvars.iv.next = add nuw i32 %indvars.iv, 1
189  %exitcond24 = icmp eq i32 %indvars.iv.next, %I
190  br i1 %exitcond24, label %for.end9, label %for.outer
191
192for.end9:
193  ret void
194}
195
196
197; CHECK-LABEL: disabled5
198; Test odd uses of phi nodes where the outer IV cannot be moved into Fore as it hits a PHI
199@f = hidden global i32 0, align 4
200define i32 @disabled5() #0 {
201; CHECK: %0 = phi i32 [ %f.promoted10, %entry ], [ 2, %for.latch ]
202; CHECK: %1 = phi i32 [ %0, %for.outer ], [ 2, %for.inner ]
203entry:
204  %f.promoted10 = load i32, ptr @f, align 4
205  br label %for.outer
206
207for.outer:
208  %0 = phi i32 [ %f.promoted10, %entry ], [ 2, %for.latch ]
209  %d.018 = phi i16 [ 0, %entry ], [ %odd.lcssa, %for.latch ]
210  %inc5.sink9 = phi i32 [ 2, %entry ], [ %inc5, %for.latch ]
211  br label %for.inner
212
213for.inner:
214  %1 = phi i32 [ %0, %for.outer ], [ 2, %for.inner ]
215  %inc.sink8 = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
216  %inc = add nuw nsw i32 %inc.sink8, 1
217  %exitcond = icmp ne i32 %inc, 7
218  br i1 %exitcond, label %for.inner, label %for.latch
219
220for.latch:
221  %.lcssa = phi i32 [ %1, %for.inner ]
222  %odd.lcssa = phi i16 [ 1, %for.inner ]
223  %inc5 = add nuw nsw i32 %inc5.sink9, 1
224  %exitcond11 = icmp ne i32 %inc5, 7
225  br i1 %exitcond11, label %for.outer, label %for.end
226
227for.end:
228  %.lcssa.lcssa = phi i32 [ %.lcssa, %for.latch ]
229  %inc.lcssa.lcssa = phi i32 [ 7, %for.latch ]
230  ret i32 0
231}
232
233
234; CHECK-LABEL: disabled6
235; There is a dependency in here, between @d and %0 (=@f)
236@d6 = hidden global i16 5, align 2
237@f6 = hidden global ptr @d6, align 4
238define i32 @disabled6() #0 {
239; CHECK: %inc8.sink14.i = phi i16 [ 1, %entry ], [ %inc8.i, %for.cond.cleanup.i ]
240; CHECK: %c.013.i = phi i32 [ 0, %for.body.i ], [ %inc.i, %for.body6.i ]
241entry:
242  store i16 1, ptr @d6, align 2
243  %0 = load ptr, ptr @f6, align 4
244  br label %for.body.i
245
246for.body.i:
247  %inc8.sink14.i = phi i16 [ 1, %entry ], [ %inc8.i, %for.cond.cleanup.i ]
248  %1 = load i16, ptr %0, align 2
249  br label %for.body6.i
250
251for.cond.cleanup.i:
252  %inc8.i = add nuw nsw i16 %inc8.sink14.i, 1
253  store i16 %inc8.i, ptr @d6, align 2
254  %cmp.i = icmp ult i16 %inc8.i, 6
255  br i1 %cmp.i, label %for.body.i, label %test.exit
256
257for.body6.i:
258  %c.013.i = phi i32 [ 0, %for.body.i ], [ %inc.i, %for.body6.i ]
259  %inc.i = add nuw nsw i32 %c.013.i, 1
260  %exitcond.i = icmp eq i32 %inc.i, 7
261  br i1 %exitcond.i, label %for.cond.cleanup.i, label %for.body6.i
262
263test.exit:
264  %conv2.i = sext i16 %1 to i32
265  ret i32 0
266}
267
268
269; CHECK-LABEL: disabled7
270; Has negative output dependency
271define void @disabled7(i32 %I, i32 %J, ptr noalias nocapture %A, ptr noalias nocapture readonly %B) #0 {
272; CHECK: %i.028 = phi i32 [ %add11, %for.cond3.for.cond.cleanup5_crit_edge ], [ 0, %for.body.preheader ]
273; CHECK: %j.026 = phi i32 [ 0, %for.body ], [ %add9, %for.body6 ]
274entry:
275  %cmp = icmp ne i32 %J, 0
276  %cmp127 = icmp ne i32 %I, 0
277  %or.cond = and i1 %cmp127, %cmp
278  br i1 %or.cond, label %for.body.preheader, label %for.end12
279
280for.body.preheader:
281  br label %for.body
282
283for.body:
284  %i.028 = phi i32 [ %add11, %for.cond3.for.cond.cleanup5_crit_edge ], [ 0, %for.body.preheader ]
285  %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.028
286  store i32 0, ptr %arrayidx, align 4
287  %sub = add i32 %i.028, -1
288  %arrayidx2 = getelementptr inbounds i32, ptr %A, i32 %sub
289  store i32 2, ptr %arrayidx2, align 4
290  br label %for.body6
291
292for.cond3.for.cond.cleanup5_crit_edge:
293  store i32 %add, ptr %arrayidx, align 4
294  %add11 = add nuw i32 %i.028, 1
295  %exitcond29 = icmp eq i32 %add11, %I
296  br i1 %exitcond29, label %for.end12, label %for.body
297
298for.body6:
299  %0 = phi i32 [ 0, %for.body ], [ %add, %for.body6 ]
300  %j.026 = phi i32 [ 0, %for.body ], [ %add9, %for.body6 ]
301  %arrayidx7 = getelementptr inbounds i32, ptr %B, i32 %j.026
302  %1 = load i32, ptr %arrayidx7, align 4
303  %add = add i32 %1, %0
304  %add9 = add nuw i32 %j.026, 1
305  %exitcond = icmp eq i32 %add9, %J
306  br i1 %exitcond, label %for.cond3.for.cond.cleanup5_crit_edge, label %for.body6
307
308for.end12:
309  ret void
310}
311
312
313; CHECK-LABEL: disabled8
314; Same as above with an extra outer loop nest
315define void @disabled8(i32 %I, i32 %J, ptr noalias nocapture %A, ptr noalias nocapture readonly %B) #0 {
316; CHECK: %i.036 = phi i32 [ %add15, %for.latch ], [ 0, %for.body ]
317; CHECK: %j.034 = phi i32 [ 0, %for.outer ], [ %add13, %for.inner ]
318entry:
319  %cmp = icmp eq i32 %J, 0
320  %cmp335 = icmp eq i32 %I, 0
321  %or.cond = or i1 %cmp, %cmp335
322  br i1 %or.cond, label %for.end18, label %for.body.preheader
323
324for.body.preheader:
325  br label %for.body
326
327for.body:
328  %x.037 = phi i32 [ %inc, %for.cond.cleanup4 ], [ 0, %for.body.preheader ]
329  br label %for.outer
330
331for.cond.cleanup4:
332  %inc = add nuw nsw i32 %x.037, 1
333  %exitcond40 = icmp eq i32 %inc, 5
334  br i1 %exitcond40, label %for.end18, label %for.body
335
336for.outer:
337  %i.036 = phi i32 [ %add15, %for.latch ], [ 0, %for.body ]
338  %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.036
339  store i32 0, ptr %arrayidx, align 4
340  %sub = add i32 %i.036, -1
341  %arrayidx6 = getelementptr inbounds i32, ptr %A, i32 %sub
342  store i32 2, ptr %arrayidx6, align 4
343  br label %for.inner
344
345for.latch:
346  store i32 %add, ptr %arrayidx, align 4
347  %add15 = add nuw i32 %i.036, 1
348  %exitcond38 = icmp eq i32 %add15, %I
349  br i1 %exitcond38, label %for.cond.cleanup4, label %for.outer
350
351for.inner:
352  %0 = phi i32 [ 0, %for.outer ], [ %add, %for.inner ]
353  %j.034 = phi i32 [ 0, %for.outer ], [ %add13, %for.inner ]
354  %arrayidx11 = getelementptr inbounds i32, ptr %B, i32 %j.034
355  %1 = load i32, ptr %arrayidx11, align 4
356  %add = add i32 %1, %0
357  %add13 = add nuw i32 %j.034, 1
358  %exitcond = icmp eq i32 %add13, %J
359  br i1 %exitcond, label %for.latch, label %for.inner
360
361for.end18:
362  ret void
363}
364
365
366; CHECK-LABEL: disabled9
367; Can't prove alias between A and B
368define void @disabled9(i32 %I, i32 %J, ptr nocapture %A, ptr nocapture readonly %B) #0 {
369; CHECK: %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
370; CHECK: %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
371entry:
372  %cmp = icmp ne i32 %J, 0
373  %cmp122 = icmp ne i32 %I, 0
374  %or.cond = and i1 %cmp, %cmp122
375  br i1 %or.cond, label %for.outer.preheader, label %for.end
376
377for.outer.preheader:
378  br label %for.outer
379
380for.outer:
381  %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
382  br label %for.inner
383
384for.inner:
385  %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
386  %sum1 = phi i32 [ 0, %for.outer ], [ %add, %for.inner ]
387  %arrayidx = getelementptr inbounds i32, ptr %B, i32 %j
388  %0 = load i32, ptr %arrayidx, align 4
389  %add = add i32 %0, %sum1
390  %inc = add nuw i32 %j, 1
391  %exitcond = icmp eq i32 %inc, %J
392  br i1 %exitcond, label %for.latch, label %for.inner
393
394for.latch:
395  %add.lcssa = phi i32 [ %add, %for.inner ]
396  %arrayidx6 = getelementptr inbounds i32, ptr %A, i32 %i
397  store i32 %add.lcssa, ptr %arrayidx6, align 4
398  %add8 = add nuw i32 %i, 1
399  %exitcond25 = icmp eq i32 %add8, %I
400  br i1 %exitcond25, label %for.end.loopexit, label %for.outer
401
402for.end.loopexit:
403  br label %for.end
404
405for.end:
406  ret void
407}
408
409
410; CHECK-LABEL: disable10
411; Simple call
412declare void @f10(i32, i32) #0
413define void @disable10(i32 %I, i32 %J, ptr noalias nocapture %A, ptr noalias nocapture readonly %B) #0 {
414; CHECK: %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
415; CHECK: %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
416entry:
417  %cmp = icmp ne i32 %J, 0
418  %cmp122 = icmp ne i32 %I, 0
419  %or.cond = and i1 %cmp, %cmp122
420  br i1 %or.cond, label %for.outer.preheader, label %for.end
421
422for.outer.preheader:
423  br label %for.outer
424
425for.outer:
426  %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
427  br label %for.inner
428
429for.inner:
430  %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
431  %sum1 = phi i32 [ 0, %for.outer ], [ %add, %for.inner ]
432  %arrayidx = getelementptr inbounds i32, ptr %B, i32 %j
433  %0 = load i32, ptr %arrayidx, align 4
434  %add = add i32 %0, %sum1
435  %inc = add nuw i32 %j, 1
436  %exitcond = icmp eq i32 %inc, %J
437  tail call void @f10(i32 %i, i32 %j) nounwind
438  br i1 %exitcond, label %for.latch, label %for.inner
439
440for.latch:
441  %add.lcssa = phi i32 [ %add, %for.inner ]
442  %arrayidx6 = getelementptr inbounds i32, ptr %A, i32 %i
443  store i32 %add.lcssa, ptr %arrayidx6, align 4
444  %add8 = add nuw i32 %i, 1
445  %exitcond25 = icmp eq i32 %add8, %I
446  br i1 %exitcond25, label %for.end.loopexit, label %for.outer
447
448for.end.loopexit:
449  br label %for.end
450
451for.end:
452  ret void
453}
454
455
456; CHECK-LABEL: disable11
457; volatile
458define void @disable11(i32 %I, i32 %J, ptr noalias nocapture %A, ptr noalias nocapture readonly %B) #0 {
459; CHECK: %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
460; CHECK: %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
461entry:
462  %cmp = icmp ne i32 %J, 0
463  %cmp122 = icmp ne i32 %I, 0
464  %or.cond = and i1 %cmp, %cmp122
465  br i1 %or.cond, label %for.outer.preheader, label %for.end
466
467for.outer.preheader:
468  br label %for.outer
469
470for.outer:
471  %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
472  br label %for.inner
473
474for.inner:
475  %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
476  %sum1 = phi i32 [ 0, %for.outer ], [ %add, %for.inner ]
477  %arrayidx = getelementptr inbounds i32, ptr %B, i32 %j
478  %0 = load volatile i32, ptr %arrayidx, align 4
479  %add = add i32 %0, %sum1
480  %inc = add nuw i32 %j, 1
481  %exitcond = icmp eq i32 %inc, %J
482  br i1 %exitcond, label %for.latch, label %for.inner
483
484for.latch:
485  %add.lcssa = phi i32 [ %add, %for.inner ]
486  %arrayidx6 = getelementptr inbounds i32, ptr %A, i32 %i
487  store i32 %add.lcssa, ptr %arrayidx6, align 4
488  %add8 = add nuw i32 %i, 1
489  %exitcond25 = icmp eq i32 %add8, %I
490  br i1 %exitcond25, label %for.end.loopexit, label %for.outer
491
492for.end.loopexit:
493  br label %for.end
494
495for.end:
496  ret void
497}
498
499
500; CHECK-LABEL: disable12
501; Multiple aft blocks
502define void @disable12(i32 %I, i32 %J, ptr noalias nocapture %A, ptr noalias nocapture readonly %B) #0 {
503; CHECK: %i = phi i32 [ %add8, %for.latch3 ], [ 0, %for.outer.preheader ]
504; CHECK: %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
505entry:
506  %cmp = icmp ne i32 %J, 0
507  %cmp122 = icmp ne i32 %I, 0
508  %or.cond = and i1 %cmp, %cmp122
509  br i1 %or.cond, label %for.outer.preheader, label %for.end
510
511for.outer.preheader:
512  br label %for.outer
513
514for.outer:
515  %i = phi i32 [ %add8, %for.latch3 ], [ 0, %for.outer.preheader ]
516  br label %for.inner
517
518for.inner:
519  %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
520  %sum1 = phi i32 [ 0, %for.outer ], [ %add, %for.inner ]
521  %arrayidx = getelementptr inbounds i32, ptr %B, i32 %j
522  %0 = load i32, ptr %arrayidx, align 4
523  %add = add i32 %0, %sum1
524  %inc = add nuw i32 %j, 1
525  %exitcond = icmp eq i32 %inc, %J
526  br i1 %exitcond, label %for.latch, label %for.inner
527
528for.latch:
529  %add.lcssa = phi i32 [ %add, %for.inner ]
530  %arrayidx6 = getelementptr inbounds i32, ptr %A, i32 %i
531  store i32 %add.lcssa, ptr %arrayidx6, align 4
532  %cmpl = icmp eq i32 %add.lcssa, 10
533  br i1 %cmpl, label %for.latch2, label %for.latch3
534
535for.latch2:
536  br label %for.latch3
537
538for.latch3:
539  %add8 = add nuw i32 %i, 1
540  %exitcond25 = icmp eq i32 %add8, %I
541  br i1 %exitcond25, label %for.end.loopexit, label %for.outer
542
543for.end.loopexit:
544  br label %for.end
545
546for.end:
547  ret void
548}
549
550
551; CHECK-LABEL: disable13
552; Two subloops
553define void @disable13(i32 %I, i32 %J, ptr noalias nocapture %A, ptr noalias nocapture readonly %B) #0 {
554; CHECK: %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
555; CHECK: %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
556; CHECK: %j2 = phi i32 [ %inc2, %for.inner2 ], [ 0, %for.inner2.preheader ]
557entry:
558  %cmp = icmp ne i32 %J, 0
559  %cmp122 = icmp ne i32 %I, 0
560  %or.cond = and i1 %cmp, %cmp122
561  br i1 %or.cond, label %for.outer.preheader, label %for.end
562
563for.outer.preheader:
564  br label %for.outer
565
566for.outer:
567  %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
568  br label %for.inner
569
570for.inner:
571  %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
572  %sum1 = phi i32 [ 0, %for.outer ], [ %add, %for.inner ]
573  %arrayidx = getelementptr inbounds i32, ptr %B, i32 %j
574  %0 = load i32, ptr %arrayidx, align 4
575  %add = add i32 %0, %sum1
576  %inc = add nuw i32 %j, 1
577  %exitcond = icmp eq i32 %inc, %J
578  br i1 %exitcond, label %for.inner2, label %for.inner
579
580for.inner2:
581  %j2 = phi i32 [ 0, %for.inner ], [ %inc2, %for.inner2 ]
582  %sum12 = phi i32 [ 0, %for.inner ], [ %add2, %for.inner2 ]
583  %arrayidx2 = getelementptr inbounds i32, ptr %B, i32 %j2
584  %l0 = load i32, ptr %arrayidx2, align 4
585  %add2 = add i32 %l0, %sum12
586  %inc2 = add nuw i32 %j2, 1
587  %exitcond2 = icmp eq i32 %inc2, %J
588  br i1 %exitcond2, label %for.latch, label %for.inner2
589
590for.latch:
591  %add.lcssa = phi i32 [ %add, %for.inner2 ]
592  %arrayidx6 = getelementptr inbounds i32, ptr %A, i32 %i
593  store i32 %add.lcssa, ptr %arrayidx6, align 4
594  %add8 = add nuw i32 %i, 1
595  %exitcond25 = icmp eq i32 %add8, %I
596  br i1 %exitcond25, label %for.end.loopexit, label %for.outer
597
598for.end.loopexit:
599  br label %for.end
600
601for.end:
602  ret void
603}
604
605
606; CHECK-LABEL: disable14
607; Multiple exits blocks
608define void @disable14(i32 %I, i32 %J, ptr noalias nocapture %A, ptr noalias nocapture readonly %B) #0 {
609; CHECK: %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
610; CHECK: %j = phi i32 [ %inc, %for.inner ], [ 0, %for.inner.preheader ]
611entry:
612  %cmp = icmp ne i32 %J, 0
613  %cmp122 = icmp ne i32 %I, 0
614  %or.cond = and i1 %cmp, %cmp122
615  br i1 %or.cond, label %for.outer.preheader, label %for.end
616
617for.outer.preheader:
618  br label %for.outer
619
620for.outer:
621  %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
622  %add8 = add nuw i32 %i, 1
623  %exitcond23 = icmp eq i32 %add8, %I
624  br i1 %exitcond23, label %for.end.loopexit, label %for.inner
625
626for.inner:
627  %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
628  %sum1 = phi i32 [ 0, %for.outer ], [ %add, %for.inner ]
629  %arrayidx = getelementptr inbounds i32, ptr %B, i32 %j
630  %0 = load i32, ptr %arrayidx, align 4
631  %add = add i32 %0, %sum1
632  %inc = add nuw i32 %j, 1
633  %exitcond = icmp eq i32 %inc, %J
634  br i1 %exitcond, label %for.latch, label %for.inner
635
636for.latch:
637  %add.lcssa = phi i32 [ %add, %for.inner ]
638  %arrayidx6 = getelementptr inbounds i32, ptr %A, i32 %i
639  store i32 %add.lcssa, ptr %arrayidx6, align 4
640  %exitcond25 = icmp eq i32 %add8, %I
641  br i1 %exitcond25, label %for.end.loopexit, label %for.outer
642
643for.end.loopexit:
644  br label %for.end
645
646for.end:
647  ret void
648}
649
650
651; CHECK-LABEL: disable15
652; Latch != exit
653define void @disable15(i32 %I, i32 %J, ptr noalias nocapture %A, ptr noalias nocapture readonly %B) #0 {
654; CHECK: %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
655; CHECK: %j = phi i32 [ %inc, %for.inner ], [ 0, %for.inner.preheader ]
656entry:
657  %cmp = icmp ne i32 %J, 0
658  %cmp122 = icmp ne i32 %I, 0
659  %or.cond = and i1 %cmp, %cmp122
660  br i1 %or.cond, label %for.outer.preheader, label %for.end
661
662for.outer.preheader:
663  br label %for.outer
664
665for.outer:
666  %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
667  %add8 = add nuw i32 %i, 1
668  %exitcond25 = icmp eq i32 %add8, %I
669  br i1 %exitcond25, label %for.end.loopexit, label %for.inner
670
671for.inner:
672  %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
673  %sum1 = phi i32 [ 0, %for.outer ], [ %add, %for.inner ]
674  %arrayidx = getelementptr inbounds i32, ptr %B, i32 %j
675  %0 = load i32, ptr %arrayidx, align 4
676  %add = add i32 %0, %sum1
677  %inc = add nuw i32 %j, 1
678  %exitcond = icmp eq i32 %inc, %J
679  br i1 %exitcond, label %for.latch, label %for.inner
680
681for.latch:
682  %add.lcssa = phi i32 [ %add, %for.inner ]
683  %arrayidx6 = getelementptr inbounds i32, ptr %A, i32 %i
684  store i32 %add.lcssa, ptr %arrayidx6, align 4
685  br label %for.outer
686
687for.end.loopexit:
688  br label %for.end
689
690for.end:
691  ret void
692}
693
694
695; CHECK-LABEL: disable16
696; Cannot move other before inner loop
697define void @disable16(i32 %I, i32 %J, ptr noalias nocapture %A, ptr noalias nocapture readonly %B) #0 {
698; CHECK: %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
699; CHECK: %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
700entry:
701  %cmp = icmp ne i32 %J, 0
702  %cmp122 = icmp ne i32 %I, 0
703  %or.cond = and i1 %cmp, %cmp122
704  br i1 %or.cond, label %for.outer.preheader, label %for.end
705
706for.outer.preheader:
707  br label %for.outer
708
709for.outer:
710  %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
711  %otherphi = phi i32 [ %other, %for.latch ], [ 0, %for.outer.preheader ]
712  br label %for.inner
713
714for.inner:
715  %j = phi i32 [ 0, %for.outer ], [ %inc, %for.inner ]
716  %sum1 = phi i32 [ 0, %for.outer ], [ %add, %for.inner ]
717  %arrayidx = getelementptr inbounds i32, ptr %B, i32 %j
718  %0 = load i32, ptr %arrayidx, align 4
719  %add = add i32 %0, %sum1
720  %inc = add nuw i32 %j, 1
721  %exitcond = icmp eq i32 %inc, %J
722  br i1 %exitcond, label %for.latch, label %for.inner
723
724for.latch:
725  %add.lcssa = phi i32 [ %add, %for.inner ]
726  %arrayidx6 = getelementptr inbounds i32, ptr %A, i32 %i
727  store i32 %add.lcssa, ptr %arrayidx6, align 4
728  %add8 = add nuw i32 %i, 1
729  %exitcond25 = icmp eq i32 %add8, %I
730  %loadarr = getelementptr inbounds i32, ptr %A, i32 %i
731  %load = load i32, ptr %arrayidx6, align 4
732  %other = add i32 %otherphi, %load
733  br i1 %exitcond25, label %for.end.loopexit, label %for.outer
734
735for.end.loopexit:
736  br label %for.end
737
738for.end:
739  ret void
740}
741