[llvm] 0a4d3ea - [LVI] Check for non-speculatable instructions
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Fri Jan 13 07:10:21 PST 2023
Author: Nikita Popov
Date: 2023-01-13T16:10:12+01:00
New Revision: 0a4d3eae335c1d4dc5bd9a440af4b66ccb9d0084
URL: https://github.com/llvm/llvm-project/commit/0a4d3eae335c1d4dc5bd9a440af4b66ccb9d0084
DIFF: https://github.com/llvm/llvm-project/commit/0a4d3eae335c1d4dc5bd9a440af4b66ccb9d0084.diff
LOG: [LVI] Check for non-speculatable instructions
When constraining an operand based on a condition at a (potentially
transitive) use site, make sure we don't skip over non-speculatable
instructions. While the result is only used under the condition,
the non-speculatable instruction may have a side-effect or UB.
Demonstrating this issue requires raising the limit on the walk,
so do that.
Added:
Modified:
llvm/lib/Analysis/LazyValueInfo.cpp
llvm/test/Transforms/CorrelatedValuePropagation/cond-at-use.ll
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp
index d49e18a8cea18..f1587cecf9fbd 100644
--- a/llvm/lib/Analysis/LazyValueInfo.cpp
+++ b/llvm/lib/Analysis/LazyValueInfo.cpp
@@ -1660,7 +1660,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 = 2;
+ const unsigned MaxUsesToInspect = 3;
for (unsigned I = 0; I < MaxUsesToInspect; ++I) {
std::optional<ValueLatticeElement> CondVal;
auto *CurrI = cast<Instruction>(CurrU->getUser());
@@ -1673,6 +1673,11 @@ 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());
diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/cond-at-use.ll b/llvm/test/Transforms/CorrelatedValuePropagation/cond-at-use.ll
index fb1a03c1aa444..58d71b46ab180 100644
--- a/llvm/test/Transforms/CorrelatedValuePropagation/cond-at-use.ll
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/cond-at-use.ll
@@ -74,12 +74,10 @@ define i16 @sel_true_cond_extra_use(i16 %x) {
ret i16 %sel
}
-; TODO: We could handle this case by raising the limit on the number of
-; instructions we look through.
define i16 @sel_true_cond_chain_speculatable(i16 %x) {
; CHECK-LABEL: @sel_true_cond_chain_speculatable(
-; CHECK-NEXT: [[SUB:%.*]] = call i16 @llvm.uadd.sat.i16(i16 [[X:%.*]], i16 1)
-; CHECK-NEXT: [[EXTRA:%.*]] = mul i16 [[SUB]], 3
+; CHECK-NEXT: [[SUB1:%.*]] = add nuw i16 [[X:%.*]], 1
+; CHECK-NEXT: [[EXTRA:%.*]] = mul i16 [[SUB1]], 3
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i16 [[X]], -1
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i16 [[EXTRA]], i16 42
; CHECK-NEXT: ret i16 [[SEL]]
@@ -106,6 +104,8 @@ define i16 @sel_true_cond_chain_non_speculatable(i16 %x) {
ret i16 %sel
}
+; TODO: We could handle this case by raising the limit on the number of
+; instructions we look through.
define i16 @sel_true_cond_longer_chain(i16 %x) {
; CHECK-LABEL: @sel_true_cond_longer_chain(
; CHECK-NEXT: [[SUB:%.*]] = call i16 @llvm.uadd.sat.i16(i16 [[X:%.*]], i16 1)
More information about the llvm-commits
mailing list