aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/LazyValueInfo.cpp
diff options
context:
space:
mode:
authorNikita Popov <npopov@redhat.com>2023-02-14 15:48:25 +0100
committerNikita Popov <npopov@redhat.com>2023-02-14 15:56:39 +0100
commitbfbfbd8b65def121ba325c6c68aca09349d119fc (patch)
tree1e11be4a9d486bc889a4d7e9ab20f7143b4df88e /llvm/lib/Analysis/LazyValueInfo.cpp
parent0fa5df1959faaf474697fae4fd36b9749b67f815 (diff)
downloadllvm-bfbfbd8b65def121ba325c6c68aca09349d119fc.zip
llvm-bfbfbd8b65def121ba325c6c68aca09349d119fc.tar.gz
llvm-bfbfbd8b65def121ba325c6c68aca09349d119fc.tar.bz2
[LVI] Fix and re-enable at-use reasoning (PR60629)
This fixes the handling of phi nodes in getConstantRangeAtUse() and re-enables it, reverting the workaround from c77c186a647b385c291ddabecd70a2b4f84ae342. For phi nodes, while we can make use of the edge condition for the incoming value, we shouldn't look past the phi node to look for further conditions, because we might be reasoning about values from two different cycle iterations (which will have the same SSA value). To handle this more specifically we would have to detect cycles, and there doesn't seem to be any motivating case for that at this point.
Diffstat (limited to 'llvm/lib/Analysis/LazyValueInfo.cpp')
-rw-r--r--llvm/lib/Analysis/LazyValueInfo.cpp15
1 files changed, 8 insertions, 7 deletions
diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp
index efe878d..944b4a2 100644
--- a/llvm/lib/Analysis/LazyValueInfo.cpp
+++ b/llvm/lib/Analysis/LazyValueInfo.cpp
@@ -1662,7 +1662,7 @@ ConstantRange LazyValueInfo::getConstantRangeAtUse(const Use &U,
// position where V can be constrained by a select or branch condition.
const Use *CurrU = &U;
// TODO: Increase limit?
- const unsigned MaxUsesToInspect = 0;
+ const unsigned MaxUsesToInspect = 3;
for (unsigned I = 0; I < MaxUsesToInspect; ++I) {
std::optional<ValueLatticeElement> CondVal;
auto *CurrI = cast<Instruction>(CurrU->getUser());
@@ -1675,11 +1675,6 @@ ConstantRange LazyValueInfo::getConstantRangeAtUse(const Use &U,
// TODO: Use non-local query?
CondVal =
getEdgeValueLocal(V, PHI->getIncomingBlock(*CurrU), PHI->getParent());
- } else if (!isSafeToSpeculativelyExecute(CurrI)) {
- // Stop walking if we hit a non-speculatable instruction. Even if the
- // result is only used under a specific condition, executing the
- // instruction itself may cause side effects or UB already.
- break;
}
if (CondVal && CondVal->isConstantRange())
CR = CR.intersectWith(CondVal->getConstantRange());
@@ -1687,7 +1682,13 @@ ConstantRange LazyValueInfo::getConstantRangeAtUse(const Use &U,
// Only follow one-use chain, to allow direct intersection of conditions.
// If there are multiple uses, we would have to intersect with the union of
// all conditions at different uses.
- if (!CurrI->hasOneUse())
+ // Stop walking if we hit a non-speculatable instruction. Even if the
+ // result is only used under a specific condition, executing the
+ // instruction itself may cause side effects or UB already.
+ // This also disallows looking through phi nodes: If the phi node is part
+ // of a cycle, we might end up reasoning about values from different cycle
+ // iterations (PR60629).
+ if (!CurrI->hasOneUse() || !isSafeToSpeculativelyExecute(CurrI))
break;
CurrU = &*CurrI->use_begin();
}