diff options
author | Florian Hahn <flo@fhahn.com> | 2024-10-14 13:08:49 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-10-14 13:08:49 +0100 |
commit | 7f06d8afb03383dea33379f9c06d010d6ee3f14e (patch) | |
tree | 53376eb946a3e013db376a128455c5de24164ac0 /llvm/lib/Analysis/ScalarEvolution.cpp | |
parent | 9cc6d6e9a96bda923ff7e7bb7394dfb4d2319b07 (diff) | |
download | llvm-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.cpp | 17 |
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. |