diff options
| author | Philip Reames <listmail@philipreames.com> | 2015-09-21 22:04:10 +0000 |
|---|---|---|
| committer | Philip Reames <listmail@philipreames.com> | 2015-09-21 22:04:10 +0000 |
| commit | 963febd4f896457496f18dbb44f25b934b487c06 (patch) | |
| tree | 5e1bffa2e9dcba41f449e814d20e50e1711caa42 /llvm | |
| parent | 4ea00210f2ba9e36451e7b020832a58ecac78aec (diff) | |
| download | bcm5719-llvm-963febd4f896457496f18dbb44f25b934b487c06.tar.gz bcm5719-llvm-963febd4f896457496f18dbb44f25b934b487c06.zip | |
Fix for pr24866
Turns out that not every basic block is guaranteed to have a node within the DominatorTree. This is really hard to trigger, but the test case from the PR managed to do so. There's active discussion continuing about what documentation and/or invariants needed cleaned up.
llvm-svn: 248216
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 9 | ||||
| -rw-r--r-- | llvm/test/Analysis/ValueTracking/pr24866.ll | 44 |
2 files changed, 52 insertions, 1 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 98fbfdc861c..10776a03cae 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -609,6 +609,11 @@ static void computeKnownBitsFromDominatingCondition(Value *V, APInt &KnownZero, if (!Q.DT || !Q.CxtI) return; Instruction *Cxt = const_cast<Instruction *>(Q.CxtI); + // The context instruction might be in a statically unreachable block. If + // so, asking dominator queries may yield suprising results. (e.g. the block + // may not have a dom tree node) + if (!Q.DT->isReachableFromEntry(Cxt->getParent())) + return; // Avoid useless work if (auto VI = dyn_cast<Instruction>(V)) @@ -655,7 +660,9 @@ static void computeKnownBitsFromDominatingCondition(Value *V, APInt &KnownZero, // instruction. Finding a condition where one path dominates the context // isn't enough because both the true and false cases could merge before // the context instruction we're actually interested in. Instead, we need - // to ensure that the taken *edge* dominates the context instruction. + // to ensure that the taken *edge* dominates the context instruction. We + // know that the edge must be reachable since we started from a reachable + // block. BasicBlock *BB0 = BI->getSuccessor(0); BasicBlockEdge Edge(BI->getParent(), BB0); if (!Edge.isSingleEdge() || !Q.DT->dominates(Edge, Q.CxtI->getParent())) diff --git a/llvm/test/Analysis/ValueTracking/pr24866.ll b/llvm/test/Analysis/ValueTracking/pr24866.ll new file mode 100644 index 00000000000..b146b4ac056 --- /dev/null +++ b/llvm/test/Analysis/ValueTracking/pr24866.ll @@ -0,0 +1,44 @@ +; RUN: opt -S %s -value-tracking-dom-conditions -licm -load-combine | FileCheck %s +; In pr24866.ll, we saw a crash when accessing a nullptr returned when +; asking for a dominator tree Node. This reproducer is really fragile, +; but it's currently the best we have. + +%struct.c_derived_tbl.2.5.8.11.14.17.23.38.59.80.92.98.104.107.155.183 = type { [256 x i32], [256 x i8] } + + +; Function Attrs: nounwind uwtable +define void @encode_one_blockX2(%struct.c_derived_tbl.2.5.8.11.14.17.23.38.59.80.92.98.104.107.155.183* nocapture readonly %actbl) #0 { +; CHECK-LABEL: @encode_one_blockX2 +entry: + br i1 false, label %L_KLOOP_01, label %L_KLOOP.preheader + +L_KLOOP_01: ; preds = %while.end, %entry + br label %L_KLOOP.preheader + +L_KLOOP_08: ; preds = %while.end + br label %L_KLOOP.preheader + +L_KLOOP.preheader: ; preds = %L_KLOOP_08, %L_KLOOP_01, %entry + %r.2.ph = phi i32 [ undef, %L_KLOOP_08 ], [ 0, %entry ], [ undef, %L_KLOOP_01 ] + br label %L_KLOOP + +L_KLOOP: ; preds = %while.end, %L_KLOOP.preheader + %r.2 = phi i32 [ 0, %while.end ], [ %r.2.ph, %L_KLOOP.preheader ] + br i1 true, label %while.body, label %while.end + +while.body: ; preds = %while.body, %L_KLOOP + br label %while.body + +while.end: ; preds = %L_KLOOP + %shl105 = shl i32 %r.2, 4 + %add106 = add nsw i32 %shl105, undef + %idxprom107 = sext i32 %add106 to i64 + %arrayidx108 = getelementptr inbounds %struct.c_derived_tbl.2.5.8.11.14.17.23.38.59.80.92.98.104.107.155.183, %struct.c_derived_tbl.2.5.8.11.14.17.23.38.59.80.92.98.104.107.155.183* %actbl, i64 0, i32 0, i64 %idxprom107 + %0 = load i32, i32* %arrayidx108, align 4 + %arrayidx110 = getelementptr inbounds %struct.c_derived_tbl.2.5.8.11.14.17.23.38.59.80.92.98.104.107.155.183, %struct.c_derived_tbl.2.5.8.11.14.17.23.38.59.80.92.98.104.107.155.183* %actbl, i64 0, i32 1, i64 %idxprom107 + %1 = load i8, i8* %arrayidx110, align 1 + indirectbr i8* undef, [label %L_KLOOP_DONE, label %L_KLOOP_01, label %L_KLOOP_08, label %L_KLOOP] + +L_KLOOP_DONE: ; preds = %while.end + ret void +} |

