|  | ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py | 
|  | ; RUN: opt < %s -S -passes=loop-unroll -verify-loop-info | FileCheck %s | 
|  | ; RUN: opt < %s -S -passes='require<opt-remark-emit>,loop-unroll,verify<loops>' | FileCheck %s | 
|  | ; | 
|  | ; Unit tests for LoopInfo::markAsRemoved. | 
|  |  | 
|  | declare i1 @check() nounwind | 
|  |  | 
|  | ; Ensure that tail->inner is removed and rely on verify-loopinfo to | 
|  | ; check soundness. | 
|  | define void @skiplevelexit() nounwind { | 
|  | ; CHECK-LABEL: @skiplevelexit( | 
|  | ; CHECK-NEXT:  entry: | 
|  | ; CHECK-NEXT:    br label [[OUTER:%.*]] | 
|  | ; CHECK:       outer: | 
|  | ; CHECK-NEXT:    br label [[INNER:%.*]] | 
|  | ; CHECK:       inner: | 
|  | ; CHECK-NEXT:    [[TMP0:%.*]] = call zeroext i1 @check() | 
|  | ; CHECK-NEXT:    br i1 true, label [[OUTER_BACKEDGE:%.*]], label [[TAIL:%.*]] | 
|  | ; CHECK:       tail: | 
|  | ; CHECK-NEXT:    ret void | 
|  | ; CHECK:       outer.backedge: | 
|  | ; CHECK-NEXT:    br label [[OUTER]] | 
|  | ; | 
|  | entry: | 
|  | br label %outer | 
|  |  | 
|  | outer: | 
|  | br label %inner | 
|  |  | 
|  | inner: | 
|  | %iv = phi i32 [ 0, %outer ], [ %inc, %tail ] | 
|  | %inc = add i32 %iv, 1 | 
|  | call zeroext i1 @check() | 
|  | br i1 true, label %outer.backedge, label %tail | 
|  |  | 
|  | tail: | 
|  | br i1 false, label %inner, label %exit | 
|  |  | 
|  | outer.backedge: | 
|  | br label %outer | 
|  |  | 
|  | exit: | 
|  | ret void | 
|  | } | 
|  |  | 
|  | ; Remove the middle loop of a triply nested loop tree. | 
|  | ; Ensure that only the middle loop is removed and rely on verify-loopinfo to | 
|  | ; check soundness. | 
|  | define void @unloopNested() { | 
|  | ; CHECK-LABEL: @unloopNested( | 
|  | ; CHECK-NEXT:  entry: | 
|  | ; CHECK-NEXT:    br label [[WHILE_COND_OUTER:%.*]] | 
|  | ; CHECK:       while.cond.outer: | 
|  | ; CHECK-NEXT:    br label [[WHILE_COND:%.*]] | 
|  | ; CHECK:       while.cond: | 
|  | ; CHECK-NEXT:    [[CMP:%.*]] = call zeroext i1 @check() | 
|  | ; CHECK-NEXT:    br i1 [[CMP]], label [[WHILE_BODY:%.*]], label [[WHILE_END:%.*]] | 
|  | ; CHECK:       while.body: | 
|  | ; CHECK-NEXT:    [[CMP3:%.*]] = call zeroext i1 @check() | 
|  | ; CHECK-NEXT:    br i1 [[CMP3]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] | 
|  | ; CHECK:       if.then: | 
|  | ; CHECK-NEXT:    br label [[RETURN:%.*]] | 
|  | ; CHECK:       if.end: | 
|  | ; CHECK-NEXT:    [[CMP_I48:%.*]] = call zeroext i1 @check() | 
|  | ; CHECK-NEXT:    br i1 [[CMP_I48]], label [[IF_THEN_I:%.*]], label [[IF_ELSE20_I:%.*]] | 
|  | ; CHECK:       if.then.i: | 
|  | ; CHECK-NEXT:    [[CMP8_I:%.*]] = call zeroext i1 @check() | 
|  | ; CHECK-NEXT:    br i1 [[CMP8_I]], label [[MERGE:%.*]], label [[IF_ELSE_I:%.*]] | 
|  | ; CHECK:       if.else.i: | 
|  | ; CHECK-NEXT:    br label [[MERGE]] | 
|  | ; CHECK:       if.else20.i: | 
|  | ; CHECK-NEXT:    [[CMP25_I:%.*]] = call zeroext i1 @check() | 
|  | ; CHECK-NEXT:    br i1 [[CMP25_I]], label [[MERGE]], label [[IF_ELSE28_I:%.*]] | 
|  | ; CHECK:       if.else28.i: | 
|  | ; CHECK-NEXT:    br label [[MERGE]] | 
|  | ; CHECK:       merge: | 
|  | ; CHECK-NEXT:    br label [[WHILE_COND2_I:%.*]] | 
|  | ; CHECK:       while.cond2.i: | 
|  | ; CHECK-NEXT:    [[CMP_I:%.*]] = call zeroext i1 @check() | 
|  | ; CHECK-NEXT:    br i1 [[CMP_I]], label [[WHILE_COND2_BACKEDGE_I:%.*]], label [[WHILE_END_I:%.*]] | 
|  | ; CHECK:       while.cond2.backedge.i: | 
|  | ; CHECK-NEXT:    br label [[WHILE_COND2_I]] | 
|  | ; CHECK:       while.end.i: | 
|  | ; CHECK-NEXT:    [[CMP1114_I:%.*]] = call zeroext i1 @check() | 
|  | ; CHECK-NEXT:    br i1 [[CMP1114_I]], label [[WHILE_BODY12_LR_PH_I:%.*]], label [[WHILE_END14_I:%.*]] | 
|  | ; CHECK:       while.body12.lr.ph.i: | 
|  | ; CHECK-NEXT:    br label [[WHILE_END14_I]] | 
|  | ; CHECK:       while.end14.i: | 
|  | ; CHECK-NEXT:    [[CALL15_I:%.*]] = call zeroext i1 @check() | 
|  | ; CHECK-NEXT:    br i1 [[CALL15_I]], label [[IF_END_I:%.*]], label [[EXIT:%.*]] | 
|  | ; CHECK:       if.end.i: | 
|  | ; CHECK-NEXT:    br label [[WHILE_COND2_BACKEDGE_I]] | 
|  | ; CHECK:       exit: | 
|  | ; CHECK-NEXT:    br label [[WHILE_COND_OUTER]] | 
|  | ; CHECK:       while.end: | 
|  | ; CHECK-NEXT:    br label [[RETURN]] | 
|  | ; CHECK:       return: | 
|  | ; CHECK-NEXT:    ret void | 
|  | ; | 
|  | entry: | 
|  | br label %while.cond.outer | 
|  |  | 
|  | while.cond.outer: | 
|  | br label %while.cond | 
|  |  | 
|  | while.cond: | 
|  | %cmp = call zeroext i1 @check() | 
|  | br i1 %cmp, label %while.body, label %while.end | 
|  |  | 
|  | while.body: | 
|  | %cmp3 = call zeroext i1 @check() | 
|  | br i1 %cmp3, label %if.then, label %if.end | 
|  |  | 
|  | if.then: | 
|  | br label %return | 
|  |  | 
|  | if.end: | 
|  | %cmp.i48 = call zeroext i1 @check() | 
|  | br i1 %cmp.i48, label %if.then.i, label %if.else20.i | 
|  |  | 
|  | if.then.i: | 
|  | %cmp8.i = call zeroext i1 @check() | 
|  | br i1 %cmp8.i, label %merge, label %if.else.i | 
|  |  | 
|  | if.else.i: | 
|  | br label %merge | 
|  |  | 
|  | if.else20.i: | 
|  | %cmp25.i = call zeroext i1 @check() | 
|  | br i1 %cmp25.i, label %merge, label %if.else28.i | 
|  |  | 
|  | if.else28.i: | 
|  | br label %merge | 
|  |  | 
|  | merge: | 
|  | br label %while.cond2.i | 
|  |  | 
|  | while.cond2.i: | 
|  | %cmp.i = call zeroext i1 @check() | 
|  | br i1 %cmp.i, label %while.cond2.backedge.i, label %while.end.i | 
|  |  | 
|  | while.cond2.backedge.i: | 
|  | br label %while.cond2.i | 
|  |  | 
|  | while.end.i: | 
|  | %cmp1114.i = call zeroext i1 @check() | 
|  | br i1 %cmp1114.i, label %while.body12.lr.ph.i, label %while.end14.i | 
|  |  | 
|  | while.body12.lr.ph.i: | 
|  | br label %while.end14.i | 
|  |  | 
|  | while.end14.i: | 
|  | %call15.i = call zeroext i1 @check() | 
|  | br i1 %call15.i, label %if.end.i, label %exit | 
|  |  | 
|  | if.end.i: | 
|  | br label %while.cond2.backedge.i | 
|  |  | 
|  | exit: | 
|  | br i1 false, label %while.cond, label %if.else | 
|  |  | 
|  | if.else: | 
|  | br label %while.cond.outer | 
|  |  | 
|  | while.end: | 
|  | br label %return | 
|  |  | 
|  | return: | 
|  | ret void | 
|  | } | 
|  |  | 
|  | ; Remove the middle loop of a deeply nested loop tree. | 
|  | ; Ensure that only the middle loop is removed and rely on verify-loopinfo to | 
|  | ; check soundness. | 
|  | ; | 
|  | ; This test must be disabled until trip count computation can be optimized... | 
|  | ; rdar:14038809 [SCEV]: Optimize trip count computation for multi-exit loops. | 
|  | define void @unloopDeepNested() nounwind { | 
|  | ; CHECK-LABEL: @unloopDeepNested( | 
|  | ; CHECK-NEXT:  for.cond8.preheader.i: | 
|  | ; CHECK-NEXT:    [[CMP113_I:%.*]] = call zeroext i1 @check() | 
|  | ; CHECK-NEXT:    br i1 [[CMP113_I]], label [[MAKE_DATA_EXIT:%.*]], label [[FOR_BODY13_LR_PH_I:%.*]] | 
|  | ; CHECK:       for.body13.lr.ph.i: | 
|  | ; CHECK-NEXT:    br label [[MAKE_DATA_EXIT]] | 
|  | ; CHECK:       make_data.exit: | 
|  | ; CHECK-NEXT:    br label [[WHILE_COND_OUTER_OUTER:%.*]] | 
|  | ; CHECK:       while.cond.outer.outer: | 
|  | ; CHECK-NEXT:    br label [[WHILE_COND_OUTER:%.*]] | 
|  | ; CHECK:       while.cond.outer: | 
|  | ; CHECK-NEXT:    br label [[WHILE_COND:%.*]] | 
|  | ; CHECK:       while.cond: | 
|  | ; CHECK-NEXT:    br label [[WHILE_COND_OUTER_I:%.*]] | 
|  | ; CHECK:       while.cond.outer.i: | 
|  | ; CHECK-NEXT:    [[TMP192_PH_I:%.*]] = call zeroext i1 @check() | 
|  | ; CHECK-NEXT:    br i1 [[TMP192_PH_I]], label [[WHILE_COND_OUTER_SPLIT_US_I:%.*]], label [[WHILE_BODY_LOOPEXIT:%.*]] | 
|  | ; CHECK:       while.cond.outer.split.us.i: | 
|  | ; CHECK-NEXT:    br label [[WHILE_COND_US_I:%.*]] | 
|  | ; CHECK:       while.cond.us.i: | 
|  | ; CHECK-NEXT:    [[CMP_US_I:%.*]] = call zeroext i1 @check() | 
|  | ; CHECK-NEXT:    br i1 [[CMP_US_I]], label [[NEXT_DATA_EXIT:%.*]], label [[WHILE_BODY_US_I:%.*]] | 
|  | ; CHECK:       while.body.us.i: | 
|  | ; CHECK-NEXT:    [[CMP7_US_I:%.*]] = call zeroext i1 @check() | 
|  | ; CHECK-NEXT:    br i1 [[CMP7_US_I]], label [[IF_THEN_US_I:%.*]], label [[IF_ELSE_I:%.*]] | 
|  | ; CHECK:       if.then.us.i: | 
|  | ; CHECK-NEXT:    br label [[WHILE_COND_US_I]] | 
|  | ; CHECK:       if.else.i: | 
|  | ; CHECK-NEXT:    br label [[WHILE_COND_OUTER_I]] | 
|  | ; CHECK:       next_data.exit: | 
|  | ; CHECK-NEXT:    [[TMP192_PH_I_LCSSA28:%.*]] = call zeroext i1 @check() | 
|  | ; CHECK-NEXT:    br i1 [[TMP192_PH_I_LCSSA28]], label [[WHILE_END:%.*]], label [[WHILE_BODY:%.*]] | 
|  | ; CHECK:       while.body.loopexit: | 
|  | ; CHECK-NEXT:    br label [[WHILE_BODY]] | 
|  | ; CHECK:       while.body: | 
|  | ; CHECK-NEXT:    br label [[WHILE_COND_I:%.*]] | 
|  | ; CHECK:       while.cond.i: | 
|  | ; CHECK-NEXT:    [[CMP_I:%.*]] = call zeroext i1 @check() | 
|  | ; CHECK-NEXT:    br i1 [[CMP_I]], label [[VALID_DATA_EXIT:%.*]], label [[WHILE_BODY_I:%.*]] | 
|  | ; CHECK:       while.body.i: | 
|  | ; CHECK-NEXT:    [[CMP7_I:%.*]] = call zeroext i1 @check() | 
|  | ; CHECK-NEXT:    br i1 [[CMP7_I]], label [[VALID_DATA_EXIT]], label [[IF_END_I:%.*]] | 
|  | ; CHECK:       if.end.i: | 
|  | ; CHECK-NEXT:    br label [[WHILE_COND_I]] | 
|  | ; CHECK:       valid_data.exit: | 
|  | ; CHECK-NEXT:    [[CMP:%.*]] = call zeroext i1 @check() | 
|  | ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN12:%.*]], label [[IF_END:%.*]] | 
|  | ; CHECK:       if.then12: | 
|  | ; CHECK-NEXT:    br label [[IF_END]] | 
|  | ; CHECK:       if.end: | 
|  | ; CHECK-NEXT:    [[TOBOOL3_I:%.*]] = call zeroext i1 @check() | 
|  | ; CHECK-NEXT:    br i1 [[TOBOOL3_I]], label [[COPY_DATA_EXIT:%.*]], label [[WHILE_BODY_LR_PH_I:%.*]] | 
|  | ; CHECK:       while.body.lr.ph.i: | 
|  | ; CHECK-NEXT:    br label [[COPY_DATA_EXIT]] | 
|  | ; CHECK:       copy_data.exit: | 
|  | ; CHECK-NEXT:    [[CMP38:%.*]] = call zeroext i1 @check() | 
|  | ; CHECK-NEXT:    br i1 [[CMP38]], label [[IF_THEN39:%.*]], label [[WHILE_COND_OUTER]] | 
|  | ; CHECK:       if.then39: | 
|  | ; CHECK-NEXT:    [[CMP5_I:%.*]] = call zeroext i1 @check() | 
|  | ; CHECK-NEXT:    br i1 [[CMP5_I]], label [[WHILE_COND_OUTER_OUTER_BACKEDGE:%.*]], label [[FOR_COND8_PREHEADER_I8_THREAD:%.*]] | 
|  | ; CHECK:       for.cond8.preheader.i8.thread: | 
|  | ; CHECK-NEXT:    br label [[WHILE_COND_OUTER_OUTER_BACKEDGE]] | 
|  | ; CHECK:       while.cond.outer.outer.backedge: | 
|  | ; CHECK-NEXT:    br label [[WHILE_COND_OUTER_OUTER]] | 
|  | ; CHECK:       while.end: | 
|  | ; CHECK-NEXT:    ret void | 
|  | ; | 
|  | for.cond8.preheader.i: | 
|  | %cmp113.i = call zeroext i1 @check() | 
|  | br i1 %cmp113.i, label %make_data.exit, label %for.body13.lr.ph.i | 
|  |  | 
|  | for.body13.lr.ph.i: | 
|  | br label %make_data.exit | 
|  |  | 
|  | make_data.exit: | 
|  | br label %while.cond.outer.outer | 
|  |  | 
|  | while.cond.outer.outer: | 
|  | br label %while.cond.outer | 
|  |  | 
|  | while.cond.outer: | 
|  | br label %while.cond | 
|  |  | 
|  | while.cond: | 
|  | br label %while.cond.outer.i | 
|  |  | 
|  | while.cond.outer.i: | 
|  | %tmp192.ph.i = call zeroext i1 @check() | 
|  | br i1 %tmp192.ph.i, label %while.cond.outer.split.us.i, label %while.body.loopexit | 
|  |  | 
|  | while.cond.outer.split.us.i: | 
|  | br label %while.cond.us.i | 
|  |  | 
|  | while.cond.us.i: | 
|  | %cmp.us.i = call zeroext i1 @check() | 
|  | br i1 %cmp.us.i, label %next_data.exit, label %while.body.us.i | 
|  |  | 
|  | while.body.us.i: | 
|  | %cmp7.us.i = call zeroext i1 @check() | 
|  | br i1 %cmp7.us.i, label %if.then.us.i, label %if.else.i | 
|  |  | 
|  | if.then.us.i: | 
|  | br label %while.cond.us.i | 
|  |  | 
|  | if.else.i: | 
|  | br label %while.cond.outer.i | 
|  |  | 
|  | next_data.exit: | 
|  | %tmp192.ph.i.lcssa28 = call zeroext i1 @check() | 
|  | br i1 %tmp192.ph.i.lcssa28, label %while.end, label %while.body | 
|  |  | 
|  | while.body.loopexit: | 
|  | br label %while.body | 
|  |  | 
|  | while.body: | 
|  | br label %while.cond.i | 
|  |  | 
|  | while.cond.i: | 
|  | %cmp.i = call zeroext i1 @check() | 
|  | br i1 %cmp.i, label %valid_data.exit, label %while.body.i | 
|  |  | 
|  | while.body.i: | 
|  | %cmp7.i = call zeroext i1 @check() | 
|  | br i1 %cmp7.i, label %valid_data.exit, label %if.end.i | 
|  |  | 
|  | if.end.i: | 
|  | br label %while.cond.i | 
|  |  | 
|  | valid_data.exit: | 
|  | br i1 true, label %if.then, label %while.cond | 
|  |  | 
|  | if.then: | 
|  | %cmp = call zeroext i1 @check() | 
|  | br i1 %cmp, label %if.then12, label %if.end | 
|  |  | 
|  | if.then12: | 
|  | br label %if.end | 
|  |  | 
|  | if.end: | 
|  | %tobool3.i = call zeroext i1 @check() | 
|  | br i1 %tobool3.i, label %copy_data.exit, label %while.body.lr.ph.i | 
|  |  | 
|  | while.body.lr.ph.i: | 
|  | br label %copy_data.exit | 
|  |  | 
|  | copy_data.exit: | 
|  | %cmp38 = call zeroext i1 @check() | 
|  | br i1 %cmp38, label %if.then39, label %while.cond.outer | 
|  |  | 
|  | if.then39: | 
|  | %cmp5.i = call zeroext i1 @check() | 
|  | br i1 %cmp5.i, label %while.cond.outer.outer.backedge, label %for.cond8.preheader.i8.thread | 
|  |  | 
|  | for.cond8.preheader.i8.thread: | 
|  | br label %while.cond.outer.outer.backedge | 
|  |  | 
|  | while.cond.outer.outer.backedge: | 
|  | br label %while.cond.outer.outer | 
|  |  | 
|  | while.end: | 
|  | ret void | 
|  | } | 
|  |  | 
|  | ; Remove a nested loop with irreducible control flow. | 
|  | ; Ensure that only the middle loop is removed and rely on verify-loopinfo to | 
|  | ; check soundness. | 
|  | define void @unloopIrreducible() nounwind { | 
|  | ; CHECK-LABEL: @unloopIrreducible( | 
|  | ; CHECK-NEXT:  entry: | 
|  | ; CHECK-NEXT:    br label [[FOR_BODY:%.*]] | 
|  | ; CHECK:       for.body: | 
|  | ; CHECK-NEXT:    [[CMP2113:%.*]] = call zeroext i1 @check() | 
|  | ; CHECK-NEXT:    br i1 [[CMP2113]], label [[FOR_BODY22_LR_PH:%.*]], label [[FOR_INC163:%.*]] | 
|  | ; CHECK:       for.body22.lr.ph: | 
|  | ; CHECK-NEXT:    br label [[FOR_BODY22:%.*]] | 
|  | ; CHECK:       for.body22: | 
|  | ; CHECK-NEXT:    br label [[FOR_BODY33:%.*]] | 
|  | ; CHECK:       for.body33: | 
|  | ; CHECK-NEXT:    br label [[FOR_END:%.*]] | 
|  | ; CHECK:       for.end: | 
|  | ; CHECK-NEXT:    [[CMP424:%.*]] = call zeroext i1 @check() | 
|  | ; CHECK-NEXT:    br i1 [[CMP424]], label [[FOR_BODY43_LR_PH:%.*]], label [[FOR_END93:%.*]] | 
|  | ; CHECK:       for.body43.lr.ph: | 
|  | ; CHECK-NEXT:    br label [[FOR_END93]] | 
|  | ; CHECK:       for.end93: | 
|  | ; CHECK-NEXT:    [[CMP96:%.*]] = call zeroext i1 @check() | 
|  | ; CHECK-NEXT:    br i1 [[CMP96]], label [[IF_THEN97:%.*]], label [[FOR_COND103:%.*]] | 
|  | ; CHECK:       if.then97: | 
|  | ; CHECK-NEXT:    br label [[FOR_COND103T:%.*]] | 
|  | ; CHECK:       for.cond103t: | 
|  | ; CHECK-NEXT:    br label [[FOR_COND103]] | 
|  | ; CHECK:       for.cond103: | 
|  | ; CHECK-NEXT:    [[CMP105:%.*]] = call zeroext i1 @check() | 
|  | ; CHECK-NEXT:    br i1 [[CMP105]], label [[FOR_BODY106:%.*]], label [[FOR_END120:%.*]] | 
|  | ; CHECK:       for.body106: | 
|  | ; CHECK-NEXT:    [[CMP108:%.*]] = call zeroext i1 @check() | 
|  | ; CHECK-NEXT:    br i1 [[CMP108]], label [[IF_THEN109:%.*]], label [[FOR_INC117:%.*]] | 
|  | ; CHECK:       if.then109: | 
|  | ; CHECK-NEXT:    br label [[FOR_INC117]] | 
|  | ; CHECK:       for.inc117: | 
|  | ; CHECK-NEXT:    br label [[FOR_COND103T]] | 
|  | ; CHECK:       for.end120: | 
|  | ; CHECK-NEXT:    br label [[FOR_INC159:%.*]] | 
|  | ; CHECK:       for.inc159: | 
|  | ; CHECK-NEXT:    br label [[FOR_INC163]] | 
|  | ; CHECK:       for.inc163: | 
|  | ; CHECK-NEXT:    [[CMP12:%.*]] = call zeroext i1 @check() | 
|  | ; CHECK-NEXT:    br i1 [[CMP12]], label [[FOR_BODY]], label [[FOR_END166:%.*]] | 
|  | ; CHECK:       for.end166: | 
|  | ; CHECK-NEXT:    ret void | 
|  | ; | 
|  | entry: | 
|  | br label %for.body | 
|  |  | 
|  | for.body: | 
|  | %cmp2113 = call zeroext i1 @check() | 
|  | br i1 %cmp2113, label %for.body22.lr.ph, label %for.inc163 | 
|  |  | 
|  | for.body22.lr.ph: | 
|  | br label %for.body22 | 
|  |  | 
|  | for.body22: | 
|  | br label %for.body33 | 
|  |  | 
|  | for.body33: | 
|  | br label %for.end | 
|  |  | 
|  | for.end: | 
|  | %cmp424 = call zeroext i1 @check() | 
|  | br i1 %cmp424, label %for.body43.lr.ph, label %for.end93 | 
|  |  | 
|  | for.body43.lr.ph: | 
|  | br label %for.end93 | 
|  |  | 
|  | for.end93: | 
|  | %cmp96 = call zeroext i1 @check() | 
|  | br i1 %cmp96, label %if.then97, label %for.cond103 | 
|  |  | 
|  | if.then97: | 
|  | br label %for.cond103t | 
|  |  | 
|  | for.cond103t: | 
|  | br label %for.cond103 | 
|  |  | 
|  | for.cond103: | 
|  | %cmp105 = call zeroext i1 @check() | 
|  | br i1 %cmp105, label %for.body106, label %for.end120 | 
|  |  | 
|  | for.body106: | 
|  | %cmp108 = call zeroext i1 @check() | 
|  | br i1 %cmp108, label %if.then109, label %for.inc117 | 
|  |  | 
|  | if.then109: | 
|  | br label %for.inc117 | 
|  |  | 
|  | for.inc117: | 
|  | br label %for.cond103t | 
|  |  | 
|  | for.end120: | 
|  | br label %for.inc159 | 
|  |  | 
|  | for.inc159: | 
|  | br i1 false, label %for.body22, label %for.cond15.for.inc163_crit_edge | 
|  |  | 
|  | for.cond15.for.inc163_crit_edge: | 
|  | br label %for.inc163 | 
|  |  | 
|  | for.inc163: | 
|  | %cmp12 = call zeroext i1 @check() | 
|  | br i1 %cmp12, label %for.body, label %for.end166 | 
|  |  | 
|  | for.end166: | 
|  | ret void | 
|  |  | 
|  | } | 
|  |  | 
|  | ; Remove a loop whose exit branches into a sibling loop. | 
|  | ; Ensure that only the loop is removed and rely on verify-loopinfo to | 
|  | ; check soundness. | 
|  | define void @unloopCriticalEdge(i1 %arg) nounwind { | 
|  | ; CHECK-LABEL: @unloopCriticalEdge( | 
|  | ; CHECK-NEXT:  entry: | 
|  | ; CHECK-NEXT:    br label [[FOR_COND31:%.*]] | 
|  | ; CHECK:       for.cond31: | 
|  | ; CHECK-NEXT:    br i1 false, label [[FOR_BODY35:%.*]], label [[FOR_END94:%.*]] | 
|  | ; CHECK:       for.body35: | 
|  | ; CHECK-NEXT:    br label [[WHILE_COND_I_PREHEADER:%.*]] | 
|  | ; CHECK:       while.cond.i.preheader: | 
|  | ; CHECK-NEXT:    br i1 %arg, label [[WHILE_COND_I_PREHEADER_SPLIT:%.*]], label [[WHILE_COND_OUTER_I_LOOPEXIT_SPLIT:%.*]] | 
|  | ; CHECK:       while.cond.i.preheader.split: | 
|  | ; CHECK-NEXT:    br label [[WHILE_COND_I:%.*]] | 
|  | ; CHECK:       while.cond.i: | 
|  | ; CHECK-NEXT:    br i1 true, label [[WHILE_COND_I]], label [[WHILE_COND_OUTER_I_LOOPEXIT:%.*]] | 
|  | ; CHECK:       while.cond.outer.i.loopexit: | 
|  | ; CHECK-NEXT:    br label [[WHILE_COND_OUTER_I_LOOPEXIT_SPLIT]] | 
|  | ; CHECK:       while.cond.outer.i.loopexit.split: | 
|  | ; CHECK-NEXT:    br label [[WHILE_BODY:%.*]] | 
|  | ; CHECK:       while.body: | 
|  | ; CHECK-NEXT:    br label [[FOR_END78:%.*]] | 
|  | ; CHECK:       for.end78: | 
|  | ; CHECK-NEXT:    br i1 false, label [[PROC2_EXIT:%.*]], label [[FOR_COND_I_PREHEADER:%.*]] | 
|  | ; CHECK:       for.cond.i.preheader: | 
|  | ; CHECK-NEXT:    br label [[FOR_COND_I:%.*]] | 
|  | ; CHECK:       for.cond.i: | 
|  | ; CHECK-NEXT:    br label [[FOR_COND_I]] | 
|  | ; CHECK:       Proc2.exit: | 
|  | ; CHECK-NEXT:    unreachable | 
|  | ; CHECK:       for.end94: | 
|  | ; CHECK-NEXT:    ret void | 
|  | ; | 
|  | entry: | 
|  | br label %for.cond31 | 
|  |  | 
|  | for.cond31: | 
|  | br i1 false, label %for.body35, label %for.end94 | 
|  |  | 
|  | for.body35: | 
|  | br label %while.cond.i.preheader | 
|  |  | 
|  | while.cond.i.preheader: | 
|  | br i1 %arg, label %while.cond.i.preheader.split, label %while.cond.outer.i.loopexit.split | 
|  |  | 
|  | while.cond.i.preheader.split: | 
|  | br label %while.cond.i | 
|  |  | 
|  | while.cond.i: | 
|  | br i1 true, label %while.cond.i, label %while.cond.outer.i.loopexit | 
|  |  | 
|  | while.cond.outer.i.loopexit: | 
|  | br label %while.cond.outer.i.loopexit.split | 
|  |  | 
|  | while.cond.outer.i.loopexit.split: | 
|  | br i1 false, label %while.cond.i.preheader, label %Func2.exit | 
|  |  | 
|  | Func2.exit: | 
|  | br label %while.body | 
|  |  | 
|  | while.body: | 
|  | br i1 false, label %while.body, label %while.end | 
|  |  | 
|  | while.end: | 
|  | br label %for.end78 | 
|  |  | 
|  | for.end78: | 
|  | br i1 false, label %Proc2.exit, label %for.cond.i.preheader | 
|  |  | 
|  | for.cond.i.preheader: | 
|  | br label %for.cond.i | 
|  |  | 
|  | for.cond.i: | 
|  | br label %for.cond.i | 
|  |  | 
|  | Proc2.exit: | 
|  | br label %for.cond31 | 
|  |  | 
|  | for.end94: | 
|  | ret void | 
|  | } | 
|  |  | 
|  | ; Test UnloopUpdater::removeBlocksFromAncestors. | 
|  | ; | 
|  | ; Check that the loop backedge is removed from the middle loop 1699, | 
|  | ; but not the inner loop 1676. | 
|  | define void @removeSubloopBlocks() nounwind { | 
|  | ; CHECK-LABEL: @removeSubloopBlocks( | 
|  | ; CHECK-NEXT:  entry: | 
|  | ; CHECK-NEXT:    br label [[TRYAGAIN_OUTER:%.*]] | 
|  | ; CHECK:       tryagain.outer: | 
|  | ; CHECK-NEXT:    br label [[TRYAGAIN:%.*]] | 
|  | ; CHECK:       tryagain: | 
|  | ; CHECK-NEXT:    br i1 false, label [[SW_BB1669:%.*]], label [[SW_BB304:%.*]] | 
|  | ; CHECK:       sw.bb304: | 
|  | ; CHECK-NEXT:    ret void | 
|  | ; CHECK:       sw.bb1669: | 
|  | ; CHECK-NEXT:    br i1 true, label [[SW_DEFAULT1711:%.*]], label [[WHILE_COND1676_PREHEADER:%.*]] | 
|  | ; CHECK:       while.cond1676.preheader: | 
|  | ; CHECK-NEXT:    br label [[WHILE_COND1676:%.*]] | 
|  | ; CHECK:       while.cond1676: | 
|  | ; CHECK-NEXT:    br i1 true, label [[WHILE_END1699:%.*]], label [[WHILE_BODY1694:%.*]] | 
|  | ; CHECK:       while.body1694: | 
|  | ; CHECK-NEXT:    unreachable | 
|  | ; CHECK:       while.end1699: | 
|  | ; CHECK-NEXT:    br label [[SW_DEFAULT1711]] | 
|  | ; CHECK:       sw.default1711: | 
|  | ; CHECK-NEXT:    br label [[DEFCHAR:%.*]] | 
|  | ; CHECK:       defchar: | 
|  | ; CHECK-NEXT:    br i1 true, label [[IF_END2413:%.*]], label [[IF_THEN2368:%.*]] | 
|  | ; CHECK:       if.then2368: | 
|  | ; CHECK-NEXT:    unreachable | 
|  | ; CHECK:       if.end2413: | 
|  | ; CHECK-NEXT:    unreachable | 
|  | ; | 
|  | entry: | 
|  | br label %tryagain.outer | 
|  |  | 
|  | tryagain.outer:                                   ; preds = %sw.bb304, %entry | 
|  | br label %tryagain | 
|  |  | 
|  | tryagain:                                         ; preds = %while.end1699, %tryagain.outer | 
|  | br i1 false, label %sw.bb1669, label %sw.bb304 | 
|  |  | 
|  | sw.bb304:                                         ; preds = %tryagain | 
|  | br i1 true, label %return, label %tryagain.outer | 
|  |  | 
|  | sw.bb1669:                                        ; preds = %tryagain | 
|  | br i1 true, label %sw.default1711, label %while.cond1676 | 
|  |  | 
|  | while.cond1676:                                   ; preds = %while.body1694, %sw.bb1669 | 
|  | br i1 true, label %while.end1699, label %while.body1694 | 
|  |  | 
|  | while.body1694:                                   ; preds = %while.cond1676 | 
|  | br label %while.cond1676 | 
|  |  | 
|  | while.end1699:                                    ; preds = %while.cond1676 | 
|  | br i1 false, label %tryagain, label %sw.default1711 | 
|  |  | 
|  | sw.default1711:                                   ; preds = %while.end1699, %sw.bb1669, %tryagain | 
|  | br label %defchar | 
|  |  | 
|  | defchar:                                          ; preds = %sw.default1711, %sw.bb376 | 
|  | br i1 true, label %if.end2413, label %if.then2368 | 
|  |  | 
|  | if.then2368:                                      ; preds = %defchar | 
|  | unreachable | 
|  |  | 
|  | if.end2413:                                       ; preds = %defchar | 
|  | unreachable | 
|  |  | 
|  | return:                                           ; preds = %sw.bb304 | 
|  | ret void | 
|  | } | 
|  |  | 
|  | ; PR11335: the most deeply nested block should be removed from the outer loop. | 
|  | define void @removeSubloopBlocks2() nounwind { | 
|  | ; CHECK-LABEL: @removeSubloopBlocks2( | 
|  | ; CHECK-NEXT:  entry: | 
|  | ; CHECK-NEXT:    [[TOBOOL_I:%.*]] = icmp ne i32 undef, 0 | 
|  | ; CHECK-NEXT:    br label [[LBL_616:%.*]] | 
|  | ; CHECK:       lbl_616.loopexit: | 
|  | ; CHECK-NEXT:    br label [[LBL_616]] | 
|  | ; CHECK:       lbl_616: | 
|  | ; CHECK-NEXT:    br label [[FOR_COND:%.*]] | 
|  | ; CHECK:       for.cond: | 
|  | ; CHECK-NEXT:    br i1 false, label [[FOR_COND1_PREHEADER:%.*]], label [[LBL_616_LOOPEXIT:%.*]] | 
|  | ; CHECK:       for.cond1.preheader: | 
|  | ; CHECK-NEXT:    br label [[FOR_COND1:%.*]] | 
|  | ; CHECK:       for.cond1.loopexit: | 
|  | ; CHECK-NEXT:    unreachable | 
|  | ; CHECK:       for.cond1: | 
|  | ; CHECK-NEXT:    br i1 false, label [[FOR_BODY2:%.*]], label [[FOR_COND3:%.*]] | 
|  | ; CHECK:       for.body2: | 
|  | ; CHECK-NEXT:    br label [[FOR_COND_I:%.*]] | 
|  | ; CHECK:       for.cond.i: | 
|  | ; CHECK-NEXT:    br i1 [[TOBOOL_I]], label [[FOR_COND_I]], label [[FOR_COND1_LOOPEXIT:%.*]] | 
|  | ; CHECK:       for.cond3: | 
|  | ; CHECK-NEXT:    ret void | 
|  | ; | 
|  | entry: | 
|  | %tobool.i = icmp ne i32 undef, 0 | 
|  | br label %lbl_616 | 
|  |  | 
|  | lbl_616.loopexit:                                 ; preds = %for.cond | 
|  | br label %lbl_616 | 
|  |  | 
|  | lbl_616:                                          ; preds = %lbl_616.loopexit, %entry | 
|  | br label %for.cond | 
|  |  | 
|  | for.cond:                                         ; preds = %for.cond3, %lbl_616 | 
|  | br i1 false, label %for.cond1.preheader, label %lbl_616.loopexit | 
|  |  | 
|  | for.cond1.preheader:                              ; preds = %for.cond | 
|  | br label %for.cond1 | 
|  |  | 
|  | for.cond1.loopexit:                               ; preds = %for.cond.i | 
|  | br label %for.cond1 | 
|  |  | 
|  | for.cond1:                                        ; preds = %for.cond1.loopexit, %for.cond1.preheader | 
|  | br i1 false, label %for.body2, label %for.cond3 | 
|  |  | 
|  | for.body2:                                        ; preds = %for.cond1 | 
|  | br label %for.cond.i | 
|  |  | 
|  | for.cond.i:                                       ; preds = %for.cond.i, %for.body2 | 
|  | br i1 %tobool.i, label %for.cond.i, label %for.cond1.loopexit | 
|  |  | 
|  | for.cond3:                                        ; preds = %for.cond1 | 
|  | br i1 false, label %for.cond, label %if.end | 
|  |  | 
|  | if.end:                                           ; preds = %for.cond3 | 
|  | ret void | 
|  | } |