Index: llvm/lib/IR/Dominators.cpp =================================================================== --- llvm/lib/IR/Dominators.cpp +++ llvm/lib/IR/Dominators.cpp @@ -261,7 +261,7 @@ PHINode *PN = dyn_cast(UserInst); if (PN && PN->getParent() == BBE.getEnd() && PN->getIncomingBlock(U) == BBE.getStart()) - return true; + return BBE.isSingleEdge(); // Otherwise use the edge-dominates-block query, which // handles the crazy critical edge cases properly. @@ -352,7 +352,7 @@ bool DominatorTree::dominates(const BasicBlockEdge &BBE1, const BasicBlockEdge &BBE2) const { if (BBE1.getStart() == BBE2.getStart() && BBE1.getEnd() == BBE2.getEnd()) - return true; + return BBE1.isSingleEdge(); return dominates(BBE1, BBE2.getStart()); } Index: llvm/unittests/IR/DominatorTreeTest.cpp =================================================================== --- llvm/unittests/IR/DominatorTreeTest.cpp +++ llvm/unittests/IR/DominatorTreeTest.cpp @@ -1072,6 +1072,50 @@ }); } +TEST(DominatorTree, SwitchEdgeDomination) { + StringRef ModuleString = + "define i32 @f(i32 %i, i32 *%p) {\n" + "bb0:\n" + " store i32 %i, i32 *%p\n" + " switch i32 %i, label %bb2 [\n" + " i32 0, label %bb1\n" + " i32 1, label %bb1\n" + " ]\n" + " bb1:\n" + " %phi = phi i32 [ 2, %bb0 ], [ 3, %bb0 ]\n" + " ret i32 1\n" + " bb2:\n" + " ret i32 4\n" + "}\n"; + + // Parse the module. + LLVMContext Context; + std::unique_ptr M = makeLLVMModule(Context, ModuleString); + + runWithDomTree(*M, "f", + [&](Function &F, DominatorTree *DT, PostDominatorTree *PDT) { + Function::iterator FI = F.begin(); + + BasicBlock *BB0 = &*FI++; + BasicBlock *BB1 = &*FI++; + BasicBlock *BB2 = &*FI++; + Instruction &Phi = *BB1->begin(); + + BasicBlockEdge E01(BB0, BB1); + BasicBlockEdge E02(BB0, BB2); + + EXPECT_TRUE(DT->dominates(E02, E02)); + EXPECT_FALSE(DT->dominates(E02, E01)); + EXPECT_FALSE(DT->dominates(E01, E02)); + // Does not dominate, because it is a multi-edge. + EXPECT_FALSE(DT->dominates(E01, E01)); + + // Similarly, multi-edge phi uses are not dominated. + EXPECT_FALSE(DT->dominates(E01, Phi.getOperandUse(0))); + EXPECT_FALSE(DT->dominates(E01, Phi.getOperandUse(1))); + }); +} + TEST(DominatorTree, ValueDomination) { StringRef ModuleString = R"( @foo = global i8 0