1 ; RUN: opt < %s -S -loop-unroll -verify-loop-info | FileCheck %s
2 ; RUN: opt < %s -S -passes='require<opt-remark-emit>,unroll,verify<loops>' | FileCheck %s
4 ; Unit tests for LoopInfo::markAsRemoved.
6 declare i1 @check() nounwind
8 ; Ensure that tail->inner is removed and rely on verify-loopinfo to
11 ; CHECK-LABEL: @skiplevelexit(
15 define void @skiplevelexit() nounwind {
23 %iv = phi i32 [ 0, %outer ], [ %inc, %tail ]
25 call zeroext i1 @check()
26 br i1 true, label %outer.backedge, label %tail
29 br i1 false, label %inner, label %exit
38 ; Remove the middle loop of a triply nested loop tree.
39 ; Ensure that only the middle loop is removed and rely on verify-loopinfo to
42 ; CHECK-LABEL: @unloopNested(
45 ; CHECK: br i1 %cmp3, label %if.then, label %if.end
47 ; CHECK: while.end14.i:
48 ; CHECK: br i1 %call15.i, label %if.end.i, label %exit
49 ; Middle loop control should no longer reach %while.cond.
50 ; Now it is the outer loop backedge.
52 ; CHECK: br label %while.cond.outer
53 define void @unloopNested() {
55 br label %while.cond.outer
61 %cmp = call zeroext i1 @check()
62 br i1 %cmp, label %while.body, label %while.end
65 %cmp3 = call zeroext i1 @check()
66 br i1 %cmp3, label %if.then, label %if.end
72 %cmp.i48 = call zeroext i1 @check()
73 br i1 %cmp.i48, label %if.then.i, label %if.else20.i
76 %cmp8.i = call zeroext i1 @check()
77 br i1 %cmp8.i, label %merge, label %if.else.i
83 %cmp25.i = call zeroext i1 @check()
84 br i1 %cmp25.i, label %merge, label %if.else28.i
90 br label %while.cond2.i
93 %cmp.i = call zeroext i1 @check()
94 br i1 %cmp.i, label %while.cond2.backedge.i, label %while.end.i
96 while.cond2.backedge.i:
97 br label %while.cond2.i
100 %cmp1114.i = call zeroext i1 @check()
101 br i1 %cmp1114.i, label %while.body12.lr.ph.i, label %while.end14.i
103 while.body12.lr.ph.i:
104 br label %while.end14.i
107 %call15.i = call zeroext i1 @check()
108 br i1 %call15.i, label %if.end.i, label %exit
111 br label %while.cond2.backedge.i
114 br i1 false, label %while.cond, label %if.else
117 br label %while.cond.outer
126 ; Remove the middle loop of a deeply nested loop tree.
127 ; Ensure that only the middle loop is removed and rely on verify-loopinfo to
130 ; This test must be disabled until trip count computation can be optimized...
131 ; rdar:14038809 [SCEV]: Optimize trip count computation for multi-exit loops.
132 ; CHECKFIXME-LABEL: @unloopDeepNested(
133 ; Inner-inner loop control.
134 ; CHECKFIXME: while.cond.us.i:
135 ; CHECKFIXME: br i1 %cmp.us.i, label %next_data.exit, label %while.body.us.i
136 ; CHECKFIXME: if.then.us.i:
137 ; CHECKFIXME: br label %while.cond.us.i
139 ; CHECKFIXME: if.else.i:
140 ; CHECKFIXME: br label %while.cond.outer.i
141 ; Middle loop control (removed).
142 ; CHECKFIXME: valid_data.exit:
144 ; CHECKFIXME: %cmp = call zeroext i1 @check()
145 ; Outer loop control.
146 ; CHECKFIXME: copy_data.exit:
147 ; CHECKFIXME: br i1 %cmp38, label %if.then39, label %while.cond.outer
148 ; Outer-outer loop tail.
149 ; CHECKFIXME: while.cond.outer.outer.backedge:
150 ; CHECKFIXME: br label %while.cond.outer.outer
151 define void @unloopDeepNested() nounwind {
152 for.cond8.preheader.i:
153 %cmp113.i = call zeroext i1 @check()
154 br i1 %cmp113.i, label %make_data.exit, label %for.body13.lr.ph.i
157 br label %make_data.exit
160 br label %while.cond.outer.outer
162 while.cond.outer.outer:
163 br label %while.cond.outer
169 br label %while.cond.outer.i
172 %tmp192.ph.i = call zeroext i1 @check()
173 br i1 %tmp192.ph.i, label %while.cond.outer.split.us.i, label %while.body.loopexit
175 while.cond.outer.split.us.i:
176 br label %while.cond.us.i
179 %cmp.us.i = call zeroext i1 @check()
180 br i1 %cmp.us.i, label %next_data.exit, label %while.body.us.i
183 %cmp7.us.i = call zeroext i1 @check()
184 br i1 %cmp7.us.i, label %if.then.us.i, label %if.else.i
187 br label %while.cond.us.i
190 br label %while.cond.outer.i
193 %tmp192.ph.i.lcssa28 = call zeroext i1 @check()
194 br i1 %tmp192.ph.i.lcssa28, label %while.end, label %while.body
200 br label %while.cond.i
203 %cmp.i = call zeroext i1 @check()
204 br i1 %cmp.i, label %valid_data.exit, label %while.body.i
207 %cmp7.i = call zeroext i1 @check()
208 br i1 %cmp7.i, label %valid_data.exit, label %if.end.i
211 br label %while.cond.i
214 br i1 true, label %if.then, label %while.cond
217 %cmp = call zeroext i1 @check()
218 br i1 %cmp, label %if.then12, label %if.end
224 %tobool3.i = call zeroext i1 @check()
225 br i1 %tobool3.i, label %copy_data.exit, label %while.body.lr.ph.i
228 br label %copy_data.exit
231 %cmp38 = call zeroext i1 @check()
232 br i1 %cmp38, label %if.then39, label %while.cond.outer
235 %cmp5.i = call zeroext i1 @check()
236 br i1 %cmp5.i, label %while.cond.outer.outer.backedge, label %for.cond8.preheader.i8.thread
238 for.cond8.preheader.i8.thread:
239 br label %while.cond.outer.outer.backedge
241 while.cond.outer.outer.backedge:
242 br label %while.cond.outer.outer
248 ; Remove a nested loop with irreducible control flow.
249 ; Ensure that only the middle loop is removed and rely on verify-loopinfo to
252 ; CHECK-LABEL: @unloopIrreducible(
255 ; CHECK: br label %for.cond103t
256 ; Nested loop (removed).
258 ; CHECK: br label %for.inc163
259 define void @unloopIrreducible() nounwind {
265 %cmp2113 = call zeroext i1 @check()
266 br i1 %cmp2113, label %for.body22.lr.ph, label %for.inc163
278 %cmp424 = call zeroext i1 @check()
279 br i1 %cmp424, label %for.body43.lr.ph, label %for.end93
285 %cmp96 = call zeroext i1 @check()
286 br i1 %cmp96, label %if.then97, label %for.cond103
289 br label %for.cond103t
292 br label %for.cond103
295 %cmp105 = call zeroext i1 @check()
296 br i1 %cmp105, label %for.body106, label %for.end120
299 %cmp108 = call zeroext i1 @check()
300 br i1 %cmp108, label %if.then109, label %for.inc117
306 br label %for.cond103t
312 br i1 false, label %for.body22, label %for.cond15.for.inc163_crit_edge
314 for.cond15.for.inc163_crit_edge:
318 %cmp12 = call zeroext i1 @check()
319 br i1 %cmp12, label %for.body, label %for.end166
326 ; Remove a loop whose exit branches into a sibling loop.
327 ; Ensure that only the loop is removed and rely on verify-loopinfo to
330 ; CHECK-LABEL: @unloopCriticalEdge(
331 ; CHECK: while.cond.outer.i.loopexit.split:
332 ; CHECK: br label %while.body
334 ; CHECK: br label %for.end78
335 define void @unloopCriticalEdge() nounwind {
340 br i1 undef, label %for.body35, label %for.end94
343 br label %while.cond.i.preheader
345 while.cond.i.preheader:
346 br i1 undef, label %while.cond.i.preheader.split, label %while.cond.outer.i.loopexit.split
348 while.cond.i.preheader.split:
349 br label %while.cond.i
352 br i1 true, label %while.cond.i, label %while.cond.outer.i.loopexit
354 while.cond.outer.i.loopexit:
355 br label %while.cond.outer.i.loopexit.split
357 while.cond.outer.i.loopexit.split:
358 br i1 false, label %while.cond.i.preheader, label %Func2.exit
364 br i1 false, label %while.body, label %while.end
370 br i1 undef, label %Proc2.exit, label %for.cond.i.preheader
372 for.cond.i.preheader:
385 ; Test UnloopUpdater::removeBlocksFromAncestors.
387 ; Check that the loop backedge is removed from the middle loop 1699,
388 ; but not the inner loop 1676.
389 ; CHECK: while.body1694:
391 ; CHECK: while.end1699:
392 ; CHECK: br label %sw.default1711
393 define void @removeSubloopBlocks() nounwind {
395 br label %tryagain.outer
397 tryagain.outer: ; preds = %sw.bb304, %entry
400 tryagain: ; preds = %while.end1699, %tryagain.outer
401 br i1 undef, label %sw.bb1669, label %sw.bb304
403 sw.bb304: ; preds = %tryagain
404 br i1 undef, label %return, label %tryagain.outer
406 sw.bb1669: ; preds = %tryagain
407 br i1 undef, label %sw.default1711, label %while.cond1676
409 while.cond1676: ; preds = %while.body1694, %sw.bb1669
410 br i1 undef, label %while.end1699, label %while.body1694
412 while.body1694: ; preds = %while.cond1676
413 br label %while.cond1676
415 while.end1699: ; preds = %while.cond1676
416 br i1 false, label %tryagain, label %sw.default1711
418 sw.default1711: ; preds = %while.end1699, %sw.bb1669, %tryagain
421 defchar: ; preds = %sw.default1711, %sw.bb376
422 br i1 undef, label %if.end2413, label %if.then2368
424 if.then2368: ; preds = %defchar
427 if.end2413: ; preds = %defchar
430 return: ; preds = %sw.bb304
434 ; PR11335: the most deeply nested block should be removed from the outer loop.
435 ; CHECK-LABEL: @removeSubloopBlocks2(
439 define void @removeSubloopBlocks2() nounwind {
441 %tobool.i = icmp ne i32 undef, 0
444 lbl_616.loopexit: ; preds = %for.cond
447 lbl_616: ; preds = %lbl_616.loopexit, %entry
450 for.cond: ; preds = %for.cond3, %lbl_616
451 br i1 false, label %for.cond1.preheader, label %lbl_616.loopexit
453 for.cond1.preheader: ; preds = %for.cond
456 for.cond1.loopexit: ; preds = %for.cond.i
459 for.cond1: ; preds = %for.cond1.loopexit, %for.cond1.preheader
460 br i1 false, label %for.body2, label %for.cond3
462 for.body2: ; preds = %for.cond1
465 for.cond.i: ; preds = %for.cond.i, %for.body2
466 br i1 %tobool.i, label %for.cond.i, label %for.cond1.loopexit
468 for.cond3: ; preds = %for.cond1
469 br i1 false, label %for.cond, label %if.end
471 if.end: ; preds = %for.cond3