diff --git a/llvm/lib/IR/Dominators.cpp b/llvm/lib/IR/Dominators.cpp --- a/llvm/lib/IR/Dominators.cpp +++ b/llvm/lib/IR/Dominators.cpp @@ -140,12 +140,7 @@ if (DefBB != UseBB) return dominates(DefBB, UseBB); - // Loop through the basic block until we find Def or User. - BasicBlock::const_iterator I = DefBB->begin(); - for (; &*I != Def && &*I != User; ++I) - /*empty*/; - - return &*I == Def; + return Def->comesBefore(User); } // true if Def would dominate a use in any instruction in UseBB. @@ -289,12 +284,7 @@ if (isa(UserInst)) return true; - // Otherwise, just loop through the basic block until we find Def or User. - BasicBlock::const_iterator I = DefBB->begin(); - for (; &*I != Def && &*I != UserInst; ++I) - /*empty*/; - - return &*I != UserInst; + return Def->comesBefore(UserInst); } bool DominatorTree::isReachableFromEntry(const Use &U) const { diff --git a/llvm/unittests/IR/DominatorTreeTest.cpp b/llvm/unittests/IR/DominatorTreeTest.cpp --- a/llvm/unittests/IR/DominatorTreeTest.cpp +++ b/llvm/unittests/IR/DominatorTreeTest.cpp @@ -43,6 +43,37 @@ return M; } +TEST(DominatorTree, PHIs) { + StringRef ModuleString = R"( + define void @f() { + bb1: + br label %bb1 + bb2: + %a = phi i32 [0, %bb1], [1, %bb2] + %b = phi i32 [2, %bb1], [%a, %bb2] + br label %bb2 + }; + )"; + + // Parse the module. + LLVMContext Context; + std::unique_ptr M = makeLLVMModule(Context, ModuleString); + + runWithDomTree(*M, "f", + [&](Function &F, DominatorTree *DT, PostDominatorTree *PDT) { + auto FI = F.begin(); + ++FI; + BasicBlock *BB2 = &*FI; + auto BI = BB2->begin(); + Instruction *PhiA = &*BI++; + Instruction *PhiB = &*BI; + + // Phis are thought to execute "instantly, together". + EXPECT_TRUE(DT->dominates(PhiA, PhiB)); + EXPECT_TRUE(DT->dominates(PhiB, PhiA)); + }); +} + TEST(DominatorTree, Unreachable) { StringRef ModuleString = "declare i32 @g()\n"