LowerSwitch: Avoid inserting NewDefault block
authorRuiling Song <ruiling.song@amd.com>
Tue, 12 Apr 2022 03:25:33 +0000 (11:25 +0800)
committerRuiling Song <ruiling.song@amd.com>
Thu, 14 Apr 2022 05:30:56 +0000 (13:30 +0800)
The NewDefault was used to simplify the updating of PHI nodes, but it
causes some inefficiency for target that will run structurizer later. For
example, for a simple two-case switch, the extra NewDefault is causing
unstructured CFG like:

        O
       / \
      O   O
     / \ / \
    C1  ND C2
     \  |  /
      \ | /
        D

The change is to avoid the ND(NewDefault) block, that is we will get a
structured CFG for above example like:

        O
       / \
      /   \
     O     O
    / \   / \
   C1  \ /  C2
    \-> D <-/

The IR change introduced by this patch should be trivial to other targets,
so I am doing this unconditionally.

Fall-through among the cases will also cause unstructured CFG, but it need
more work and will be addressed in a separate change.

Reviewed by: arsenm

Differential Revision: https://reviews.llvm.org/D123607

llvm/lib/Transforms/Utils/LowerSwitch.cpp
llvm/test/CodeGen/AMDGPU/multilevel-break.ll
llvm/test/Transforms/FixIrreducible/switch.ll
llvm/test/Transforms/LowerSwitch/2014-06-23-PHIlowering.ll
llvm/test/Transforms/LowerSwitch/do-not-handle-impossible-values.ll
llvm/test/Transforms/LowerSwitch/feature.ll
llvm/test/Transforms/StructurizeCFG/interleaved-loop-order.ll
llvm/test/Transforms/UnifyLoopExits/switch.ll
llvm/test/Transforms/Util/lowerswitch.ll

index aff9d13..44aeb26 100644 (file)
@@ -119,25 +119,27 @@ raw_ostream &operator<<(raw_ostream &O, const CaseVector &C) {
 void FixPhis(
     BasicBlock *SuccBB, BasicBlock *OrigBB, BasicBlock *NewBB,
     const unsigned NumMergedCases = std::numeric_limits<unsigned>::max()) {
-  for (BasicBlock::iterator I = SuccBB->begin(),
-                            IE = SuccBB->getFirstNonPHI()->getIterator();
-       I != IE; ++I) {
-    PHINode *PN = cast<PHINode>(I);
+  for (auto &I : SuccBB->phis()) {
+    PHINode *PN = cast<PHINode>(&I);
 
-    // Only update the first occurrence.
+    // Only update the first occurrence if NewBB exists.
     unsigned Idx = 0, E = PN->getNumIncomingValues();
     unsigned LocalNumMergedCases = NumMergedCases;
-    for (; Idx != E; ++Idx) {
+    for (; Idx != E && NewBB; ++Idx) {
       if (PN->getIncomingBlock(Idx) == OrigBB) {
         PN->setIncomingBlock(Idx, NewBB);
         break;
       }
     }
 
+    // Skip the updated incoming block so that it will not be removed.
+    if (NewBB)
+      ++Idx;
+
     // Remove additional occurrences coming from condensed cases and keep the
     // number of incoming values equal to the number of branches to SuccBB.
     SmallVector<unsigned, 8> Indices;
-    for (++Idx; LocalNumMergedCases > 0 && Idx < E; ++Idx)
+    for (; LocalNumMergedCases > 0 && Idx < E; ++Idx)
       if (PN->getIncomingBlock(Idx) == OrigBB) {
         Indices.push_back(Idx);
         LocalNumMergedCases--;
@@ -195,6 +197,13 @@ BasicBlock *NewLeafBlock(CaseRange &Leaf, Value *Val, ConstantInt *LowerBound,
   BasicBlock *Succ = Leaf.BB;
   BranchInst::Create(Succ, Default, Comp, NewLeaf);
 
+  // Update the PHI incoming value/block for the default.
+  for (auto &I : Default->phis()) {
+    PHINode *PN = cast<PHINode>(&I);
+    auto *V = PN->getIncomingValueForBlock(OrigBlock);
+    PN->addIncoming(V, NewLeaf);
+  }
+
   // If there were any PHI nodes in this successor, rewrite one entry
   // from OrigBlock to come from NewLeaf.
   for (BasicBlock::iterator I = Succ->begin(); isa<PHINode>(I); ++I) {
@@ -494,19 +503,17 @@ void ProcessSwitchInst(SwitchInst *SI,
     Val = SI->getCondition();
   }
 
-  // Create a new, empty default block so that the new hierarchy of
-  // if-then statements go to this and the PHI nodes are happy.
-  BasicBlock *NewDefault = BasicBlock::Create(SI->getContext(), "NewDefault");
-  F->getBasicBlockList().insert(Default->getIterator(), NewDefault);
-  BranchInst::Create(Default, NewDefault);
-
   BasicBlock *SwitchBlock =
       SwitchConvert(Cases.begin(), Cases.end(), LowerBound, UpperBound, Val,
-                    OrigBlock, OrigBlock, NewDefault, UnreachableRanges);
-
-  // If there are entries in any PHI nodes for the default edge, make sure
-  // to update them as well.
-  FixPhis(Default, OrigBlock, NewDefault);
+                    OrigBlock, OrigBlock, Default, UnreachableRanges);
+
+  // We have added incoming values for newly-created predecessors in
+  // NewLeafBlock(). The only meaningful work we offload to FixPhis() is to
+  // remove the incoming values from OrigBlock. There might be a special case
+  // that SwitchBlock is the same as Default, under which the PHIs in Default
+  // are fixed inside SwitchConvert().
+  if (SwitchBlock != Default)
+    FixPhis(Default, OrigBlock, nullptr);
 
   // Branch to our shiny new if-then stuff...
   BranchInst::Create(SwitchBlock, OrigBlock);
index b4fe0ec..bf757bd 100644 (file)
@@ -116,7 +116,7 @@ define amdgpu_kernel void @multi_if_break_loop(i32 %arg) #0 {
 ; OPT-NEXT:    [[TMP:%.*]] = sub i32 [[ID]], [[ARG:%.*]]
 ; OPT-NEXT:    br label [[BB1:%.*]]
 ; OPT:       bb1:
-; OPT-NEXT:    [[PHI_BROKEN:%.*]] = phi i64 [ [[TMP4:%.*]], [[FLOW4:%.*]] ], [ 0, [[BB:%.*]] ]
+; OPT-NEXT:    [[PHI_BROKEN:%.*]] = phi i64 [ [[TMP2:%.*]], [[FLOW4:%.*]] ], [ 0, [[BB:%.*]] ]
 ; OPT-NEXT:    [[LSR_IV:%.*]] = phi i32 [ undef, [[BB]] ], [ [[LSR_IV_NEXT:%.*]], [[FLOW4]] ]
 ; OPT-NEXT:    [[LSR_IV_NEXT]] = add i32 [[LSR_IV]], 1
 ; OPT-NEXT:    [[CMP0:%.*]] = icmp slt i32 [[LSR_IV_NEXT]], 0
@@ -130,44 +130,32 @@ define amdgpu_kernel void @multi_if_break_loop(i32 %arg) #0 {
 ; OPT-NEXT:    br i1 [[SWITCHLEAF2]], label [[CASE1:%.*]], label [[FLOW3:%.*]]
 ; OPT:       Flow3:
 ; OPT-NEXT:    [[TMP0:%.*]] = phi i1 [ [[CMP2:%.*]], [[CASE1]] ], [ true, [[LEAFBLOCK1]] ]
-; OPT-NEXT:    [[TMP1:%.*]] = phi i1 [ false, [[CASE1]] ], [ true, [[LEAFBLOCK1]] ]
 ; OPT-NEXT:    br label [[FLOW]]
 ; OPT:       LeafBlock:
 ; OPT-NEXT:    [[SWITCHLEAF:%.*]] = icmp eq i32 [[LOAD0]], 0
 ; OPT-NEXT:    br i1 [[SWITCHLEAF]], label [[CASE0:%.*]], label [[FLOW5:%.*]]
 ; OPT:       Flow4:
-; OPT-NEXT:    [[TMP2:%.*]] = phi i1 [ [[TMP9:%.*]], [[FLOW5]] ], [ [[TMP6:%.*]], [[FLOW]] ]
-; OPT-NEXT:    [[TMP3:%.*]] = phi i1 [ [[TMP10:%.*]], [[FLOW5]] ], [ [[TMP7:%.*]], [[FLOW]] ]
-; OPT-NEXT:    [[TMP4]] = call i64 @llvm.amdgcn.if.break.i64(i1 [[TMP2]], i64 [[PHI_BROKEN]])
-; OPT-NEXT:    [[TMP5:%.*]] = call i1 @llvm.amdgcn.loop.i64(i64 [[TMP4]])
-; OPT-NEXT:    br i1 [[TMP5]], label [[FLOW6:%.*]], label [[BB1]]
+; OPT-NEXT:    [[TMP1:%.*]] = phi i1 [ [[TMP6:%.*]], [[FLOW5]] ], [ [[TMP4:%.*]], [[FLOW]] ]
+; OPT-NEXT:    [[TMP2]] = call i64 @llvm.amdgcn.if.break.i64(i1 [[TMP1]], i64 [[PHI_BROKEN]])
+; OPT-NEXT:    [[TMP3:%.*]] = call i1 @llvm.amdgcn.loop.i64(i64 [[TMP2]])
+; OPT-NEXT:    br i1 [[TMP3]], label [[BB9:%.*]], label [[BB1]]
 ; OPT:       case0:
 ; OPT-NEXT:    [[LOAD1:%.*]] = load volatile i32, i32 addrspace(1)* undef, align 4
 ; OPT-NEXT:    [[CMP1:%.*]] = icmp sge i32 [[TMP]], [[LOAD1]]
 ; OPT-NEXT:    br label [[FLOW5]]
 ; OPT:       Flow:
-; OPT-NEXT:    [[TMP6]] = phi i1 [ [[TMP0]], [[FLOW3]] ], [ true, [[NODEBLOCK]] ]
-; OPT-NEXT:    [[TMP7]] = phi i1 [ [[TMP1]], [[FLOW3]] ], [ false, [[NODEBLOCK]] ]
-; OPT-NEXT:    [[TMP8:%.*]] = phi i1 [ false, [[FLOW3]] ], [ true, [[NODEBLOCK]] ]
-; OPT-NEXT:    br i1 [[TMP8]], label [[LEAFBLOCK:%.*]], label [[FLOW4]]
+; OPT-NEXT:    [[TMP4]] = phi i1 [ [[TMP0]], [[FLOW3]] ], [ true, [[NODEBLOCK]] ]
+; OPT-NEXT:    [[TMP5:%.*]] = phi i1 [ false, [[FLOW3]] ], [ true, [[NODEBLOCK]] ]
+; OPT-NEXT:    br i1 [[TMP5]], label [[LEAFBLOCK:%.*]], label [[FLOW4]]
 ; OPT:       case1:
 ; OPT-NEXT:    [[LOAD2:%.*]] = load volatile i32, i32 addrspace(1)* undef, align 4
 ; OPT-NEXT:    [[CMP2]] = icmp sge i32 [[TMP]], [[LOAD2]]
 ; OPT-NEXT:    br label [[FLOW3]]
 ; OPT:       Flow5:
-; OPT-NEXT:    [[TMP9]] = phi i1 [ [[CMP1]], [[CASE0]] ], [ [[TMP6]], [[LEAFBLOCK]] ]
-; OPT-NEXT:    [[TMP10]] = phi i1 [ false, [[CASE0]] ], [ true, [[LEAFBLOCK]] ]
+; OPT-NEXT:    [[TMP6]] = phi i1 [ [[CMP1]], [[CASE0]] ], [ [[TMP4]], [[LEAFBLOCK]] ]
 ; OPT-NEXT:    br label [[FLOW4]]
-; OPT:       Flow6:
-; OPT-NEXT:    call void @llvm.amdgcn.end.cf.i64(i64 [[TMP4]])
-; OPT-NEXT:    [[TMP11:%.*]] = call { i1, i64 } @llvm.amdgcn.if.i64(i1 [[TMP3]])
-; OPT-NEXT:    [[TMP12:%.*]] = extractvalue { i1, i64 } [[TMP11]], 0
-; OPT-NEXT:    [[TMP13:%.*]] = extractvalue { i1, i64 } [[TMP11]], 1
-; OPT-NEXT:    br i1 [[TMP12]], label [[NEWDEFAULT:%.*]], label [[BB9:%.*]]
-; OPT:       NewDefault:
-; OPT-NEXT:    br label [[BB9]]
 ; OPT:       bb9:
-; OPT-NEXT:    call void @llvm.amdgcn.end.cf.i64(i64 [[TMP13]])
+; OPT-NEXT:    call void @llvm.amdgcn.end.cf.i64(i64 [[TMP2]])
 ; OPT-NEXT:    ret void
 ;
 ; GCN-LABEL: multi_if_break_loop:
@@ -178,65 +166,53 @@ define amdgpu_kernel void @multi_if_break_loop(i32 %arg) #0 {
 ; GCN-NEXT:    s_waitcnt lgkmcnt(0)
 ; GCN-NEXT:    v_subrev_i32_e32 v0, vcc, s2, v0
 ; GCN-NEXT:    s_mov_b32 s2, -1
-; GCN-NEXT:    ; implicit-def: $sgpr4_sgpr5
 ; GCN-NEXT:    s_branch .LBB1_2
 ; GCN-NEXT:  .LBB1_1: ; %Flow4
 ; GCN-NEXT:    ; in Loop: Header=BB1_2 Depth=1
-; GCN-NEXT:    s_and_b64 s[6:7], exec, s[6:7]
-; GCN-NEXT:    s_or_b64 s[0:1], s[6:7], s[0:1]
-; GCN-NEXT:    s_andn2_b64 s[4:5], s[4:5], exec
-; GCN-NEXT:    s_and_b64 s[6:7], s[8:9], exec
-; GCN-NEXT:    s_or_b64 s[4:5], s[4:5], s[6:7]
+; GCN-NEXT:    s_and_b64 s[4:5], exec, s[4:5]
+; GCN-NEXT:    s_or_b64 s[0:1], s[4:5], s[0:1]
 ; GCN-NEXT:    s_andn2_b64 exec, exec, s[0:1]
 ; GCN-NEXT:    s_cbranch_execz .LBB1_9
 ; GCN-NEXT:  .LBB1_2: ; %bb1
 ; GCN-NEXT:    ; =>This Inner Loop Header: Depth=1
 ; GCN-NEXT:    buffer_load_dword v1, off, s[0:3], 0 glc
 ; GCN-NEXT:    s_waitcnt vmcnt(0)
-; GCN-NEXT:    s_mov_b64 s[6:7], -1
+; GCN-NEXT:    s_mov_b64 s[4:5], -1
 ; GCN-NEXT:    v_cmp_gt_i32_e32 vcc, 1, v1
-; GCN-NEXT:    ; implicit-def: $sgpr8_sgpr9
-; GCN-NEXT:    s_mov_b64 s[10:11], -1
+; GCN-NEXT:    s_mov_b64 s[6:7], -1
 ; GCN-NEXT:    s_cbranch_vccnz .LBB1_6
 ; GCN-NEXT:  ; %bb.3: ; %LeafBlock1
 ; GCN-NEXT:    ; in Loop: Header=BB1_2 Depth=1
-; GCN-NEXT:    s_mov_b64 s[6:7], -1
 ; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 1, v1
-; GCN-NEXT:    s_mov_b64 s[8:9], -1
+; GCN-NEXT:    s_mov_b64 s[4:5], -1
 ; GCN-NEXT:    s_cbranch_vccz .LBB1_5
 ; GCN-NEXT:  ; %bb.4: ; %case1
 ; GCN-NEXT:    ; in Loop: Header=BB1_2 Depth=1
 ; GCN-NEXT:    buffer_load_dword v2, off, s[0:3], 0 glc
 ; GCN-NEXT:    s_waitcnt vmcnt(0)
 ; GCN-NEXT:    v_cmp_ge_i32_e32 vcc, v0, v2
-; GCN-NEXT:    s_mov_b64 s[8:9], 0
-; GCN-NEXT:    s_orn2_b64 s[6:7], vcc, exec
+; GCN-NEXT:    s_orn2_b64 s[4:5], vcc, exec
 ; GCN-NEXT:  .LBB1_5: ; %Flow3
 ; GCN-NEXT:    ; in Loop: Header=BB1_2 Depth=1
-; GCN-NEXT:    s_mov_b64 s[10:11], 0
+; GCN-NEXT:    s_mov_b64 s[6:7], 0
 ; GCN-NEXT:  .LBB1_6: ; %Flow
 ; GCN-NEXT:    ; in Loop: Header=BB1_2 Depth=1
-; GCN-NEXT:    s_and_b64 vcc, exec, s[10:11]
+; GCN-NEXT:    s_and_b64 vcc, exec, s[6:7]
 ; GCN-NEXT:    s_cbranch_vccz .LBB1_1
 ; GCN-NEXT:  ; %bb.7: ; %LeafBlock
 ; GCN-NEXT:    ; in Loop: Header=BB1_2 Depth=1
 ; GCN-NEXT:    v_cmp_eq_u32_e32 vcc, 0, v1
-; GCN-NEXT:    s_mov_b64 s[8:9], -1
 ; GCN-NEXT:    s_cbranch_vccz .LBB1_1
 ; GCN-NEXT:  ; %bb.8: ; %case0
 ; GCN-NEXT:    ; in Loop: Header=BB1_2 Depth=1
 ; GCN-NEXT:    buffer_load_dword v1, off, s[0:3], 0 glc
 ; GCN-NEXT:    s_waitcnt vmcnt(0)
-; GCN-NEXT:    s_mov_b64 s[8:9], 0
 ; GCN-NEXT:    v_cmp_ge_i32_e32 vcc, v0, v1
-; GCN-NEXT:    s_andn2_b64 s[6:7], s[6:7], exec
-; GCN-NEXT:    s_and_b64 s[10:11], vcc, exec
-; GCN-NEXT:    s_or_b64 s[6:7], s[6:7], s[10:11]
+; GCN-NEXT:    s_andn2_b64 s[4:5], s[4:5], exec
+; GCN-NEXT:    s_and_b64 s[6:7], vcc, exec
+; GCN-NEXT:    s_or_b64 s[4:5], s[4:5], s[6:7]
 ; GCN-NEXT:    s_branch .LBB1_1
-; GCN-NEXT:  .LBB1_9: ; %loop.exit.guard
-; GCN-NEXT:    s_or_b64 exec, exec, s[0:1]
-; GCN-NEXT:    s_and_saveexec_b64 s[0:1], s[4:5]
-; GCN-NEXT:    s_xor_b64 s[0:1], exec, s[0:1]
+; GCN-NEXT:  .LBB1_9: ; %bb9
 ; GCN-NEXT:    s_endpgm
 bb:
   %id = call i32 @llvm.amdgcn.workitem.id.x()
index a906d04..f7a00a2 100644 (file)
@@ -14,12 +14,10 @@ define void @loop_1(i32 %Value, i1 %PredEntry, i1 %PredD) {
 ; CHECK-NEXT:    br i1 [[PIVOT]], label [[LEAFBLOCK:%.*]], label [[LEAFBLOCK1:%.*]]
 ; CHECK:       LeafBlock1:
 ; CHECK-NEXT:    [[SWITCHLEAF2:%.*]] = icmp eq i32 [[VALUE]], 1
-; CHECK-NEXT:    br i1 [[SWITCHLEAF2]], label [[IRR_GUARD]], label [[NEWDEFAULT:%.*]]
+; CHECK-NEXT:    br i1 [[SWITCHLEAF2]], label [[IRR_GUARD]], label [[EXIT:%.*]]
 ; CHECK:       LeafBlock:
 ; CHECK-NEXT:    [[SWITCHLEAF:%.*]] = icmp eq i32 [[VALUE]], 0
-; CHECK-NEXT:    br i1 [[SWITCHLEAF]], label [[IRR_GUARD]], label [[NEWDEFAULT]]
-; CHECK:       NewDefault:
-; CHECK-NEXT:    br label [[EXIT:%.*]]
+; CHECK-NEXT:    br i1 [[SWITCHLEAF]], label [[IRR_GUARD]], label [[EXIT]]
 ; CHECK:       exit:
 ; CHECK-NEXT:    ret void
 ; CHECK:       irr.guard:
index 24f1d3a..27c1e52 100644 (file)
@@ -6,7 +6,7 @@ define i32 @test(i32 %arg) #0 {
 ; CHECK-NEXT:  %res.0 = phi i32 [ 1, %NodeBlock ], [ 2, %1 ]
 ; CHECK-NEXT:  br label %3
 ; CHECK: 5:
-; CHECK-NEXT:   %res.3 = phi i32 [ 0, %NewDefault ], [ %res.2, %4 ]
+; CHECK-NEXT:   %res.3 = phi i32 [ %res.2, %4 ], [ 0, %LeafBlock ], [ 0, %LeafBlock1 ]
 ; CHECK-NEXT:   %6 = add nsw i32 %res.3, 1
 ; CHECK-NEXT:   ret i32 %6
 
index 71c1ec7..0deab42 100644 (file)
@@ -13,15 +13,13 @@ define i32 @test1(i32 %val) {
 ; CHECK-NEXT:    br i1 [[PIVOT]], label [[LEAFBLOCK:%.*]], label [[CASE_1:%.*]]
 ; CHECK:       LeafBlock:
 ; CHECK-NEXT:    [[SWITCHLEAF:%.*]] = icmp eq i2 [[TRUNC]], -2
-; CHECK-NEXT:    br i1 [[SWITCHLEAF]], label [[CASE_2:%.*]], label [[NEWDEFAULT:%.*]]
+; CHECK-NEXT:    br i1 [[SWITCHLEAF]], label [[CASE_2:%.*]], label [[CASE_D:%.*]]
 ; CHECK:       case.1:
 ; CHECK-NEXT:    [[RES1:%.*]] = call i32 @case1()
 ; CHECK-NEXT:    br label [[EXIT:%.*]]
 ; CHECK:       case.2:
 ; CHECK-NEXT:    [[RES2:%.*]] = call i32 @case2()
 ; CHECK-NEXT:    br label [[EXIT]]
-; CHECK:       NewDefault:
-; CHECK-NEXT:    br label [[CASE_D:%.*]]
 ; CHECK:       case.D:
 ; CHECK-NEXT:    [[RESD:%.*]] = call i32 @caseD()
 ; CHECK-NEXT:    br label [[EXIT]]
@@ -59,22 +57,20 @@ exit:
 define i32 @test2() {
 ; CHECK-LABEL: @test2(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[VAL:%.*]] = call i32 @getVal(), !range !0
+; CHECK-NEXT:    [[VAL:%.*]] = call i32 @getVal(), !range [[RNG0:![0-9]+]]
 ; CHECK-NEXT:    br label [[NODEBLOCK:%.*]]
 ; CHECK:       NodeBlock:
 ; CHECK-NEXT:    [[PIVOT:%.*]] = icmp slt i32 [[VAL]], 2
 ; CHECK-NEXT:    br i1 [[PIVOT]], label [[CASE_1:%.*]], label [[LEAFBLOCK:%.*]]
 ; CHECK:       LeafBlock:
 ; CHECK-NEXT:    [[SWITCHLEAF:%.*]] = icmp eq i32 [[VAL]], 2
-; CHECK-NEXT:    br i1 [[SWITCHLEAF]], label [[CASE_2:%.*]], label [[NEWDEFAULT:%.*]]
+; CHECK-NEXT:    br i1 [[SWITCHLEAF]], label [[CASE_2:%.*]], label [[CASE_D:%.*]]
 ; CHECK:       case.1:
 ; CHECK-NEXT:    [[RES1:%.*]] = call i32 @case1()
 ; CHECK-NEXT:    br label [[EXIT:%.*]]
 ; CHECK:       case.2:
 ; CHECK-NEXT:    [[RES2:%.*]] = call i32 @case2()
 ; CHECK-NEXT:    br label [[EXIT]]
-; CHECK:       NewDefault:
-; CHECK-NEXT:    br label [[CASE_D:%.*]]
 ; CHECK:       case.D:
 ; CHECK-NEXT:    [[RESD:%.*]] = call i32 @caseD()
 ; CHECK-NEXT:    br label [[EXIT]]
@@ -113,13 +109,11 @@ exit:
 define i32 @test3() {
 ; CHECK-LABEL: @test3(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[VAL:%.*]] = call i32 @getVal(), !range !1
+; CHECK-NEXT:    [[VAL:%.*]] = call i32 @getVal(), !range [[RNG1:![0-9]+]]
 ; CHECK-NEXT:    br label [[LEAFBLOCK:%.*]]
 ; CHECK:       LeafBlock:
 ; CHECK-NEXT:    [[SWITCHLEAF:%.*]] = icmp eq i32 [[VAL]], 2
-; CHECK-NEXT:    br i1 [[SWITCHLEAF]], label [[CASE_2:%.*]], label [[NEWDEFAULT:%.*]]
-; CHECK:       NewDefault:
-; CHECK-NEXT:    br label [[CASE_1:%.*]]
+; CHECK-NEXT:    br i1 [[SWITCHLEAF]], label [[CASE_2:%.*]], label [[CASE_1:%.*]]
 ; CHECK:       case.1:
 ; CHECK-NEXT:    [[RES1:%.*]] = call i32 @case1()
 ; CHECK-NEXT:    br label [[EXIT:%.*]]
@@ -162,22 +156,20 @@ exit:
 define i32 @test4() {
 ; CHECK-LABEL: @test4(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[VAL:%.*]] = call i32 @getVal(), !range !2
+; CHECK-NEXT:    [[VAL:%.*]] = call i32 @getVal(), !range [[RNG2:![0-9]+]]
 ; CHECK-NEXT:    br label [[NODEBLOCK:%.*]]
 ; CHECK:       NodeBlock:
 ; CHECK-NEXT:    [[PIVOT:%.*]] = icmp slt i32 [[VAL]], 2
 ; CHECK-NEXT:    br i1 [[PIVOT]], label [[CASE_1:%.*]], label [[LEAFBLOCK:%.*]]
 ; CHECK:       LeafBlock:
 ; CHECK-NEXT:    [[SWITCHLEAF:%.*]] = icmp eq i32 [[VAL]], 2
-; CHECK-NEXT:    br i1 [[SWITCHLEAF]], label [[CASE_2:%.*]], label [[NEWDEFAULT:%.*]]
+; CHECK-NEXT:    br i1 [[SWITCHLEAF]], label [[CASE_2:%.*]], label [[CASE_D:%.*]]
 ; CHECK:       case.1:
 ; CHECK-NEXT:    [[RES1:%.*]] = call i32 @case1()
 ; CHECK-NEXT:    br label [[EXIT:%.*]]
 ; CHECK:       case.2:
 ; CHECK-NEXT:    [[RES2:%.*]] = call i32 @case2()
 ; CHECK-NEXT:    br label [[EXIT]]
-; CHECK:       NewDefault:
-; CHECK-NEXT:    br label [[CASE_D:%.*]]
 ; CHECK:       case.D:
 ; CHECK-NEXT:    [[RESD:%.*]] = call i32 @caseD()
 ; CHECK-NEXT:    br label [[EXIT]]
@@ -219,21 +211,19 @@ define i32 @test5(i1 %cond) {
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[SWITCH:%.*]], label [[CASE_D:%.*]]
 ; CHECK:       switch:
-; CHECK-NEXT:    [[VAL:%.*]] = call i32 @getVal(), !range !1
+; CHECK-NEXT:    [[VAL:%.*]] = call i32 @getVal(), !range [[RNG1]]
 ; CHECK-NEXT:    br label [[NODEBLOCK:%.*]]
 ; CHECK:       NodeBlock:
 ; CHECK-NEXT:    [[PIVOT:%.*]] = icmp slt i32 [[VAL]], 3
 ; CHECK-NEXT:    br i1 [[PIVOT]], label [[LEAFBLOCK:%.*]], label [[CASE_1:%.*]]
 ; CHECK:       LeafBlock:
 ; CHECK-NEXT:    [[SWITCHLEAF:%.*]] = icmp eq i32 [[VAL]], 1
-; CHECK-NEXT:    br i1 [[SWITCHLEAF]], label [[CASE_1]], label [[NEWDEFAULT:%.*]]
+; CHECK-NEXT:    br i1 [[SWITCHLEAF]], label [[CASE_1]], label [[CASE_D]]
 ; CHECK:       case.1:
 ; CHECK-NEXT:    [[RES1:%.*]] = call i32 @case1()
 ; CHECK-NEXT:    br label [[EXIT:%.*]]
-; CHECK:       NewDefault:
-; CHECK-NEXT:    br label [[CASE_D]]
 ; CHECK:       case.D:
-; CHECK-NEXT:    [[DELTA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 20, [[NEWDEFAULT]] ]
+; CHECK-NEXT:    [[DELTA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 20, [[LEAFBLOCK]] ]
 ; CHECK-NEXT:    [[RESD_TMP:%.*]] = call i32 @caseD()
 ; CHECK-NEXT:    [[RESD:%.*]] = add i32 [[RESD_TMP]], [[DELTA]]
 ; CHECK-NEXT:    br label [[EXIT]]
@@ -277,13 +267,11 @@ define i32 @test6(i1 %cond) {
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[SWITCH:%.*]], label [[CASE_D:%.*]]
 ; CHECK:       switch:
-; CHECK-NEXT:    [[VAL:%.*]] = call i32 @getVal(), !range !1
+; CHECK-NEXT:    [[VAL:%.*]] = call i32 @getVal(), !range [[RNG1]]
 ; CHECK-NEXT:    br label [[LEAFBLOCK:%.*]]
 ; CHECK:       LeafBlock:
 ; CHECK-NEXT:    [[SWITCHLEAF:%.*]] = icmp eq i32 [[VAL]], 2
-; CHECK-NEXT:    br i1 [[SWITCHLEAF]], label [[CASE_2:%.*]], label [[NEWDEFAULT:%.*]]
-; CHECK:       NewDefault:
-; CHECK-NEXT:    br label [[CASE_1:%.*]]
+; CHECK-NEXT:    br i1 [[SWITCHLEAF]], label [[CASE_2:%.*]], label [[CASE_1:%.*]]
 ; CHECK:       case.1:
 ; CHECK-NEXT:    [[RES1:%.*]] = call i32 @case1()
 ; CHECK-NEXT:    br label [[EXIT:%.*]]
@@ -336,7 +324,7 @@ define i32 @test7(i1 %cond) {
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[SWITCH:%.*]], label [[CASE_D:%.*]]
 ; CHECK:       switch:
-; CHECK-NEXT:    [[VAL:%.*]] = call i32 @getVal(), !range !1
+; CHECK-NEXT:    [[VAL:%.*]] = call i32 @getVal(), !range [[RNG1]]
 ; CHECK-NEXT:    br label [[CASE_D]]
 ; CHECK:       case.D:
 ; CHECK-NEXT:    [[DELTA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 20, [[SWITCH]] ]
@@ -378,13 +366,11 @@ define i32 @test8(i1 %cond) {
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[SWITCH:%.*]], label [[CASE_D:%.*]]
 ; CHECK:       switch:
-; CHECK-NEXT:    [[VAL:%.*]] = call i32 @getVal(), !range !3
+; CHECK-NEXT:    [[VAL:%.*]] = call i32 @getVal(), !range [[RNG3:![0-9]+]]
 ; CHECK-NEXT:    br label [[LEAFBLOCK:%.*]]
 ; CHECK:       LeafBlock:
 ; CHECK-NEXT:    [[SWITCHLEAF:%.*]] = icmp eq i32 [[VAL]], 2
-; CHECK-NEXT:    br i1 [[SWITCHLEAF]], label [[CASE_2:%.*]], label [[NEWDEFAULT:%.*]]
-; CHECK:       NewDefault:
-; CHECK-NEXT:    br label [[CASE_1:%.*]]
+; CHECK-NEXT:    br i1 [[SWITCHLEAF]], label [[CASE_2:%.*]], label [[CASE_1:%.*]]
 ; CHECK:       case.1:
 ; CHECK-NEXT:    [[RES1:%.*]] = call i32 @case1()
 ; CHECK-NEXT:    br label [[EXIT:%.*]]
@@ -441,14 +427,12 @@ define i32 @test9(i1 %cond, i2 %val) {
 ; CHECK-NEXT:    br label [[LEAFBLOCK:%.*]]
 ; CHECK:       LeafBlock:
 ; CHECK-NEXT:    [[SWITCHLEAF:%.*]] = icmp sge i2 [[VAL:%.*]], 0
-; CHECK-NEXT:    br i1 [[SWITCHLEAF]], label [[CASE_1:%.*]], label [[NEWDEFAULT:%.*]]
+; CHECK-NEXT:    br i1 [[SWITCHLEAF]], label [[CASE_1:%.*]], label [[CASE_D]]
 ; CHECK:       case.1:
 ; CHECK-NEXT:    [[RES1:%.*]] = call i32 @case1()
 ; CHECK-NEXT:    br label [[EXIT:%.*]]
-; CHECK:       NewDefault:
-; CHECK-NEXT:    br label [[CASE_D]]
 ; CHECK:       case.D:
-; CHECK-NEXT:    [[DELTA:%.*]] = phi i32 [ 20, [[NEWDEFAULT]] ], [ 0, [[ENTRY:%.*]] ]
+; CHECK-NEXT:    [[DELTA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 20, [[LEAFBLOCK]] ]
 ; CHECK-NEXT:    [[RESD_TMP:%.*]] = call i32 @caseD()
 ; CHECK-NEXT:    [[RESD:%.*]] = add i32 [[RESD_TMP]], [[DELTA]]
 ; CHECK-NEXT:    br label [[EXIT]]
@@ -497,9 +481,7 @@ define i32 @test10() {
 ; CHECK:       LeafBlock:
 ; CHECK-NEXT:    [[VAL_OFF:%.*]] = add i32 [[VAL]], -3
 ; CHECK-NEXT:    [[SWITCHLEAF:%.*]] = icmp ule i32 [[VAL_OFF]], 1
-; CHECK-NEXT:    br i1 [[SWITCHLEAF]], label [[CASE_2:%.*]], label [[NEWDEFAULT:%.*]]
-; CHECK:       NewDefault:
-; CHECK-NEXT:    br label [[CASE_1:%.*]]
+; CHECK-NEXT:    br i1 [[SWITCHLEAF]], label [[CASE_2:%.*]], label [[CASE_1:%.*]]
 ; CHECK:       case.1:
 ; CHECK-NEXT:    [[RES1:%.*]] = call i32 @case1()
 ; CHECK-NEXT:    br label [[EXIT:%.*]]
@@ -560,15 +542,13 @@ define i32 @test11() {
 ; CHECK-NEXT:    br i1 [[PIVOT]], label [[CASE_1:%.*]], label [[LEAFBLOCK:%.*]]
 ; CHECK:       LeafBlock:
 ; CHECK-NEXT:    [[SWITCHLEAF:%.*]] = icmp eq i64 [[VAL_ZEXT]], 1
-; CHECK-NEXT:    br i1 [[SWITCHLEAF]], label [[CASE_2:%.*]], label [[NEWDEFAULT:%.*]]
+; CHECK-NEXT:    br i1 [[SWITCHLEAF]], label [[CASE_2:%.*]], label [[CASE_D:%.*]]
 ; CHECK:       case.1:
 ; CHECK-NEXT:    [[RES1:%.*]] = call i32 @case1()
 ; CHECK-NEXT:    br label [[EXIT:%.*]]
 ; CHECK:       case.2:
 ; CHECK-NEXT:    [[RES2:%.*]] = call i32 @case2()
 ; CHECK-NEXT:    br label [[EXIT]]
-; CHECK:       NewDefault:
-; CHECK-NEXT:    br label [[CASE_D:%.*]]
 ; CHECK:       case.D:
 ; CHECK-NEXT:    [[RESD:%.*]] = call i32 @caseD()
 ; CHECK-NEXT:    br label [[EXIT]]
@@ -616,13 +596,11 @@ define void @test12() {
 ; CHECK-NEXT:    br i1 [[PIVOT]], label [[CASE_1:%.*]], label [[LEAFBLOCK:%.*]]
 ; CHECK:       LeafBlock:
 ; CHECK-NEXT:    [[SWITCHLEAF:%.*]] = icmp eq i32 [[INDVAR]], 1
-; CHECK-NEXT:    br i1 [[SWITCHLEAF]], label [[CASE_2:%.*]], label [[NEWDEFAULT:%.*]]
+; CHECK-NEXT:    br i1 [[SWITCHLEAF]], label [[CASE_2:%.*]], label [[LATCH]]
 ; CHECK:       case.1:
 ; CHECK-NEXT:    br label [[LATCH]]
 ; CHECK:       case.2:
 ; CHECK-NEXT:    br label [[LATCH]]
-; CHECK:       NewDefault:
-; CHECK-NEXT:    br label [[LATCH]]
 ; CHECK:       latch:
 ; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[INDVAR]], 1
 ; CHECK-NEXT:    br i1 undef, label [[EXIT:%.*]], label [[FOR_BODY]]
@@ -666,23 +644,19 @@ define void @test13(i32 %val) {
 ; CHECK:       LeafBlock:
 ; CHECK-NEXT:    [[TMP_OFF:%.*]] = add i32 [[TMP]], -2
 ; CHECK-NEXT:    [[SWITCHLEAF:%.*]] = icmp ule i32 [[TMP_OFF]], 1
-; CHECK-NEXT:    br i1 [[SWITCHLEAF]], label [[BB34:%.*]], label [[NEWDEFAULT:%.*]]
+; CHECK-NEXT:    br i1 [[SWITCHLEAF]], label [[BB34:%.*]], label [[BB35:%.*]]
 ; CHECK:       bb34:
 ; CHECK-NEXT:    br label [[BB38:%.*]]
-; CHECK:       NewDefault:
-; CHECK-NEXT:    br label [[BB35:%.*]]
 ; CHECK:       bb35:
 ; CHECK-NEXT:    br label [[NODEBLOCK:%.*]]
 ; CHECK:       NodeBlock:
 ; CHECK-NEXT:    [[PIVOT:%.*]] = icmp slt i32 [[TMP]], 6
-; CHECK-NEXT:    br i1 [[PIVOT]], label [[LEAFBLOCK2:%.*]], label [[BB37:%.*]]
-; CHECK:       LeafBlock2:
-; CHECK-NEXT:    [[SWITCHLEAF3:%.*]] = icmp sle i32 [[TMP]], 1
-; CHECK-NEXT:    br i1 [[SWITCHLEAF3]], label [[BB37]], label [[NEWDEFAULT1:%.*]]
+; CHECK-NEXT:    br i1 [[PIVOT]], label [[LEAFBLOCK1:%.*]], label [[BB37:%.*]]
+; CHECK:       LeafBlock1:
+; CHECK-NEXT:    [[SWITCHLEAF2:%.*]] = icmp sle i32 [[TMP]], 1
+; CHECK-NEXT:    br i1 [[SWITCHLEAF2]], label [[BB37]], label [[BB38]]
 ; CHECK:       bb37:
 ; CHECK-NEXT:    br label [[BB38]]
-; CHECK:       NewDefault1:
-; CHECK-NEXT:    br label [[BB38]]
 ; CHECK:       bb38:
 ; CHECK-NEXT:    br label [[BB33]]
 ;
@@ -720,7 +694,7 @@ bb38:
 define i32 @test14() {
 ; CHECK-LABEL: @test14(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[TMP:%.*]] = call i32 @getVal(), !range !4
+; CHECK-NEXT:    [[TMP:%.*]] = call i32 @getVal(), !range [[RNG4:![0-9]+]]
 ; CHECK-NEXT:    [[VAL:%.*]] = call i32 @llvm.ctpop.i32(i32 [[TMP]])
 ; CHECK-NEXT:    br label [[NODEBLOCK:%.*]]
 ; CHECK:       NodeBlock:
@@ -728,15 +702,13 @@ define i32 @test14() {
 ; CHECK-NEXT:    br i1 [[PIVOT]], label [[CASE_1:%.*]], label [[LEAFBLOCK:%.*]]
 ; CHECK:       LeafBlock:
 ; CHECK-NEXT:    [[SWITCHLEAF:%.*]] = icmp eq i32 [[VAL]], 1
-; CHECK-NEXT:    br i1 [[SWITCHLEAF]], label [[CASE_2:%.*]], label [[NEWDEFAULT:%.*]]
+; CHECK-NEXT:    br i1 [[SWITCHLEAF]], label [[CASE_2:%.*]], label [[CASE_D:%.*]]
 ; CHECK:       case.1:
 ; CHECK-NEXT:    [[RES1:%.*]] = call i32 @case1()
 ; CHECK-NEXT:    br label [[EXIT:%.*]]
 ; CHECK:       case.2:
 ; CHECK-NEXT:    [[RES2:%.*]] = call i32 @case2()
 ; CHECK-NEXT:    br label [[EXIT]]
-; CHECK:       NewDefault:
-; CHECK-NEXT:    br label [[CASE_D:%.*]]
 ; CHECK:       case.D:
 ; CHECK-NEXT:    [[RESD:%.*]] = call i32 @caseD()
 ; CHECK-NEXT:    br label [[EXIT]]
@@ -783,15 +755,13 @@ define i32 @test15() {
 ; CHECK-NEXT:    br i1 [[PIVOT]], label [[CASE_1:%.*]], label [[LEAFBLOCK:%.*]]
 ; CHECK:       LeafBlock:
 ; CHECK-NEXT:    [[SWITCHLEAF:%.*]] = icmp eq i32 [[VAL]], 1
-; CHECK-NEXT:    br i1 [[SWITCHLEAF]], label [[CASE_2:%.*]], label [[NEWDEFAULT:%.*]]
+; CHECK-NEXT:    br i1 [[SWITCHLEAF]], label [[CASE_2:%.*]], label [[CASE_D:%.*]]
 ; CHECK:       case.1:
 ; CHECK-NEXT:    [[RES1:%.*]] = call i32 @case1()
 ; CHECK-NEXT:    br label [[EXIT:%.*]]
 ; CHECK:       case.2:
 ; CHECK-NEXT:    [[RES2:%.*]] = call i32 @case2()
 ; CHECK-NEXT:    br label [[EXIT]]
-; CHECK:       NewDefault:
-; CHECK-NEXT:    br label [[CASE_D:%.*]]
 ; CHECK:       case.D:
 ; CHECK-NEXT:    [[RESD:%.*]] = call i32 @caseD()
 ; CHECK-NEXT:    br label [[EXIT]]
@@ -838,9 +808,7 @@ define i32 @test16(float %f) {
 ; CHECK-NEXT:    br label [[LEAFBLOCK:%.*]]
 ; CHECK:       LeafBlock:
 ; CHECK-NEXT:    [[SWITCHLEAF:%.*]] = icmp sge i64 [[CLAMP]], 2
-; CHECK-NEXT:    br i1 [[SWITCHLEAF]], label [[CASE_2:%.*]], label [[NEWDEFAULT:%.*]]
-; CHECK:       NewDefault:
-; CHECK-NEXT:    br label [[CASE_1:%.*]]
+; CHECK-NEXT:    br i1 [[SWITCHLEAF]], label [[CASE_2:%.*]], label [[CASE_1:%.*]]
 ; CHECK:       case.1:
 ; CHECK-NEXT:    [[RES1:%.*]] = call i32 @case1()
 ; CHECK-NEXT:    br label [[EXIT:%.*]]
index 55427af..ffd1ed1 100644 (file)
@@ -25,7 +25,7 @@
 
 ;CHECK:     LeafBlock11:                                      ; preds = %NodeBlock13
 ;CHECK-NEXT:  %SwitchLeaf12 = icmp eq i32 %tmp158, 15
-;CHECK-NEXT:  br i1 %SwitchLeaf12, label %bb334, label %NewDefault
+;CHECK-NEXT:  br i1 %SwitchLeaf12, label %bb334, label %bb336
 
 ;CHECK:     NodeBlock9:                                       ; preds = %NodeBlock17
 ;CHECK-NEXT:  %Pivot10 = icmp slt i32 %tmp158, 11
@@ -54,7 +54,7 @@
 ;CHECK:     LeafBlock:                                        ; preds = %NodeBlock
 ;CHECK-NEXT:  %tmp158.off = add i32 %tmp158, 6
 ;CHECK-NEXT:  %SwitchLeaf = icmp ule i32 %tmp158.off, 4
-;CHECK-NEXT:  br i1 %SwitchLeaf, label %bb338, label %NewDefault
+;CHECK-NEXT:  br i1 %SwitchLeaf, label %bb338, label %bb336
 
 define i32 @main(i32 %tmp158) {
 entry:
index 3cca3c9..d6b67b6 100644 (file)
@@ -14,35 +14,30 @@ define i1 @test_nested(i32 %x, i1 %b1, i1 %b2, i1 %b3) {
 ; CHECK-NEXT:    [[B3_INV:%.*]] = xor i1 [[B3:%.*]], true
 ; CHECK-NEXT:    br label [[OUTER_LOOP_HEADER:%.*]]
 ; CHECK:       Flow12:
-; CHECK-NEXT:    br i1 [[TMP3:%.*]], label [[EXIT_TRUE:%.*]], label [[FLOW13:%.*]]
+; CHECK-NEXT:    br i1 [[TMP2:%.*]], label [[EXIT_TRUE:%.*]], label [[FLOW13:%.*]]
 ; CHECK:       exit.true:
 ; CHECK-NEXT:    br label [[FLOW13]]
 ; CHECK:       Flow13:
-; CHECK-NEXT:    br i1 [[TMP2:%.*]], label [[NEWDEFAULT:%.*]], label [[FLOW14:%.*]]
-; CHECK:       NewDefault:
-; CHECK-NEXT:    br label [[EXIT_FALSE:%.*]]
-; CHECK:       Flow14:
-; CHECK-NEXT:    [[TMP0:%.*]] = phi i1 [ false, [[EXIT_FALSE]] ], [ true, [[FLOW13]] ]
-; CHECK-NEXT:    br label [[EXIT:%.*]]
+; CHECK-NEXT:    br i1 [[TMP1:%.*]], label [[EXIT_FALSE:%.*]], label [[EXIT:%.*]]
 ; CHECK:       exit.false:
-; CHECK-NEXT:    br label [[FLOW14]]
+; CHECK-NEXT:    br label [[EXIT]]
 ; CHECK:       outer.loop.header:
 ; CHECK-NEXT:    br i1 [[B1:%.*]], label [[OUTER_LOOP_BODY:%.*]], label [[FLOW3:%.*]]
 ; CHECK:       outer.loop.body:
 ; CHECK-NEXT:    br label [[INNER_LOOP_HEADER:%.*]]
 ; CHECK:       Flow3:
-; CHECK-NEXT:    [[TMP1:%.*]] = phi i1 [ [[TMP16:%.*]], [[FLOW11:%.*]] ], [ true, [[OUTER_LOOP_HEADER]] ]
-; CHECK-NEXT:    [[TMP2]] = phi i1 [ [[TMP12:%.*]], [[FLOW11]] ], [ false, [[OUTER_LOOP_HEADER]] ]
-; CHECK-NEXT:    [[TMP3]] = phi i1 [ false, [[FLOW11]] ], [ true, [[OUTER_LOOP_HEADER]] ]
-; CHECK-NEXT:    br i1 [[TMP1]], label [[FLOW12:%.*]], label [[OUTER_LOOP_HEADER]]
+; CHECK-NEXT:    [[TMP0:%.*]] = phi i1 [ [[TMP15:%.*]], [[FLOW11:%.*]] ], [ true, [[OUTER_LOOP_HEADER]] ]
+; CHECK-NEXT:    [[TMP1]] = phi i1 [ [[TMP11:%.*]], [[FLOW11]] ], [ false, [[OUTER_LOOP_HEADER]] ]
+; CHECK-NEXT:    [[TMP2]] = phi i1 [ false, [[FLOW11]] ], [ true, [[OUTER_LOOP_HEADER]] ]
+; CHECK-NEXT:    br i1 [[TMP0]], label [[FLOW12:%.*]], label [[OUTER_LOOP_HEADER]]
 ; CHECK:       inner.loop.header:
-; CHECK-NEXT:    [[TMP4:%.*]] = phi i1 [ [[TMP8:%.*]], [[FLOW4:%.*]] ], [ false, [[OUTER_LOOP_BODY]] ]
+; CHECK-NEXT:    [[TMP3:%.*]] = phi i1 [ [[TMP7:%.*]], [[FLOW4:%.*]] ], [ false, [[OUTER_LOOP_BODY]] ]
 ; CHECK-NEXT:    br i1 [[B2:%.*]], label [[INNER_LOOP_BODY:%.*]], label [[FLOW4]]
 ; CHECK:       Flow6:
-; CHECK-NEXT:    [[TMP5:%.*]] = phi i1 [ false, [[INNER_LOOP_LATCH:%.*]] ], [ true, [[LEAFBLOCK:%.*]] ]
+; CHECK-NEXT:    [[TMP4:%.*]] = phi i1 [ false, [[INNER_LOOP_LATCH:%.*]] ], [ true, [[LEAFBLOCK:%.*]] ]
 ; CHECK-NEXT:    br label [[FLOW5:%.*]]
 ; CHECK:       Flow7:
-; CHECK-NEXT:    br i1 [[TMP10:%.*]], label [[INNER_LOOP_END:%.*]], label [[FLOW8:%.*]]
+; CHECK-NEXT:    br i1 [[TMP9:%.*]], label [[INNER_LOOP_END:%.*]], label [[FLOW8:%.*]]
 ; CHECK:       inner.loop.end:
 ; CHECK-NEXT:    br label [[FLOW8]]
 ; CHECK:       inner.loop.body:
@@ -50,24 +45,24 @@ define i1 @test_nested(i32 %x, i1 %b1, i1 %b2, i1 %b3) {
 ; CHECK:       inner.loop.body.else:
 ; CHECK-NEXT:    br label [[FLOW]]
 ; CHECK:       Flow:
-; CHECK-NEXT:    [[TMP6:%.*]] = phi i1 [ false, [[INNER_LOOP_BODY_ELSE]] ], [ true, [[INNER_LOOP_BODY]] ]
-; CHECK-NEXT:    br i1 [[TMP6]], label [[INNER_LOOP_BODY_THEN:%.*]], label [[INNER_LOOP_COND:%.*]]
+; CHECK-NEXT:    [[TMP5:%.*]] = phi i1 [ false, [[INNER_LOOP_BODY_ELSE]] ], [ true, [[INNER_LOOP_BODY]] ]
+; CHECK-NEXT:    br i1 [[TMP5]], label [[INNER_LOOP_BODY_THEN:%.*]], label [[INNER_LOOP_COND:%.*]]
 ; CHECK:       inner.loop.body.then:
 ; CHECK-NEXT:    br label [[INNER_LOOP_COND]]
 ; CHECK:       Flow4:
-; CHECK-NEXT:    [[TMP7:%.*]] = phi i1 [ [[TMP17:%.*]], [[FLOW5]] ], [ true, [[INNER_LOOP_HEADER]] ]
-; CHECK-NEXT:    [[TMP8]] = phi i1 [ [[TMP18:%.*]], [[FLOW5]] ], [ [[TMP4]], [[INNER_LOOP_HEADER]] ]
-; CHECK-NEXT:    [[TMP9:%.*]] = phi i1 [ [[TMP19:%.*]], [[FLOW5]] ], [ false, [[INNER_LOOP_HEADER]] ]
-; CHECK-NEXT:    [[TMP10]] = phi i1 [ false, [[FLOW5]] ], [ true, [[INNER_LOOP_HEADER]] ]
-; CHECK-NEXT:    br i1 [[TMP7]], label [[FLOW7:%.*]], label [[INNER_LOOP_HEADER]]
+; CHECK-NEXT:    [[TMP6:%.*]] = phi i1 [ [[TMP16:%.*]], [[FLOW5]] ], [ true, [[INNER_LOOP_HEADER]] ]
+; CHECK-NEXT:    [[TMP7]] = phi i1 [ [[TMP17:%.*]], [[FLOW5]] ], [ [[TMP3]], [[INNER_LOOP_HEADER]] ]
+; CHECK-NEXT:    [[TMP8:%.*]] = phi i1 [ [[TMP18:%.*]], [[FLOW5]] ], [ false, [[INNER_LOOP_HEADER]] ]
+; CHECK-NEXT:    [[TMP9]] = phi i1 [ false, [[FLOW5]] ], [ true, [[INNER_LOOP_HEADER]] ]
+; CHECK-NEXT:    br i1 [[TMP6]], label [[FLOW7:%.*]], label [[INNER_LOOP_HEADER]]
 ; CHECK:       inner.loop.cond:
 ; CHECK-NEXT:    br label [[NODEBLOCK:%.*]]
 ; CHECK:       NodeBlock:
 ; CHECK-NEXT:    [[PIVOT:%.*]] = icmp slt i32 [[X:%.*]], 1
 ; CHECK-NEXT:    br i1 [[PIVOT]], label [[LEAFBLOCK]], label [[FLOW5]]
 ; CHECK:       Flow8:
-; CHECK-NEXT:    [[TMP11:%.*]] = phi i1 [ true, [[INNER_LOOP_END]] ], [ false, [[FLOW7]] ]
-; CHECK-NEXT:    br i1 [[TMP9]], label [[LEAFBLOCK1:%.*]], label [[FLOW9:%.*]]
+; CHECK-NEXT:    [[TMP10:%.*]] = phi i1 [ true, [[INNER_LOOP_END]] ], [ false, [[FLOW7]] ]
+; CHECK-NEXT:    br i1 [[TMP8]], label [[LEAFBLOCK1:%.*]], label [[FLOW9:%.*]]
 ; CHECK:       LeafBlock1:
 ; CHECK-NEXT:    [[SWITCHLEAF2:%.*]] = icmp eq i32 [[X]], 1
 ; CHECK-NEXT:    br i1 [[SWITCHLEAF2]], label [[INNER_LOOP_BREAK:%.*]], label [[FLOW10:%.*]]
@@ -75,31 +70,32 @@ define i1 @test_nested(i32 %x, i1 %b1, i1 %b2, i1 %b3) {
 ; CHECK-NEXT:    [[SWITCHLEAF:%.*]] = icmp eq i32 [[X]], 0
 ; CHECK-NEXT:    br i1 [[SWITCHLEAF]], label [[INNER_LOOP_LATCH]], label [[FLOW6:%.*]]
 ; CHECK:       Flow9:
-; CHECK-NEXT:    [[TMP12]] = phi i1 [ [[TMP14:%.*]], [[FLOW10]] ], [ [[TMP8]], [[FLOW8]] ]
-; CHECK-NEXT:    [[TMP13:%.*]] = phi i1 [ [[TMP15:%.*]], [[FLOW10]] ], [ [[TMP11]], [[FLOW8]] ]
-; CHECK-NEXT:    br i1 [[TMP13]], label [[OUTER_LOOP_CLEANUP:%.*]], label [[FLOW11]]
+; CHECK-NEXT:    [[TMP11]] = phi i1 [ [[TMP13:%.*]], [[FLOW10]] ], [ [[TMP7]], [[FLOW8]] ]
+; CHECK-NEXT:    [[TMP12:%.*]] = phi i1 [ [[TMP14:%.*]], [[FLOW10]] ], [ [[TMP10]], [[FLOW8]] ]
+; CHECK-NEXT:    br i1 [[TMP12]], label [[OUTER_LOOP_CLEANUP:%.*]], label [[FLOW11]]
 ; CHECK:       inner.loop.break:
 ; CHECK-NEXT:    br label [[FLOW10]]
 ; CHECK:       Flow10:
-; CHECK-NEXT:    [[TMP14]] = phi i1 [ false, [[INNER_LOOP_BREAK]] ], [ true, [[LEAFBLOCK1]] ]
-; CHECK-NEXT:    [[TMP15]] = phi i1 [ true, [[INNER_LOOP_BREAK]] ], [ [[TMP11]], [[LEAFBLOCK1]] ]
+; CHECK-NEXT:    [[TMP13]] = phi i1 [ false, [[INNER_LOOP_BREAK]] ], [ true, [[LEAFBLOCK1]] ]
+; CHECK-NEXT:    [[TMP14]] = phi i1 [ true, [[INNER_LOOP_BREAK]] ], [ [[TMP10]], [[LEAFBLOCK1]] ]
 ; CHECK-NEXT:    br label [[FLOW9]]
 ; CHECK:       outer.loop.cleanup:
 ; CHECK-NEXT:    br label [[OUTER_LOOP_LATCH:%.*]]
 ; CHECK:       Flow11:
-; CHECK-NEXT:    [[TMP16]] = phi i1 [ false, [[OUTER_LOOP_LATCH]] ], [ true, [[FLOW9]] ]
+; CHECK-NEXT:    [[TMP15]] = phi i1 [ false, [[OUTER_LOOP_LATCH]] ], [ true, [[FLOW9]] ]
 ; CHECK-NEXT:    br label [[FLOW3]]
 ; CHECK:       outer.loop.latch:
 ; CHECK-NEXT:    br label [[FLOW11]]
 ; CHECK:       Flow5:
-; CHECK-NEXT:    [[TMP17]] = phi i1 [ [[TMP5]], [[FLOW6]] ], [ true, [[NODEBLOCK]] ]
-; CHECK-NEXT:    [[TMP18]] = phi i1 [ [[TMP5]], [[FLOW6]] ], [ [[TMP4]], [[NODEBLOCK]] ]
-; CHECK-NEXT:    [[TMP19]] = phi i1 [ false, [[FLOW6]] ], [ true, [[NODEBLOCK]] ]
+; CHECK-NEXT:    [[TMP16]] = phi i1 [ [[TMP4]], [[FLOW6]] ], [ true, [[NODEBLOCK]] ]
+; CHECK-NEXT:    [[TMP17]] = phi i1 [ [[TMP4]], [[FLOW6]] ], [ [[TMP3]], [[NODEBLOCK]] ]
+; CHECK-NEXT:    [[TMP18]] = phi i1 [ false, [[FLOW6]] ], [ true, [[NODEBLOCK]] ]
 ; CHECK-NEXT:    br label [[FLOW4]]
 ; CHECK:       inner.loop.latch:
 ; CHECK-NEXT:    br label [[FLOW6]]
 ; CHECK:       exit:
-; CHECK-NEXT:    ret i1 [[TMP0]]
+; CHECK-NEXT:    [[R:%.*]] = phi i1 [ true, [[FLOW13]] ], [ false, [[EXIT_FALSE]] ]
+; CHECK-NEXT:    ret i1 [[R]]
 ;
 entry:
   br label %outer.loop.header
index 1898d76..77fa9b4 100644 (file)
@@ -23,8 +23,6 @@ define void @loop_1(i32 %Value, i1 %PredEntry, i1 %PredD) {
 ; CHECK-NEXT:    br label [[D]]
 ; CHECK:       D:
 ; CHECK-NEXT:    br i1 [[PREDD:%.*]], label [[A]], label [[LOOP_EXIT_GUARD]]
-; CHECK:       NewDefault:
-; CHECK-NEXT:    br label [[X:%.*]]
 ; CHECK:       X:
 ; CHECK-NEXT:    br label [[EXIT:%.*]]
 ; CHECK:       Y:
@@ -34,8 +32,8 @@ define void @loop_1(i32 %Value, i1 %PredEntry, i1 %PredD) {
 ; CHECK:       exit:
 ; CHECK-NEXT:    ret void
 ; CHECK:       loop.exit.guard:
-; CHECK-NEXT:    [[GUARD_NEWDEFAULT:%.*]] = phi i1 [ true, [[LEAFBLOCK1]] ], [ true, [[LEAFBLOCK]] ], [ false, [[D]] ]
-; CHECK-NEXT:    br i1 [[GUARD_NEWDEFAULT]], label [[NEWDEFAULT:%.*]], label [[Y:%.*]]
+; CHECK-NEXT:    [[GUARD_X:%.*]] = phi i1 [ true, [[LEAFBLOCK1]] ], [ true, [[LEAFBLOCK]] ], [ false, [[D]] ]
+; CHECK-NEXT:    br i1 [[GUARD_X]], label [[X:%.*]], label [[Y:%.*]]
 ;
 entry:
   br i1 %PredEntry, label %A, label %G
index 6344f17..f0bdbeb 100644 (file)
@@ -5,15 +5,15 @@ define void @test0(i32 %mode) {
 ; CHECK-LABEL: @test0
 ;
 ; CHECK: icmp eq i32 %mode, 4
-; CHECK-NEXT: label %BB3, label %NewDefault
+; CHECK-NEXT: label %BB3, label %BB2
 ;
 ; CHECK: icmp eq i32 %mode, 2
-; CHECK-NEXT: label %BB3, label %NewDefault
+; CHECK-NEXT: label %BB3, label %BB2
 ;
 ; CHECK: icmp eq i32 %mode, 0
-; CHECK-NEXT: label %BB3, label %NewDefault
+; CHECK-NEXT: label %BB3, label %BB2
 ;
-; CHECK: %merge = phi i64 [ 1, %BB3 ], [ 0, %NewDefault ]
+; CHECK: %merge = phi i64 [ 1, %BB3 ], [ 0, %LeafBlock ], [ 0, %LeafBlock1 ], [ 0, %LeafBlock3 ]
 BB1:
   switch i32 %mode, label %BB2 [
     i32 3, label %BB2
@@ -213,7 +213,7 @@ lbl2:                                             ; preds = %cleanup, %lbl1
 
 for.cond:                                         ; preds = %cleanup, %cleanup, %lbl2
 ; CHECK: for.cond:
-; CHECK: phi i16 [ undef, %lbl2 ], [ %b.3, %NewDefault ]{{$}}
+; CHECK: phi i16 [ undef, %lbl2 ], [ %b.3, %LeafBlock ], [ %b.3, %LeafBlock1 ]{{$}}
 ; CHECK: for.cond1:
   %b.2 = phi i16 [ undef, %lbl2 ], [ %b.3, %cleanup ], [ %b.3, %cleanup ]
   br label %for.cond1