}
}
+ unsigned NrOfDefaults = (SI->getDefaultDest() == Default) ? 1 : 0;
+ for (const auto &Case : SI->cases())
+ if (Case.getCaseSuccessor() == Default)
+ NrOfDefaults++;
+
// 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);
- // If there is an entry in any PHI nodes for the default edge, make sure
- // to update them as well.
- for (BasicBlock::iterator I = Default->begin(); isa<PHINode>(I); ++I) {
- PHINode *PN = cast<PHINode>(I);
- int BlockIdx = PN->getBasicBlockIndex(OrigBlock);
- assert(BlockIdx != -1 && "Switch didn't go to this successor??");
- PN->setIncomingBlock((unsigned)BlockIdx, 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, NrOfDefaults);
+
// Branch to our shiny new if-then stuff...
BranchInst::Create(SwitchBlock, OrigBlock);
; Test that we don't crash and have a different basic block for each incoming edge.
define void @test0() {
; CHECK-LABEL: @test0
-; CHECK: %merge = phi i64 [ 1, %BB3 ], [ 0, %NewDefault ], [ 0, %NodeBlock5 ], [ 0, %LeafBlock1 ]
+; CHECK: %merge = phi i64 [ 1, %BB3 ], [ 0, %NodeBlock5 ], [ 0, %LeafBlock1 ], [ 0, %NewDefault ]
BB1:
switch i32 undef, label %BB2 [
i32 3, label %BB2
._crit_edge: ; preds = %34, %0
ret void
}
+
+; Test that the PHI node in for.cond should have one entry for each predecessor
+; of its parent basic block after lowerswitch merged several cases into a new
+; default block.
+define void @test3() {
+; CHECK-LABEL: @test3
+entry:
+ br label %lbl1
+
+lbl1: ; preds = %cleanup, %entry
+ br label %lbl2
+
+lbl2: ; preds = %cleanup, %lbl1
+ br label %for.cond
+
+for.cond: ; preds = %cleanup, %cleanup, %lbl2
+; CHECK: for.cond:
+; CHECK: phi i16 [ undef, %lbl2 ], [ %b.3, %NewDefault ]{{$}}
+; CHECK: for.cond1:
+ %b.2 = phi i16 [ undef, %lbl2 ], [ %b.3, %cleanup ], [ %b.3, %cleanup ]
+ br label %for.cond1
+
+for.cond1: ; preds = %for.inc, %for.cond
+ %b.3 = phi i16 [ %b.2, %for.cond ], [ undef, %for.inc ]
+ %tobool = icmp ne i16 %b.3, 0
+ br i1 %tobool, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond1
+ br i1 undef, label %if.then, label %for.inc
+
+if.then: ; preds = %for.body
+ br label %cleanup
+
+for.inc: ; preds = %for.body
+ br label %for.cond1
+
+for.end: ; preds = %for.cond1
+ br i1 undef, label %if.then4, label %for.body7
+
+if.then4: ; preds = %for.end
+ br label %cleanup
+
+for.body7: ; preds = %for.end
+ br label %cleanup
+
+cleanup: ; preds = %for.body7, %if.then4, %if.then
+ switch i32 undef, label %unreachable [
+ i32 0, label %for.cond
+ i32 2, label %lbl1
+ i32 5, label %for.cond
+ i32 3, label %lbl2
+ ]
+
+unreachable: ; preds = %cleanup
+ unreachable
+}