xref: /llvm-project/llvm/test/Transforms/LoopUnroll/unloop.ll (revision abb9f9fa06ef22be2b0287b9047d5cfed71d91d4)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -S -passes=loop-unroll -verify-loop-info | FileCheck %s
3; RUN: opt < %s -S -passes='require<opt-remark-emit>,loop-unroll,verify<loops>' | FileCheck %s
4;
5; Unit tests for LoopInfo::markAsRemoved.
6
7declare i1 @check() nounwind
8
9; Ensure that tail->inner is removed and rely on verify-loopinfo to
10; check soundness.
11define void @skiplevelexit() nounwind {
12; CHECK-LABEL: @skiplevelexit(
13; CHECK-NEXT:  entry:
14; CHECK-NEXT:    br label [[OUTER:%.*]]
15; CHECK:       outer:
16; CHECK-NEXT:    br label [[INNER:%.*]]
17; CHECK:       inner:
18; CHECK-NEXT:    [[TMP0:%.*]] = call zeroext i1 @check()
19; CHECK-NEXT:    br i1 true, label [[OUTER_BACKEDGE:%.*]], label [[TAIL:%.*]]
20; CHECK:       tail:
21; CHECK-NEXT:    ret void
22; CHECK:       outer.backedge:
23; CHECK-NEXT:    br label [[OUTER]]
24;
25entry:
26  br label %outer
27
28outer:
29  br label %inner
30
31inner:
32  %iv = phi i32 [ 0, %outer ], [ %inc, %tail ]
33  %inc = add i32 %iv, 1
34  call zeroext i1 @check()
35  br i1 true, label %outer.backedge, label %tail
36
37tail:
38  br i1 false, label %inner, label %exit
39
40outer.backedge:
41  br label %outer
42
43exit:
44  ret void
45}
46
47; Remove the middle loop of a triply nested loop tree.
48; Ensure that only the middle loop is removed and rely on verify-loopinfo to
49; check soundness.
50define void @unloopNested() {
51; CHECK-LABEL: @unloopNested(
52; CHECK-NEXT:  entry:
53; CHECK-NEXT:    br label [[WHILE_COND_OUTER:%.*]]
54; CHECK:       while.cond.outer:
55; CHECK-NEXT:    br label [[WHILE_COND:%.*]]
56; CHECK:       while.cond:
57; CHECK-NEXT:    [[CMP:%.*]] = call zeroext i1 @check()
58; CHECK-NEXT:    br i1 [[CMP]], label [[WHILE_BODY:%.*]], label [[WHILE_END:%.*]]
59; CHECK:       while.body:
60; CHECK-NEXT:    [[CMP3:%.*]] = call zeroext i1 @check()
61; CHECK-NEXT:    br i1 [[CMP3]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
62; CHECK:       if.then:
63; CHECK-NEXT:    br label [[RETURN:%.*]]
64; CHECK:       if.end:
65; CHECK-NEXT:    [[CMP_I48:%.*]] = call zeroext i1 @check()
66; CHECK-NEXT:    br i1 [[CMP_I48]], label [[IF_THEN_I:%.*]], label [[IF_ELSE20_I:%.*]]
67; CHECK:       if.then.i:
68; CHECK-NEXT:    [[CMP8_I:%.*]] = call zeroext i1 @check()
69; CHECK-NEXT:    br i1 [[CMP8_I]], label [[MERGE:%.*]], label [[IF_ELSE_I:%.*]]
70; CHECK:       if.else.i:
71; CHECK-NEXT:    br label [[MERGE]]
72; CHECK:       if.else20.i:
73; CHECK-NEXT:    [[CMP25_I:%.*]] = call zeroext i1 @check()
74; CHECK-NEXT:    br i1 [[CMP25_I]], label [[MERGE]], label [[IF_ELSE28_I:%.*]]
75; CHECK:       if.else28.i:
76; CHECK-NEXT:    br label [[MERGE]]
77; CHECK:       merge:
78; CHECK-NEXT:    br label [[WHILE_COND2_I:%.*]]
79; CHECK:       while.cond2.i:
80; CHECK-NEXT:    [[CMP_I:%.*]] = call zeroext i1 @check()
81; CHECK-NEXT:    br i1 [[CMP_I]], label [[WHILE_COND2_BACKEDGE_I:%.*]], label [[WHILE_END_I:%.*]]
82; CHECK:       while.cond2.backedge.i:
83; CHECK-NEXT:    br label [[WHILE_COND2_I]]
84; CHECK:       while.end.i:
85; CHECK-NEXT:    [[CMP1114_I:%.*]] = call zeroext i1 @check()
86; CHECK-NEXT:    br i1 [[CMP1114_I]], label [[WHILE_BODY12_LR_PH_I:%.*]], label [[WHILE_END14_I:%.*]]
87; CHECK:       while.body12.lr.ph.i:
88; CHECK-NEXT:    br label [[WHILE_END14_I]]
89; CHECK:       while.end14.i:
90; CHECK-NEXT:    [[CALL15_I:%.*]] = call zeroext i1 @check()
91; CHECK-NEXT:    br i1 [[CALL15_I]], label [[IF_END_I:%.*]], label [[EXIT:%.*]]
92; CHECK:       if.end.i:
93; CHECK-NEXT:    br label [[WHILE_COND2_BACKEDGE_I]]
94; CHECK:       exit:
95; CHECK-NEXT:    br label [[WHILE_COND_OUTER]]
96; CHECK:       while.end:
97; CHECK-NEXT:    br label [[RETURN]]
98; CHECK:       return:
99; CHECK-NEXT:    ret void
100;
101entry:
102  br label %while.cond.outer
103
104while.cond.outer:
105  br label %while.cond
106
107while.cond:
108  %cmp = call zeroext i1 @check()
109  br i1 %cmp, label %while.body, label %while.end
110
111while.body:
112  %cmp3 = call zeroext i1 @check()
113  br i1 %cmp3, label %if.then, label %if.end
114
115if.then:
116  br label %return
117
118if.end:
119  %cmp.i48 = call zeroext i1 @check()
120  br i1 %cmp.i48, label %if.then.i, label %if.else20.i
121
122if.then.i:
123  %cmp8.i = call zeroext i1 @check()
124  br i1 %cmp8.i, label %merge, label %if.else.i
125
126if.else.i:
127  br label %merge
128
129if.else20.i:
130  %cmp25.i = call zeroext i1 @check()
131  br i1 %cmp25.i, label %merge, label %if.else28.i
132
133if.else28.i:
134  br label %merge
135
136merge:
137  br label %while.cond2.i
138
139while.cond2.i:
140  %cmp.i = call zeroext i1 @check()
141  br i1 %cmp.i, label %while.cond2.backedge.i, label %while.end.i
142
143while.cond2.backedge.i:
144  br label %while.cond2.i
145
146while.end.i:
147  %cmp1114.i = call zeroext i1 @check()
148  br i1 %cmp1114.i, label %while.body12.lr.ph.i, label %while.end14.i
149
150while.body12.lr.ph.i:
151  br label %while.end14.i
152
153while.end14.i:
154  %call15.i = call zeroext i1 @check()
155  br i1 %call15.i, label %if.end.i, label %exit
156
157if.end.i:
158  br label %while.cond2.backedge.i
159
160exit:
161  br i1 false, label %while.cond, label %if.else
162
163if.else:
164  br label %while.cond.outer
165
166while.end:
167  br label %return
168
169return:
170  ret void
171}
172
173; Remove the middle loop of a deeply nested loop tree.
174; Ensure that only the middle loop is removed and rely on verify-loopinfo to
175; check soundness.
176;
177; This test must be disabled until trip count computation can be optimized...
178; rdar:14038809 [SCEV]: Optimize trip count computation for multi-exit loops.
179define void @unloopDeepNested() nounwind {
180; CHECK-LABEL: @unloopDeepNested(
181; CHECK-NEXT:  for.cond8.preheader.i:
182; CHECK-NEXT:    [[CMP113_I:%.*]] = call zeroext i1 @check()
183; CHECK-NEXT:    br i1 [[CMP113_I]], label [[MAKE_DATA_EXIT:%.*]], label [[FOR_BODY13_LR_PH_I:%.*]]
184; CHECK:       for.body13.lr.ph.i:
185; CHECK-NEXT:    br label [[MAKE_DATA_EXIT]]
186; CHECK:       make_data.exit:
187; CHECK-NEXT:    br label [[WHILE_COND_OUTER_OUTER:%.*]]
188; CHECK:       while.cond.outer.outer:
189; CHECK-NEXT:    br label [[WHILE_COND_OUTER:%.*]]
190; CHECK:       while.cond.outer:
191; CHECK-NEXT:    br label [[WHILE_COND:%.*]]
192; CHECK:       while.cond:
193; CHECK-NEXT:    br label [[WHILE_COND_OUTER_I:%.*]]
194; CHECK:       while.cond.outer.i:
195; CHECK-NEXT:    [[TMP192_PH_I:%.*]] = call zeroext i1 @check()
196; CHECK-NEXT:    br i1 [[TMP192_PH_I]], label [[WHILE_COND_OUTER_SPLIT_US_I:%.*]], label [[WHILE_BODY_LOOPEXIT:%.*]]
197; CHECK:       while.cond.outer.split.us.i:
198; CHECK-NEXT:    br label [[WHILE_COND_US_I:%.*]]
199; CHECK:       while.cond.us.i:
200; CHECK-NEXT:    [[CMP_US_I:%.*]] = call zeroext i1 @check()
201; CHECK-NEXT:    br i1 [[CMP_US_I]], label [[NEXT_DATA_EXIT:%.*]], label [[WHILE_BODY_US_I:%.*]]
202; CHECK:       while.body.us.i:
203; CHECK-NEXT:    [[CMP7_US_I:%.*]] = call zeroext i1 @check()
204; CHECK-NEXT:    br i1 [[CMP7_US_I]], label [[IF_THEN_US_I:%.*]], label [[IF_ELSE_I:%.*]]
205; CHECK:       if.then.us.i:
206; CHECK-NEXT:    br label [[WHILE_COND_US_I]]
207; CHECK:       if.else.i:
208; CHECK-NEXT:    br label [[WHILE_COND_OUTER_I]]
209; CHECK:       next_data.exit:
210; CHECK-NEXT:    [[TMP192_PH_I_LCSSA28:%.*]] = call zeroext i1 @check()
211; CHECK-NEXT:    br i1 [[TMP192_PH_I_LCSSA28]], label [[WHILE_END:%.*]], label [[WHILE_BODY:%.*]]
212; CHECK:       while.body.loopexit:
213; CHECK-NEXT:    br label [[WHILE_BODY]]
214; CHECK:       while.body:
215; CHECK-NEXT:    br label [[WHILE_COND_I:%.*]]
216; CHECK:       while.cond.i:
217; CHECK-NEXT:    [[CMP_I:%.*]] = call zeroext i1 @check()
218; CHECK-NEXT:    br i1 [[CMP_I]], label [[VALID_DATA_EXIT:%.*]], label [[WHILE_BODY_I:%.*]]
219; CHECK:       while.body.i:
220; CHECK-NEXT:    [[CMP7_I:%.*]] = call zeroext i1 @check()
221; CHECK-NEXT:    br i1 [[CMP7_I]], label [[VALID_DATA_EXIT]], label [[IF_END_I:%.*]]
222; CHECK:       if.end.i:
223; CHECK-NEXT:    br label [[WHILE_COND_I]]
224; CHECK:       valid_data.exit:
225; CHECK-NEXT:    [[CMP:%.*]] = call zeroext i1 @check()
226; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN12:%.*]], label [[IF_END:%.*]]
227; CHECK:       if.then12:
228; CHECK-NEXT:    br label [[IF_END]]
229; CHECK:       if.end:
230; CHECK-NEXT:    [[TOBOOL3_I:%.*]] = call zeroext i1 @check()
231; CHECK-NEXT:    br i1 [[TOBOOL3_I]], label [[COPY_DATA_EXIT:%.*]], label [[WHILE_BODY_LR_PH_I:%.*]]
232; CHECK:       while.body.lr.ph.i:
233; CHECK-NEXT:    br label [[COPY_DATA_EXIT]]
234; CHECK:       copy_data.exit:
235; CHECK-NEXT:    [[CMP38:%.*]] = call zeroext i1 @check()
236; CHECK-NEXT:    br i1 [[CMP38]], label [[IF_THEN39:%.*]], label [[WHILE_COND_OUTER]]
237; CHECK:       if.then39:
238; CHECK-NEXT:    [[CMP5_I:%.*]] = call zeroext i1 @check()
239; CHECK-NEXT:    br i1 [[CMP5_I]], label [[WHILE_COND_OUTER_OUTER_BACKEDGE:%.*]], label [[FOR_COND8_PREHEADER_I8_THREAD:%.*]]
240; CHECK:       for.cond8.preheader.i8.thread:
241; CHECK-NEXT:    br label [[WHILE_COND_OUTER_OUTER_BACKEDGE]]
242; CHECK:       while.cond.outer.outer.backedge:
243; CHECK-NEXT:    br label [[WHILE_COND_OUTER_OUTER]]
244; CHECK:       while.end:
245; CHECK-NEXT:    ret void
246;
247for.cond8.preheader.i:
248  %cmp113.i = call zeroext i1 @check()
249  br i1 %cmp113.i, label %make_data.exit, label %for.body13.lr.ph.i
250
251for.body13.lr.ph.i:
252  br label %make_data.exit
253
254make_data.exit:
255  br label %while.cond.outer.outer
256
257while.cond.outer.outer:
258  br label %while.cond.outer
259
260while.cond.outer:
261  br label %while.cond
262
263while.cond:
264  br label %while.cond.outer.i
265
266while.cond.outer.i:
267  %tmp192.ph.i = call zeroext i1 @check()
268  br i1 %tmp192.ph.i, label %while.cond.outer.split.us.i, label %while.body.loopexit
269
270while.cond.outer.split.us.i:
271  br label %while.cond.us.i
272
273while.cond.us.i:
274  %cmp.us.i = call zeroext i1 @check()
275  br i1 %cmp.us.i, label %next_data.exit, label %while.body.us.i
276
277while.body.us.i:
278  %cmp7.us.i = call zeroext i1 @check()
279  br i1 %cmp7.us.i, label %if.then.us.i, label %if.else.i
280
281if.then.us.i:
282  br label %while.cond.us.i
283
284if.else.i:
285  br label %while.cond.outer.i
286
287next_data.exit:
288  %tmp192.ph.i.lcssa28 = call zeroext i1 @check()
289  br i1 %tmp192.ph.i.lcssa28, label %while.end, label %while.body
290
291while.body.loopexit:
292  br label %while.body
293
294while.body:
295  br label %while.cond.i
296
297while.cond.i:
298  %cmp.i = call zeroext i1 @check()
299  br i1 %cmp.i, label %valid_data.exit, label %while.body.i
300
301while.body.i:
302  %cmp7.i = call zeroext i1 @check()
303  br i1 %cmp7.i, label %valid_data.exit, label %if.end.i
304
305if.end.i:
306  br label %while.cond.i
307
308valid_data.exit:
309  br i1 true, label %if.then, label %while.cond
310
311if.then:
312  %cmp = call zeroext i1 @check()
313  br i1 %cmp, label %if.then12, label %if.end
314
315if.then12:
316  br label %if.end
317
318if.end:
319  %tobool3.i = call zeroext i1 @check()
320  br i1 %tobool3.i, label %copy_data.exit, label %while.body.lr.ph.i
321
322while.body.lr.ph.i:
323  br label %copy_data.exit
324
325copy_data.exit:
326  %cmp38 = call zeroext i1 @check()
327  br i1 %cmp38, label %if.then39, label %while.cond.outer
328
329if.then39:
330  %cmp5.i = call zeroext i1 @check()
331  br i1 %cmp5.i, label %while.cond.outer.outer.backedge, label %for.cond8.preheader.i8.thread
332
333for.cond8.preheader.i8.thread:
334  br label %while.cond.outer.outer.backedge
335
336while.cond.outer.outer.backedge:
337  br label %while.cond.outer.outer
338
339while.end:
340  ret void
341}
342
343; Remove a nested loop with irreducible control flow.
344; Ensure that only the middle loop is removed and rely on verify-loopinfo to
345; check soundness.
346define void @unloopIrreducible() nounwind {
347; CHECK-LABEL: @unloopIrreducible(
348; CHECK-NEXT:  entry:
349; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
350; CHECK:       for.body:
351; CHECK-NEXT:    [[CMP2113:%.*]] = call zeroext i1 @check()
352; CHECK-NEXT:    br i1 [[CMP2113]], label [[FOR_BODY22_LR_PH:%.*]], label [[FOR_INC163:%.*]]
353; CHECK:       for.body22.lr.ph:
354; CHECK-NEXT:    br label [[FOR_BODY22:%.*]]
355; CHECK:       for.body22:
356; CHECK-NEXT:    br label [[FOR_BODY33:%.*]]
357; CHECK:       for.body33:
358; CHECK-NEXT:    br label [[FOR_END:%.*]]
359; CHECK:       for.end:
360; CHECK-NEXT:    [[CMP424:%.*]] = call zeroext i1 @check()
361; CHECK-NEXT:    br i1 [[CMP424]], label [[FOR_BODY43_LR_PH:%.*]], label [[FOR_END93:%.*]]
362; CHECK:       for.body43.lr.ph:
363; CHECK-NEXT:    br label [[FOR_END93]]
364; CHECK:       for.end93:
365; CHECK-NEXT:    [[CMP96:%.*]] = call zeroext i1 @check()
366; CHECK-NEXT:    br i1 [[CMP96]], label [[IF_THEN97:%.*]], label [[FOR_COND103:%.*]]
367; CHECK:       if.then97:
368; CHECK-NEXT:    br label [[FOR_COND103T:%.*]]
369; CHECK:       for.cond103t:
370; CHECK-NEXT:    br label [[FOR_COND103]]
371; CHECK:       for.cond103:
372; CHECK-NEXT:    [[CMP105:%.*]] = call zeroext i1 @check()
373; CHECK-NEXT:    br i1 [[CMP105]], label [[FOR_BODY106:%.*]], label [[FOR_END120:%.*]]
374; CHECK:       for.body106:
375; CHECK-NEXT:    [[CMP108:%.*]] = call zeroext i1 @check()
376; CHECK-NEXT:    br i1 [[CMP108]], label [[IF_THEN109:%.*]], label [[FOR_INC117:%.*]]
377; CHECK:       if.then109:
378; CHECK-NEXT:    br label [[FOR_INC117]]
379; CHECK:       for.inc117:
380; CHECK-NEXT:    br label [[FOR_COND103T]]
381; CHECK:       for.end120:
382; CHECK-NEXT:    br label [[FOR_INC159:%.*]]
383; CHECK:       for.inc159:
384; CHECK-NEXT:    br label [[FOR_INC163]]
385; CHECK:       for.inc163:
386; CHECK-NEXT:    [[CMP12:%.*]] = call zeroext i1 @check()
387; CHECK-NEXT:    br i1 [[CMP12]], label [[FOR_BODY]], label [[FOR_END166:%.*]]
388; CHECK:       for.end166:
389; CHECK-NEXT:    ret void
390;
391entry:
392  br label %for.body
393
394for.body:
395  %cmp2113 = call zeroext i1 @check()
396  br i1 %cmp2113, label %for.body22.lr.ph, label %for.inc163
397
398for.body22.lr.ph:
399  br label %for.body22
400
401for.body22:
402  br label %for.body33
403
404for.body33:
405  br label %for.end
406
407for.end:
408  %cmp424 = call zeroext i1 @check()
409  br i1 %cmp424, label %for.body43.lr.ph, label %for.end93
410
411for.body43.lr.ph:
412  br label %for.end93
413
414for.end93:
415  %cmp96 = call zeroext i1 @check()
416  br i1 %cmp96, label %if.then97, label %for.cond103
417
418if.then97:
419  br label %for.cond103t
420
421for.cond103t:
422  br label %for.cond103
423
424for.cond103:
425  %cmp105 = call zeroext i1 @check()
426  br i1 %cmp105, label %for.body106, label %for.end120
427
428for.body106:
429  %cmp108 = call zeroext i1 @check()
430  br i1 %cmp108, label %if.then109, label %for.inc117
431
432if.then109:
433  br label %for.inc117
434
435for.inc117:
436  br label %for.cond103t
437
438for.end120:
439  br label %for.inc159
440
441for.inc159:
442  br i1 false, label %for.body22, label %for.cond15.for.inc163_crit_edge
443
444for.cond15.for.inc163_crit_edge:
445  br label %for.inc163
446
447for.inc163:
448  %cmp12 = call zeroext i1 @check()
449  br i1 %cmp12, label %for.body, label %for.end166
450
451for.end166:
452  ret void
453
454}
455
456; Remove a loop whose exit branches into a sibling loop.
457; Ensure that only the loop is removed and rely on verify-loopinfo to
458; check soundness.
459define void @unloopCriticalEdge(i1 %arg) nounwind {
460; CHECK-LABEL: @unloopCriticalEdge(
461; CHECK-NEXT:  entry:
462; CHECK-NEXT:    br label [[FOR_COND31:%.*]]
463; CHECK:       for.cond31:
464; CHECK-NEXT:    br i1 false, label [[FOR_BODY35:%.*]], label [[FOR_END94:%.*]]
465; CHECK:       for.body35:
466; CHECK-NEXT:    br label [[WHILE_COND_I_PREHEADER:%.*]]
467; CHECK:       while.cond.i.preheader:
468; CHECK-NEXT:    br i1 %arg, label [[WHILE_COND_I_PREHEADER_SPLIT:%.*]], label [[WHILE_COND_OUTER_I_LOOPEXIT_SPLIT:%.*]]
469; CHECK:       while.cond.i.preheader.split:
470; CHECK-NEXT:    br label [[WHILE_COND_I:%.*]]
471; CHECK:       while.cond.i:
472; CHECK-NEXT:    br i1 true, label [[WHILE_COND_I]], label [[WHILE_COND_OUTER_I_LOOPEXIT:%.*]]
473; CHECK:       while.cond.outer.i.loopexit:
474; CHECK-NEXT:    br label [[WHILE_COND_OUTER_I_LOOPEXIT_SPLIT]]
475; CHECK:       while.cond.outer.i.loopexit.split:
476; CHECK-NEXT:    br label [[WHILE_BODY:%.*]]
477; CHECK:       while.body:
478; CHECK-NEXT:    br label [[FOR_END78:%.*]]
479; CHECK:       for.end78:
480; CHECK-NEXT:    br i1 false, label [[PROC2_EXIT:%.*]], label [[FOR_COND_I_PREHEADER:%.*]]
481; CHECK:       for.cond.i.preheader:
482; CHECK-NEXT:    br label [[FOR_COND_I:%.*]]
483; CHECK:       for.cond.i:
484; CHECK-NEXT:    br label [[FOR_COND_I]]
485; CHECK:       Proc2.exit:
486; CHECK-NEXT:    unreachable
487; CHECK:       for.end94:
488; CHECK-NEXT:    ret void
489;
490entry:
491  br label %for.cond31
492
493for.cond31:
494  br i1 false, label %for.body35, label %for.end94
495
496for.body35:
497  br label %while.cond.i.preheader
498
499while.cond.i.preheader:
500  br i1 %arg, label %while.cond.i.preheader.split, label %while.cond.outer.i.loopexit.split
501
502while.cond.i.preheader.split:
503  br label %while.cond.i
504
505while.cond.i:
506  br i1 true, label %while.cond.i, label %while.cond.outer.i.loopexit
507
508while.cond.outer.i.loopexit:
509  br label %while.cond.outer.i.loopexit.split
510
511while.cond.outer.i.loopexit.split:
512  br i1 false, label %while.cond.i.preheader, label %Func2.exit
513
514Func2.exit:
515  br label %while.body
516
517while.body:
518  br i1 false, label %while.body, label %while.end
519
520while.end:
521  br label %for.end78
522
523for.end78:
524  br i1 false, label %Proc2.exit, label %for.cond.i.preheader
525
526for.cond.i.preheader:
527  br label %for.cond.i
528
529for.cond.i:
530  br label %for.cond.i
531
532Proc2.exit:
533  br label %for.cond31
534
535for.end94:
536  ret void
537}
538
539; Test UnloopUpdater::removeBlocksFromAncestors.
540;
541; Check that the loop backedge is removed from the middle loop 1699,
542; but not the inner loop 1676.
543define void @removeSubloopBlocks() nounwind {
544; CHECK-LABEL: @removeSubloopBlocks(
545; CHECK-NEXT:  entry:
546; CHECK-NEXT:    br label [[TRYAGAIN_OUTER:%.*]]
547; CHECK:       tryagain.outer:
548; CHECK-NEXT:    br label [[TRYAGAIN:%.*]]
549; CHECK:       tryagain:
550; CHECK-NEXT:    br i1 false, label [[SW_BB1669:%.*]], label [[SW_BB304:%.*]]
551; CHECK:       sw.bb304:
552; CHECK-NEXT:    ret void
553; CHECK:       sw.bb1669:
554; CHECK-NEXT:    br i1 true, label [[SW_DEFAULT1711:%.*]], label [[WHILE_COND1676_PREHEADER:%.*]]
555; CHECK:       while.cond1676.preheader:
556; CHECK-NEXT:    br label [[WHILE_COND1676:%.*]]
557; CHECK:       while.cond1676:
558; CHECK-NEXT:    br i1 true, label [[WHILE_END1699:%.*]], label [[WHILE_BODY1694:%.*]]
559; CHECK:       while.body1694:
560; CHECK-NEXT:    unreachable
561; CHECK:       while.end1699:
562; CHECK-NEXT:    br label [[SW_DEFAULT1711]]
563; CHECK:       sw.default1711:
564; CHECK-NEXT:    br label [[DEFCHAR:%.*]]
565; CHECK:       defchar:
566; CHECK-NEXT:    br i1 true, label [[IF_END2413:%.*]], label [[IF_THEN2368:%.*]]
567; CHECK:       if.then2368:
568; CHECK-NEXT:    unreachable
569; CHECK:       if.end2413:
570; CHECK-NEXT:    unreachable
571;
572entry:
573  br label %tryagain.outer
574
575tryagain.outer:                                   ; preds = %sw.bb304, %entry
576  br label %tryagain
577
578tryagain:                                         ; preds = %while.end1699, %tryagain.outer
579  br i1 false, label %sw.bb1669, label %sw.bb304
580
581sw.bb304:                                         ; preds = %tryagain
582  br i1 true, label %return, label %tryagain.outer
583
584sw.bb1669:                                        ; preds = %tryagain
585  br i1 true, label %sw.default1711, label %while.cond1676
586
587while.cond1676:                                   ; preds = %while.body1694, %sw.bb1669
588  br i1 true, label %while.end1699, label %while.body1694
589
590while.body1694:                                   ; preds = %while.cond1676
591  br label %while.cond1676
592
593while.end1699:                                    ; preds = %while.cond1676
594  br i1 false, label %tryagain, label %sw.default1711
595
596sw.default1711:                                   ; preds = %while.end1699, %sw.bb1669, %tryagain
597  br label %defchar
598
599defchar:                                          ; preds = %sw.default1711, %sw.bb376
600  br i1 true, label %if.end2413, label %if.then2368
601
602if.then2368:                                      ; preds = %defchar
603  unreachable
604
605if.end2413:                                       ; preds = %defchar
606  unreachable
607
608return:                                           ; preds = %sw.bb304
609  ret void
610}
611
612; PR11335: the most deeply nested block should be removed from the outer loop.
613define void @removeSubloopBlocks2() nounwind {
614; CHECK-LABEL: @removeSubloopBlocks2(
615; CHECK-NEXT:  entry:
616; CHECK-NEXT:    [[TOBOOL_I:%.*]] = icmp ne i32 undef, 0
617; CHECK-NEXT:    br label [[LBL_616:%.*]]
618; CHECK:       lbl_616.loopexit:
619; CHECK-NEXT:    br label [[LBL_616]]
620; CHECK:       lbl_616:
621; CHECK-NEXT:    br label [[FOR_COND:%.*]]
622; CHECK:       for.cond:
623; CHECK-NEXT:    br i1 false, label [[FOR_COND1_PREHEADER:%.*]], label [[LBL_616_LOOPEXIT:%.*]]
624; CHECK:       for.cond1.preheader:
625; CHECK-NEXT:    br label [[FOR_COND1:%.*]]
626; CHECK:       for.cond1.loopexit:
627; CHECK-NEXT:    unreachable
628; CHECK:       for.cond1:
629; CHECK-NEXT:    br i1 false, label [[FOR_BODY2:%.*]], label [[FOR_COND3:%.*]]
630; CHECK:       for.body2:
631; CHECK-NEXT:    br label [[FOR_COND_I:%.*]]
632; CHECK:       for.cond.i:
633; CHECK-NEXT:    br i1 [[TOBOOL_I]], label [[FOR_COND_I]], label [[FOR_COND1_LOOPEXIT:%.*]]
634; CHECK:       for.cond3:
635; CHECK-NEXT:    ret void
636;
637entry:
638  %tobool.i = icmp ne i32 undef, 0
639  br label %lbl_616
640
641lbl_616.loopexit:                                 ; preds = %for.cond
642  br label %lbl_616
643
644lbl_616:                                          ; preds = %lbl_616.loopexit, %entry
645  br label %for.cond
646
647for.cond:                                         ; preds = %for.cond3, %lbl_616
648  br i1 false, label %for.cond1.preheader, label %lbl_616.loopexit
649
650for.cond1.preheader:                              ; preds = %for.cond
651  br label %for.cond1
652
653for.cond1.loopexit:                               ; preds = %for.cond.i
654  br label %for.cond1
655
656for.cond1:                                        ; preds = %for.cond1.loopexit, %for.cond1.preheader
657  br i1 false, label %for.body2, label %for.cond3
658
659for.body2:                                        ; preds = %for.cond1
660  br label %for.cond.i
661
662for.cond.i:                                       ; preds = %for.cond.i, %for.body2
663  br i1 %tobool.i, label %for.cond.i, label %for.cond1.loopexit
664
665for.cond3:                                        ; preds = %for.cond1
666  br i1 false, label %for.cond, label %if.end
667
668if.end:                                           ; preds = %for.cond3
669  ret void
670}
671