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
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, 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 ]
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
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
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
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
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, 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 ]
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
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
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
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
103 ; CHECK-LABEL: disabled3
104 ; Tests loop carry dependencies in an array S
105 define 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 ]
109 %S = alloca [4 x i32], align 4
110 %cmp = icmp eq i32 %J, 0
111 br i1 %cmp, label %return, label %if.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
119 %arrayidx9 = getelementptr inbounds [4 x i32], [4 x i32]* %S, i32 0, i32 0
126 %i.029 = phi i32 [ 0, %for.preheader ], [ %add12, %for.latch ]
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
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
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]
161 define 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 ]
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
174 %indvars.iv = phi i32 [ %indvars.iv.next, %for.latch ], [ 1, %for.preheader ]
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
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
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
202 define 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 ]
206 %f.promoted10 = load i32, i32* @f, align 4
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 ]
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
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
230 %.lcssa.lcssa = phi i32 [ %.lcssa, %for.latch ]
231 %inc.lcssa.lcssa = phi i32 [ 7, %for.latch ]
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
240 define 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 ]
244 store i16 1, i16* @d6, align 2
245 %0 = load i16*, i16** @f6, align 4
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
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
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
266 %conv2.i = sext i16 %1 to i32
271 ; CHECK-LABEL: disabled7
272 ; Has negative output dependency
273 define 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 ]
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
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
294 for.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
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
315 ; CHECK-LABEL: disabled8
316 ; Same as above with an extra outer loop nest
317 define 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 ]
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
330 %x.037 = phi i32 [ %inc, %for.cond.cleanup4 ], [ 0, %for.body.preheader ]
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
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
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
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
368 ; CHECK-LABEL: disabled9
369 ; Can't prove alias between A and B
370 define 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 ]
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
383 %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
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
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
412 ; CHECK-LABEL: disable10
414 declare void @f10(i32, i32) #0
415 define 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 ]
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
428 %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
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
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
458 ; CHECK-LABEL: disable11
460 define 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 ]
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
473 %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
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
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
502 ; CHECK-LABEL: disable12
503 ; Multiple aft blocks
504 define 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 ]
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
517 %i = phi i32 [ %add8, %for.latch3 ], [ 0, %for.outer.preheader ]
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
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
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
553 ; CHECK-LABEL: disable13
555 define 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 ]
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
569 %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
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
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
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
608 ; CHECK-LABEL: disable14
609 ; Multiple exits blocks
610 define 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 ]
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
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
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
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
653 ; CHECK-LABEL: disable15
655 define 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 ]
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
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
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
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
697 ; CHECK-LABEL: disable16
698 ; Cannot move other before inner loop
699 define 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 ]
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
712 %i = phi i32 [ %add8, %for.latch ], [ 0, %for.outer.preheader ]
713 %otherphi = phi i32 [ %other, %for.latch ], [ 0, %for.outer.preheader ]
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
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