diff options
author | Nikita Popov <npopov@redhat.com> | 2023-02-14 15:48:25 +0100 |
---|---|---|
committer | Nikita Popov <npopov@redhat.com> | 2023-02-14 15:56:39 +0100 |
commit | bfbfbd8b65def121ba325c6c68aca09349d119fc (patch) | |
tree | 1e11be4a9d486bc889a4d7e9ab20f7143b4df88e /llvm/lib/Analysis/LazyValueInfo.cpp | |
parent | 0fa5df1959faaf474697fae4fd36b9749b67f815 (diff) | |
download | llvm-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.cpp | 15 |
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(); } |