aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
diff options
context:
space:
mode:
authorFlorian Hahn <flo@fhahn.com>2025-09-05 16:13:11 +0100
committerGitHub <noreply@github.com>2025-09-05 15:13:11 +0000
commitf8972c8280d28660aaff888c093a9e01b9ee71e6 (patch)
tree0dbcca5260c7b72d3f87bdf3ab09c843e6295a99 /llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
parent85dbe18beef4537dcdfaf9a009b1dd3dbdab608b (diff)
downloadllvm-f8972c8280d28660aaff888c093a9e01b9ee71e6.zip
llvm-f8972c8280d28660aaff888c093a9e01b9ee71e6.tar.gz
llvm-f8972c8280d28660aaff888c093a9e01b9ee71e6.tar.bz2
[SCEVExp] Fix early exit in ComputeEndCheck. (#156910)
ComputeEndCheck incorrectly returned false for unsigned predicates starting at zero and a positive step. The AddRec could still wrap if Step * trunc ExitCount wraps or trunc ExitCount strips leading 1s. Fixes https://github.com/llvm/llvm-project/issues/156849. PR: https://github.com/llvm/llvm-project/pull/156910
Diffstat (limited to 'llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp11
1 files changed, 9 insertions, 2 deletions
diff --git a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
index 3e3d51b..7c12dac 100644
--- a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
+++ b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
@@ -2187,8 +2187,15 @@ Value *SCEVExpander::generateOverflowCheck(const SCEVAddRecExpr *AR,
// negative. If Step is known to be positive or negative, only create
// either 1. or 2.
auto ComputeEndCheck = [&]() -> Value * {
- // Checking <u 0 is always false.
- if (!Signed && Start->isZero() && SE.isKnownPositive(Step))
+ // Checking <u 0 is always false, if (Step * trunc ExitCount) does not wrap.
+ // TODO: Predicates that can be proven true/false should be discarded when
+ // the predicates are created, not late during expansion.
+ if (!Signed && Start->isZero() && SE.isKnownPositive(Step) &&
+ DstBits < SrcBits &&
+ ExitCount == SE.getZeroExtendExpr(SE.getTruncateExpr(ExitCount, ARTy),
+ ExitCount->getType()) &&
+ SE.willNotOverflow(Instruction::Mul, Signed, Step,
+ SE.getTruncateExpr(ExitCount, ARTy)))
return ConstantInt::getFalse(Loc->getContext());
// Get the backedge taken count and truncate or extended to the AR type.