[rtsan] Add fork/execve interceptors (#117198)
[llvm-project.git] / llvm / test / Transforms / LoopUnrollAndJam / disable.ll
blob170d6d062ce1a893efe19928a30e0fd1d5a3fe75
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
4 target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
6 ;; Common check for all tests. None should be unroll and jammed
7 ; CHECK-NOT: remark: {{.*}} unroll and jammed
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
13 define 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 ]
16 entry:
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
22 for.preheader:
23   br label %for.outer
25 for.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
32 for.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
42 for.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
50 return:
51   ret void
55 ; CHECK-LABEL: disabled2
56 ; Tests an incompatible block layout (for.outer jumps past for.inner)
57 ; FIXME: Make this work
58 define 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 ]
61 entry:
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
67 for.preheader:
68   br label %for.outer
70 for.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
77 for.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
90 for.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
98 for.end14:
99   ret void
103 ; CHECK-LABEL: disabled3
104 ; Tests loop carry dependencies in an array S
105 define 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 ]
108 entry:
109   %S = alloca [4 x i32], align 4
110   %cmp = icmp eq i32 %J, 0
111   br i1 %cmp, label %return, label %if.end
113 if.end:
114   %cmp128 = icmp eq i32 %I, 0
115   br i1 %cmp128, label %for.cond.cleanup, label %for.preheader
117 for.preheader:
118   br label %for.outer
120 for.cond.cleanup:
121   br label %return
123 for.outer:
124   %i.029 = phi i32 [ 0, %for.preheader ], [ %add12, %for.latch ]
125   br label %for.inner
127 for.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
143 for.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
151 return:
152   ret void
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]
159 define 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 ]
162 entry:
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
168 for.preheader:
169   br label %for.outer
171 for.outer:
172   %indvars.iv = phi i32 [ %indvars.iv.next, %for.latch ], [ 1, %for.preheader ]
173   br label %for.inner
175 for.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
185 for.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
192 for.end9:
193   ret void
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
200 define 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 ]
203 entry:
204   %f.promoted10 = load i32, ptr @f, align 4
205   br label %for.outer
207 for.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
213 for.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
220 for.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
227 for.end:
228   %.lcssa.lcssa = phi i32 [ %.lcssa, %for.latch ]
229   %inc.lcssa.lcssa = phi i32 [ 7, %for.latch ]
230   ret i32 0
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
238 define 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 ]
241 entry:
242   store i16 1, ptr @d6, align 2
243   %0 = load ptr, ptr @f6, align 4
244   br label %for.body.i
246 for.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
251 for.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
257 for.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
263 test.exit:
264   %conv2.i = sext i16 %1 to i32
265   ret i32 0
269 ; CHECK-LABEL: disabled7
270 ; Has negative output dependency
271 define 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 ]
274 entry:
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
280 for.body.preheader:
281   br label %for.body
283 for.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
292 for.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
298 for.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
308 for.end12:
309   ret void
313 ; CHECK-LABEL: disabled8
314 ; Same as above with an extra outer loop nest
315 define 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 ]
318 entry:
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
324 for.body.preheader:
325   br label %for.body
327 for.body:
328   %x.037 = phi i32 [ %inc, %for.cond.cleanup4 ], [ 0, %for.body.preheader ]
329   br label %for.outer
331 for.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
336 for.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
345 for.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
351 for.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
361 for.end18:
362   ret void
366 ; CHECK-LABEL: disabled9
367 ; Can't prove alias between A and B
368 define 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 ]
371 entry:
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
377 for.outer.preheader:
378   br label %for.outer
380 for.outer:
381   %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
382   br label %for.inner
384 for.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
394 for.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
402 for.end.loopexit:
403   br label %for.end
405 for.end:
406   ret void
410 ; CHECK-LABEL: disable10
411 ; Simple call
412 declare void @f10(i32, i32) #0
413 define 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 ]
416 entry:
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
422 for.outer.preheader:
423   br label %for.outer
425 for.outer:
426   %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
427   br label %for.inner
429 for.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
440 for.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
448 for.end.loopexit:
449   br label %for.end
451 for.end:
452   ret void
456 ; CHECK-LABEL: disable11
457 ; volatile
458 define 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 ]
461 entry:
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
467 for.outer.preheader:
468   br label %for.outer
470 for.outer:
471   %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
472   br label %for.inner
474 for.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
484 for.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
492 for.end.loopexit:
493   br label %for.end
495 for.end:
496   ret void
500 ; CHECK-LABEL: disable12
501 ; Multiple aft blocks
502 define 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 ]
505 entry:
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
511 for.outer.preheader:
512   br label %for.outer
514 for.outer:
515   %i = phi i32 [ %add8, %for.latch3 ], [ 0, %for.outer.preheader ]
516   br label %for.inner
518 for.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
528 for.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
535 for.latch2:
536   br label %for.latch3
538 for.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
543 for.end.loopexit:
544   br label %for.end
546 for.end:
547   ret void
551 ; CHECK-LABEL: disable13
552 ; Two subloops
553 define 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 ]
557 entry:
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
563 for.outer.preheader:
564   br label %for.outer
566 for.outer:
567   %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
568   br label %for.inner
570 for.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
580 for.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
590 for.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
598 for.end.loopexit:
599   br label %for.end
601 for.end:
602   ret void
606 ; CHECK-LABEL: disable14
607 ; Multiple exits blocks
608 define 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 ]
611 entry:
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
617 for.outer.preheader:
618   br label %for.outer
620 for.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
626 for.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
636 for.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
643 for.end.loopexit:
644   br label %for.end
646 for.end:
647   ret void
651 ; CHECK-LABEL: disable15
652 ; Latch != exit
653 define 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 ]
656 entry:
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
662 for.outer.preheader:
663   br label %for.outer
665 for.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
671 for.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
681 for.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
687 for.end.loopexit:
688   br label %for.end
690 for.end:
691   ret void
695 ; CHECK-LABEL: disable16
696 ; Cannot move other before inner loop
697 define 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 ]
700 entry:
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
706 for.outer.preheader:
707   br label %for.outer
709 for.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
714 for.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
724 for.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
735 for.end.loopexit:
736   br label %for.end
738 for.end:
739   ret void