Index: llvm/trunk/lib/Transforms/Utils/LowerSwitch.cpp =================================================================== --- llvm/trunk/lib/Transforms/Utils/LowerSwitch.cpp +++ llvm/trunk/lib/Transforms/Utils/LowerSwitch.cpp @@ -74,7 +74,7 @@ LowerSwitch() : FunctionPass(ID) { initializeLowerSwitchPass(*PassRegistry::getPassRegistry()); - } + } bool runOnFunction(Function &F) override; @@ -327,7 +327,7 @@ } else if (Leaf.Low->isZero()) { // Val >= 0 && Val <= Hi --> Val <=u Hi Comp = new ICmpInst(*NewLeaf, ICmpInst::ICMP_ULE, Val, Leaf.High, - "SwitchLeaf"); + "SwitchLeaf"); } else { // Emit V-Lo <=u Hi-Lo Constant* NegLo = ConstantExpr::getNeg(Leaf.Low); @@ -354,7 +354,7 @@ for (uint64_t j = 0; j < Range; ++j) { PN->removeIncomingValue(OrigBlock); } - + int BlockIdx = PN->getBasicBlockIndex(OrigBlock); assert(BlockIdx != -1 && "Switch didn't go to this successor??"); PN->setIncomingBlock((unsigned)BlockIdx, NewLeaf); @@ -495,6 +495,10 @@ } #endif + // As the default block in the switch is unreachable, update the PHI nodes + // (remove the entry to the default block) to reflect this. + Default->removePredecessor(OrigBlock); + // Use the most popular block as the new default, reducing the number of // cases. assert(MaxPop > 0 && PopSucc); @@ -508,6 +512,10 @@ if (Cases.empty()) { BranchInst::Create(Default, CurBlock); SI->eraseFromParent(); + // As all the cases have been replaced with a single branch, only keep + // one entry in the PHI nodes. + for (unsigned I = 0 ; I < (MaxPop - 1) ; ++I) + PopSucc->removePredecessor(OrigBlock); return; } } Index: llvm/trunk/test/Transforms/Util/lowerswitch.ll =================================================================== --- llvm/trunk/test/Transforms/Util/lowerswitch.ll +++ llvm/trunk/test/Transforms/Util/lowerswitch.ll @@ -242,3 +242,51 @@ unreachable: ; preds = %cleanup unreachable } + +; Test that the PHI node in cleanup17 is removed as the switch default block is +; not reachable. +define void @test4() { +; CHECK-LABEL: @test4 +entry: + switch i32 undef, label %cleanup17 [ + i32 0, label %return + i32 9, label %return + ] + +cleanup17: +; CHECK: cleanup17: +; CHECK-NOT: phi i16 [ undef, %entry ] +; CHECK: return: + + %retval.4 = phi i16 [ undef, %entry ] + unreachable + +return: + ret void +} + +; Test that the PHI node in for.inc is updated correctly as the switch is +; replaced with a single branch to for.inc +define void @test5() { +; CHECK-LABEL: @test5 +entry: + br i1 undef, label %cleanup10, label %cleanup10.thread + +cleanup10.thread: + br label %for.inc + +cleanup10: + switch i32 undef, label %unreachable [ + i32 0, label %for.inc + i32 4, label %for.inc + ] + +for.inc: +; CHECK: for.inc: +; CHECK-NEXT: phi i16 [ 0, %cleanup10.thread ], [ undef, %cleanup10 ] +%0 = phi i16 [ undef, %cleanup10 ], [ 0, %cleanup10.thread ], [ undef, %cleanup10 ] + unreachable + +unreachable: + unreachable +}