aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ScalarEvolution.cpp
diff options
context:
space:
mode:
authorFlorian Hahn <flo@fhahn.com>2024-10-14 13:08:49 +0100
committerGitHub <noreply@github.com>2024-10-14 13:08:49 +0100
commit7f06d8afb03383dea33379f9c06d010d6ee3f14e (patch)
tree53376eb946a3e013db376a128455c5de24164ac0 /llvm/lib/Analysis/ScalarEvolution.cpp
parent9cc6d6e9a96bda923ff7e7bb7394dfb4d2319b07 (diff)
downloadllvm-7f06d8afb03383dea33379f9c06d010d6ee3f14e.zip
llvm-7f06d8afb03383dea33379f9c06d010d6ee3f14e.tar.gz
llvm-7f06d8afb03383dea33379f9c06d010d6ee3f14e.tar.bz2
[SCEV] Retain SCEVSequentialMinMaxExpr if an operand may trigger UB. (#110824)
Retain SCEVSequentialMinMaxExpr if an operand may trigger UB, e.g. if there is an UDiv operand that may divide by 0 or poison PR: https://github.com/llvm/llvm-project/pull/110824
Diffstat (limited to 'llvm/lib/Analysis/ScalarEvolution.cpp')
-rw-r--r--llvm/lib/Analysis/ScalarEvolution.cpp17
1 files changed, 16 insertions, 1 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index cea3a5b..97ea405 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -4200,7 +4200,7 @@ bool ScalarEvolution::canReuseInstruction(
// Either the value can't be poison, or the S would also be poison if it
// is.
- if (PoisonVals.contains(V) || isGuaranteedNotToBePoison(V))
+ if (PoisonVals.contains(V) || ::isGuaranteedNotToBePoison(V))
continue;
auto *I = dyn_cast<Instruction>(V);
@@ -4303,6 +4303,16 @@ ScalarEvolution::getSequentialMinMaxExpr(SCEVTypes Kind,
}
for (unsigned i = 1, e = Ops.size(); i != e; ++i) {
+ bool MayBeUB = SCEVExprContains(Ops[i], [this](const SCEV *S) {
+ auto *UDiv = dyn_cast<SCEVUDivExpr>(S);
+ // The UDiv may be UB if the divisor is poison or zero. Unless the divisor
+ // is a non-zero constant, we have to assume the UDiv may be UB.
+ return UDiv && (!isKnownNonZero(UDiv->getOperand(1)) ||
+ !isGuaranteedNotToBePoison(UDiv->getOperand(1)));
+ });
+
+ if (MayBeUB)
+ continue;
// We can replace %x umin_seq %y with %x umin %y if either:
// * %y being poison implies %x is also poison.
// * %x cannot be the saturating value (e.g. zero for umin).
@@ -7298,6 +7308,11 @@ bool ScalarEvolution::isGuaranteedToTransferExecutionTo(const Instruction *A,
return false;
}
+bool ScalarEvolution::isGuaranteedNotToBePoison(const SCEV *Op) {
+ SCEVPoisonCollector PC(/* LookThroughMaybePoisonBlocking */ true);
+ visitAll(Op, PC);
+ return PC.MaybePoison.empty();
+}
bool ScalarEvolution::isSCEVExprNeverPoison(const Instruction *I) {
// Only proceed if we can prove that I does not yield poison.