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.

llvm-svn: 196099
This commit is contained in:
Diego Novillo 2013-12-02 14:08:27 +00:00
parent c0378e72d1
commit ee592429f1
2 changed files with 30 additions and 1 deletions

View File

@ -348,10 +348,12 @@ public:
/// Get all nodes dominated by R, including R itself. /// Get all nodes dominated by R, including R itself.
void getDescendants(NodeT *R, SmallVectorImpl<NodeT *> &Result) const { void getDescendants(NodeT *R, SmallVectorImpl<NodeT *> &Result) const {
Result.clear();
const DomTreeNodeBase<NodeT> *RN = getNode(R); 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; SmallVector<const DomTreeNodeBase<NodeT> *, 8> WL;
WL.push_back(RN); WL.push_back(RN);
Result.clear();
while (!WL.empty()) { while (!WL.empty()) {
const DomTreeNodeBase<NodeT> *N = WL.pop_back_val(); const DomTreeNodeBase<NodeT> *N = WL.pop_back_val();

View File

@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/Analysis/Dominators.h" #include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/PostDominators.h"
#include "llvm/Assembly/Parser.h" #include "llvm/Assembly/Parser.h"
#include "llvm/IR/Instructions.h" #include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h" #include "llvm/IR/LLVMContext.h"
@ -26,6 +27,7 @@ namespace llvm {
static char ID; static char ID;
virtual bool runOnFunction(Function &F) { virtual bool runOnFunction(Function &F) {
DominatorTree *DT = &getAnalysis<DominatorTree>(); DominatorTree *DT = &getAnalysis<DominatorTree>();
PostDominatorTree *PDT = &getAnalysis<PostDominatorTree>();
Function::iterator FI = F.begin(); Function::iterator FI = F.begin();
BasicBlock *BB0 = FI++; BasicBlock *BB0 = FI++;
@ -148,10 +150,34 @@ namespace llvm {
EXPECT_TRUE(DT->dominates(Y6, BB3)); 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; return false;
} }
virtual void getAnalysisUsage(AnalysisUsage &AU) const { virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<DominatorTree>(); AU.addRequired<DominatorTree>();
AU.addRequired<PostDominatorTree>();
} }
DPass() : FunctionPass(ID) { DPass() : FunctionPass(ID) {
initializeDPassPass(*PassRegistry::getPassRegistry()); initializeDPassPass(*PassRegistry::getPassRegistry());
@ -201,4 +227,5 @@ namespace llvm {
INITIALIZE_PASS_BEGIN(DPass, "dpass", "dpass", false, false) INITIALIZE_PASS_BEGIN(DPass, "dpass", "dpass", false, false)
INITIALIZE_PASS_DEPENDENCY(DominatorTree) INITIALIZE_PASS_DEPENDENCY(DominatorTree)
INITIALIZE_PASS_DEPENDENCY(PostDominatorTree)
INITIALIZE_PASS_END(DPass, "dpass", "dpass", false, false) INITIALIZE_PASS_END(DPass, "dpass", "dpass", false, false)