summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorSerguei Katkov <serguei.katkov@azul.com>2018-05-23 05:54:55 +0000
committerSerguei Katkov <serguei.katkov@azul.com>2018-05-23 05:54:55 +0000
commit46ef8fffdf6409fb520ce614146b18fd98c0010e (patch)
treea83bdc8846d24bab88696989d795fd7cd10d48e6 /llvm/lib
parent39e0347e6a0a3c2f29f427e755de75358b2d7bbb (diff)
downloadbcm5719-llvm-46ef8fffdf6409fb520ce614146b18fd98c0010e.tar.gz
bcm5719-llvm-46ef8fffdf6409fb520ce614146b18fd98c0010e.zip
SafepointIRVerifier is made unreachable block tolerant
SafepointIRVerifier crashed while traversing blocks without a DomTreeNode. This could happen with a custom pipeline or when some optional passes were skipped by OptBisect. SafepointIRVerifier is fixed to traverse basic blocks that are reachable from entry. Test are added. Patch Author: Yevgeny Rouban! Reviewers: anna, reames, dneilson, DaniilSuchkov, skatkov Reviewed By: reames Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D47011 llvm-svn: 333063
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/IR/SafepointIRVerifier.cpp27
1 files changed, 20 insertions, 7 deletions
diff --git a/llvm/lib/IR/SafepointIRVerifier.cpp b/llvm/lib/IR/SafepointIRVerifier.cpp
index 25a7f8d6d51..8de18c0fb34 100644
--- a/llvm/lib/IR/SafepointIRVerifier.cpp
+++ b/llvm/lib/IR/SafepointIRVerifier.cpp
@@ -318,6 +318,12 @@ public:
static void verifyFunction(GCPtrTracker &&Tracker,
InstructionVerifier &Verifier);
+ /// Returns true for reachable blocks that are verified, the other blocks are
+ /// ignored.
+ bool isMapped(const BasicBlock *BB) const {
+ return BlockMap.find(BB) != BlockMap.end();
+ }
+
private:
/// Returns true if the instruction may be safely skipped during verification.
bool instructionMayBeSkipped(const Instruction *I) const;
@@ -374,12 +380,13 @@ private:
GCPtrTracker::GCPtrTracker(const Function &F, const DominatorTree &DT) : F(F) {
// First, calculate Contribution of each BB.
- for (const BasicBlock &BB : F) {
- BasicBlockState *BBS = new (BSAllocator.Allocate()) BasicBlockState;
- for (const auto &I : BB)
- transferInstruction(I, BBS->Cleared, BBS->Contribution);
- BlockMap[&BB] = BBS;
- }
+ for (const BasicBlock &BB : F)
+ if (DT.isReachableFromEntry(&BB)) {
+ BasicBlockState *BBS = new (BSAllocator.Allocate()) BasicBlockState;
+ for (const auto &I : BB)
+ transferInstruction(I, BBS->Cleared, BBS->Contribution);
+ BlockMap[&BB] = BBS;
+ }
// Initialize AvailableIn/Out sets of each BB using only information about
// dominating BBs.
@@ -452,7 +459,8 @@ void GCPtrTracker::recalculateBBsStates() {
size_t OldInCount = BBS->AvailableIn.size();
for (const BasicBlock *PBB : predecessors(BB))
- set_intersect(BBS->AvailableIn, BlockMap[PBB]->AvailableOut);
+ if (isMapped(PBB))
+ set_intersect(BBS->AvailableIn, BlockMap[PBB]->AvailableOut);
assert(OldInCount >= BBS->AvailableIn.size() && "invariant!");
@@ -491,6 +499,8 @@ bool GCPtrTracker::removeValidUnrelocatedDefs(const BasicBlock *BB,
bool HasUnrelocatedInputs = false;
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
const BasicBlock *InBB = PN->getIncomingBlock(i);
+ if (!isMapped(InBB))
+ continue;
const Value *InValue = PN->getIncomingValue(i);
if (isNotExclusivelyConstantDerived(InValue)) {
@@ -560,6 +570,7 @@ void GCPtrTracker::gatherDominatingDefs(const BasicBlock *BB,
const DominatorTree &DT) {
DomTreeNode *DTN = DT[const_cast<BasicBlock *>(BB)];
+ assert(DTN && "Unreachable blocks are ignored");
while (DTN->getIDom()) {
DTN = DTN->getIDom();
const auto &Defs = BlockMap[DTN->getBlock()]->Contribution;
@@ -617,6 +628,8 @@ void InstructionVerifier::verifyInstruction(
if (containsGCPtrType(PN->getType()))
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
const BasicBlock *InBB = PN->getIncomingBlock(i);
+ if (!Tracker->isMapped(InBB))
+ continue;
const Value *InValue = PN->getIncomingValue(i);
if (isNotExclusivelyConstantDerived(InValue) &&
OpenPOWER on IntegriCloud