diff options
author | Diego Novillo <dnovillo@google.com> | 2013-12-02 14:08:27 +0000 |
---|---|---|
committer | Diego Novillo <dnovillo@google.com> | 2013-12-02 14:08:27 +0000 |
commit | 97add46aeea26db338f68f16aaf2587737ab46da (patch) | |
tree | 4319b8962e7a45ccf859745bef2087bc5e07ef07 | |
parent | c15aff93c49dabb5ed174fd3731c7219e96af1f4 (diff) | |
download | llvm-97add46aeea26db338f68f16aaf2587737ab46da.tar.gz llvm-97add46aeea26db338f68f16aaf2587737ab46da.tar.bz2 llvm-97add46aeea26db338f68f16aaf2587737ab46da.tar.xz |
Fix dominator descendants for unreachable blocks.
When a block is unreachable, asking its dom tree descendants should
return the empty set. However, the computation of the descendants
was causing a segmentation fault because the dom tree node we get
from the basic block is initially NULL.
Fixed by adding a test for a valid dom tree node before we iterate.
The patch also adds some unit tests to the existing dom tree tests.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@196099 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/llvm/Analysis/Dominators.h | 4 | ||||
-rw-r--r-- | unittests/IR/DominatorTreeTest.cpp | 27 |
2 files changed, 30 insertions, 1 deletions
diff --git a/include/llvm/Analysis/Dominators.h b/include/llvm/Analysis/Dominators.h index e35e101de3..896664c1c1 100644 --- a/include/llvm/Analysis/Dominators.h +++ b/include/llvm/Analysis/Dominators.h @@ -348,10 +348,12 @@ public: /// Get all nodes dominated by R, including R itself. void getDescendants(NodeT *R, SmallVectorImpl<NodeT *> &Result) const { + Result.clear(); const DomTreeNodeBase<NodeT> *RN = getNode(R); + if (RN == NULL) + return; // If R is unreachable, it will not be present in the DOM tree. SmallVector<const DomTreeNodeBase<NodeT> *, 8> WL; WL.push_back(RN); - Result.clear(); while (!WL.empty()) { const DomTreeNodeBase<NodeT> *N = WL.pop_back_val(); diff --git a/unittests/IR/DominatorTreeTest.cpp b/unittests/IR/DominatorTreeTest.cpp index 4e5af9395c..387d732660 100644 --- a/unittests/IR/DominatorTreeTest.cpp +++ b/unittests/IR/DominatorTreeTest.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/Dominators.h" +#include "llvm/Analysis/PostDominators.h" #include "llvm/Assembly/Parser.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/LLVMContext.h" @@ -26,6 +27,7 @@ namespace llvm { static char ID; virtual bool runOnFunction(Function &F) { DominatorTree *DT = &getAnalysis<DominatorTree>(); + PostDominatorTree *PDT = &getAnalysis<PostDominatorTree>(); Function::iterator FI = F.begin(); BasicBlock *BB0 = FI++; @@ -148,10 +150,34 @@ namespace llvm { EXPECT_TRUE(DT->dominates(Y6, BB3)); + // Post dominance. + EXPECT_TRUE(PDT->dominates(BB0, BB0)); + EXPECT_FALSE(PDT->dominates(BB1, BB0)); + EXPECT_FALSE(PDT->dominates(BB2, BB0)); + EXPECT_FALSE(PDT->dominates(BB3, BB0)); + EXPECT_TRUE(PDT->dominates(BB4, BB1)); + + // Dominance descendants. + SmallVector<BasicBlock *, 8> DominatedBBs, PostDominatedBBs; + + DT->getDescendants(BB0, DominatedBBs); + PDT->getDescendants(BB0, PostDominatedBBs); + EXPECT_EQ(DominatedBBs.size(), 4UL); + EXPECT_EQ(PostDominatedBBs.size(), 1UL); + + // BB3 is unreachable. It should have no dominators nor postdominators. + DominatedBBs.clear(); + PostDominatedBBs.clear(); + DT->getDescendants(BB3, DominatedBBs); + DT->getDescendants(BB3, PostDominatedBBs); + EXPECT_EQ(DominatedBBs.size(), 0UL); + EXPECT_EQ(PostDominatedBBs.size(), 0UL); + return false; } virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired<DominatorTree>(); + AU.addRequired<PostDominatorTree>(); } DPass() : FunctionPass(ID) { initializeDPassPass(*PassRegistry::getPassRegistry()); @@ -201,4 +227,5 @@ namespace llvm { INITIALIZE_PASS_BEGIN(DPass, "dpass", "dpass", false, false) INITIALIZE_PASS_DEPENDENCY(DominatorTree) +INITIALIZE_PASS_DEPENDENCY(PostDominatorTree) INITIALIZE_PASS_END(DPass, "dpass", "dpass", false, false) |