Index: lib/Transforms/Scalar/LoopUnswitch.cpp =================================================================== --- lib/Transforms/Scalar/LoopUnswitch.cpp +++ lib/Transforms/Scalar/LoopUnswitch.cpp @@ -593,6 +593,45 @@ continue; if (BranchInst *BI = dyn_cast(TI)) { + /* + * Some branches may be rendered unreachable because of previous unswitching. + * Unswitch only those branches that are reachable. + */ + auto *Node = DT->getNode(*I)->getIDom(); + BasicBlock *DomBB = Node->getBlock(); + bool isUnreachable = false; + while (currentLoop->contains(DomBB)) { + BranchInst *BI = dyn_cast (DomBB->getTerminator()); + + if (BI && BI->isConditional()) { + Value *Cond = BI->getCondition(); + BasicBlock *Succ = NULL; + if (Cond == ConstantInt::getTrue(Cond->getContext())) { + Succ = BI->getSuccessor(1); + } else if (Cond == ConstantInt::getFalse(Cond->getContext())){ + Succ = BI->getSuccessor(0); + } + + if (Succ) { + BasicBlockEdge UnreachableEdge (BI->getParent(), Succ); + if (DT->dominates(UnreachableEdge, *I)) { + isUnreachable = true; + break; + } + } + } + + if (isUnreachable) break; + + Node = DT->getNode(DomBB)->getIDom(); + DomBB = Node->getBlock(); + } + + if (isUnreachable) { + DEBUG (dbgs() << "Unreachable branch: " << *TI << " in Function " << (*I)->getParent()->getName() << "\n"); + continue; + } + // If this isn't branching on an invariant condition, we can't unswitch // it. if (BI->isConditional()) {