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