diff options
author | Florian Hahn <flo@fhahn.com> | 2025-09-05 16:13:11 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-09-05 15:13:11 +0000 |
commit | f8972c8280d28660aaff888c093a9e01b9ee71e6 (patch) | |
tree | 0dbcca5260c7b72d3f87bdf3ab09c843e6295a99 /llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp | |
parent | 85dbe18beef4537dcdfaf9a009b1dd3dbdab608b (diff) | |
download | llvm-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.cpp | 11 |
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. |