Index: lib/Transforms/Utils/LowerSwitch.cpp =================================================================== --- lib/Transforms/Utils/LowerSwitch.cpp +++ lib/Transforms/Utils/LowerSwitch.cpp @@ -74,7 +74,7 @@ LowerSwitch() : FunctionPass(ID) { initializeLowerSwitchPass(*PassRegistry::getPassRegistry()); - } + } bool runOnFunction(Function &F) override; @@ -211,6 +211,20 @@ } } +/// Remove the first occurrence of the "switch statement" BB in the PHI +/// nodes +static void removeEntryFromPhis(BasicBlock *SuccBB, BasicBlock *OrigBB) { + for (BasicBlock::iterator I = SuccBB->begin(), + IE = SuccBB->getFirstNonPHI()->getIterator(); + I != IE;) { + PHINode *PN = cast(I); + ++I; // To avoid invalid iterator if PHI node are removed below + int BlockIdx = PN->getBasicBlockIndex(OrigBB); + assert(BlockIdx != -1 && "Switch didn't go to this successor??"); + PN->removeIncomingValue((unsigned)BlockIdx, true); + } +} + /// Convert the switch statement into a binary lookup of the case values. /// The function recursively builds this tree. LowerBound and UpperBound are /// used to keep track of the bounds for Val that have already been checked by @@ -327,7 +341,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 +368,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 +509,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. + removeEntryFromPhis(Default, OrigBlock); + // Use the most popular block as the new default, reducing the number of // cases. assert(MaxPop > 0 && PopSucc); Index: test/Transforms/Util/lowerswitch.ll =================================================================== --- test/Transforms/Util/lowerswitch.ll +++ test/Transforms/Util/lowerswitch.ll @@ -242,3 +242,52 @@ 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: + br label %for.cond + +for.cond: + br label %for.cond1 + +for.cond1: + br i1 undef, label %for.end20, label %for.end20 + +for.cond3: + br label %for.cond3 + +for.cond5: + br i1 undef, label %cleanup.thread, label %if.end9 + +if.end9: + br i1 undef, label %cleanup.thread, label %cleanup13 + +cleanup.thread: + br label %cleanup13 + +cleanup13: + switch i32 undef, label %cleanup17 [ + i32 0, label %for.cond5 + i32 9, label %for.cond5 + ] + +cleanup17: +; CHECK: cleanup17: +; CHECK-NOT: phi i16 [ undef, %cleanup13 ] +; CHECK: for.end20: + + %retval.4 = phi i16 [ undef, %cleanup13 ] + unreachable + +for.end20: + br label %for.cond + +return: + ret void + +unreachable: + unreachable +}