diff --git a/include/llvm/IR/Dominators.h b/include/llvm/IR/Dominators.h index 6a14785a6cc..a79be8779b7 100644 --- a/include/llvm/IR/Dominators.h +++ b/include/llvm/IR/Dominators.h @@ -172,6 +172,8 @@ class DominatorTree : public DominatorTreeBase { /// never dominate the use. bool dominates(const BasicBlockEdge &BBE, const Use &U) const; bool dominates(const BasicBlockEdge &BBE, const BasicBlock *BB) const; + /// Returns true if edge \p BBE1 dominates edge \p BBE2. + bool dominates(const BasicBlockEdge &BBE1, const BasicBlockEdge &BBE2) const; // Ensure base class overloads are visible. using Base::isReachableFromEntry; diff --git a/lib/IR/Dominators.cpp b/lib/IR/Dominators.cpp index d4a2026726b..bb1cc347dcb 100644 --- a/lib/IR/Dominators.cpp +++ b/lib/IR/Dominators.cpp @@ -316,6 +316,14 @@ bool DominatorTree::isReachableFromEntry(const Use &U) const { return isReachableFromEntry(I->getParent()); } +// Edge BBE1 dominates edge BBE2 if they match or BBE1 dominates start of BBE2. +bool DominatorTree::dominates(const BasicBlockEdge &BBE1, + const BasicBlockEdge &BBE2) const { + if (BBE1.getStart() == BBE2.getStart() && BBE1.getEnd() == BBE2.getEnd()) + return true; + return dominates(BBE1, BBE2.getStart()); +} + //===----------------------------------------------------------------------===// // DominatorTreeAnalysis and related pass implementations //===----------------------------------------------------------------------===// diff --git a/unittests/IR/DominatorTreeTest.cpp b/unittests/IR/DominatorTreeTest.cpp index 22d2003de35..66e122760ef 100644 --- a/unittests/IR/DominatorTreeTest.cpp +++ b/unittests/IR/DominatorTreeTest.cpp @@ -1020,3 +1020,54 @@ TEST(DominatorTree, InsertIntoIrreducible) { EXPECT_TRUE(DT.verify()); } +TEST(DominatorTree, EdgeDomination) { + StringRef ModuleString = "define i32 @f(i1 %cond) {\n" + " bb0:\n" + " br i1 %cond, label %bb1, label %bb2\n" + " bb1:\n" + " br label %bb3\n" + " bb2:\n" + " br label %bb3\n" + " bb3:\n" + " ret i32 4" + "}\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++; + BasicBlock *BB3 = &*FI++; + + BasicBlockEdge E01(BB0, BB1); + BasicBlockEdge E02(BB0, BB2); + BasicBlockEdge E13(BB1, BB3); + BasicBlockEdge E23(BB2, BB3); + + EXPECT_TRUE(DT->dominates(E01, E01)); + EXPECT_FALSE(DT->dominates(E01, E02)); + EXPECT_TRUE(DT->dominates(E01, E13)); + EXPECT_FALSE(DT->dominates(E01, E23)); + + EXPECT_FALSE(DT->dominates(E02, E01)); + EXPECT_TRUE(DT->dominates(E02, E02)); + EXPECT_FALSE(DT->dominates(E02, E13)); + EXPECT_TRUE(DT->dominates(E02, E23)); + + EXPECT_FALSE(DT->dominates(E13, E01)); + EXPECT_FALSE(DT->dominates(E13, E02)); + EXPECT_TRUE(DT->dominates(E13, E13)); + EXPECT_FALSE(DT->dominates(E13, E23)); + + EXPECT_FALSE(DT->dominates(E23, E01)); + EXPECT_FALSE(DT->dominates(E23, E02)); + EXPECT_FALSE(DT->dominates(E23, E13)); + EXPECT_TRUE(DT->dominates(E23, E23)); + }); +}