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