Index: llvm/trunk/lib/Transforms/Utils/LowerSwitch.cpp =================================================================== --- llvm/trunk/lib/Transforms/Utils/LowerSwitch.cpp +++ llvm/trunk/lib/Transforms/Utils/LowerSwitch.cpp @@ -512,25 +512,25 @@ } } + 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(I); ++I) { - PHINode *PN = cast(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); Index: llvm/trunk/test/Transforms/Util/lowerswitch.ll =================================================================== --- llvm/trunk/test/Transforms/Util/lowerswitch.ll +++ llvm/trunk/test/Transforms/Util/lowerswitch.ll @@ -3,7 +3,7 @@ ; 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 @@ -186,3 +186,59 @@ ._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 +}