aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
diff options
context:
space:
mode:
authorFlorian Hahn <flo@fhahn.com>2024-02-10 18:11:17 +0000
committerGitHub <noreply@github.com>2024-02-10 18:11:17 +0000
commitdce77a357948709e335910ddc07f9c3f2eb2ac4b (patch)
tree703fc1bd758e10d5ece9148c92ef9cbb466c399a /llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
parentd2e4a725da5b4cbef8b5c1446f29fed1487aeab0 (diff)
downloadllvm-dce77a357948709e335910ddc07f9c3f2eb2ac4b.zip
llvm-dce77a357948709e335910ddc07f9c3f2eb2ac4b.tar.gz
llvm-dce77a357948709e335910ddc07f9c3f2eb2ac4b.tar.bz2
[IndVars] Preserve flags of narrow IV inc if replacing with wider inc. (#80446)
We are replacing a narrow IV increment with a wider one. If the original (narrow) increment did not wrap, the wider one should not wrap either. Set the flags to be the union of both wide increment and original increment; this ensures we preserve flags SCEV could infer for the wider increment. Fixes https://github.com/llvm/llvm-project/issues/71517.
Diffstat (limited to 'llvm/lib/Transforms/Utils/SimplifyIndVar.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/SimplifyIndVar.cpp21
1 files changed, 21 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
index 1b142f1..5aa6df4 100644
--- a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
@@ -1985,7 +1985,28 @@ PHINode *WidenIV::createWideIV(SCEVExpander &Rewriter) {
// increment to the new (widened) increment.
auto *OrigInc =
cast<Instruction>(OrigPhi->getIncomingValueForBlock(LatchBlock));
+
WideInc->setDebugLoc(OrigInc->getDebugLoc());
+ // We are replacing a narrow IV increment with a wider IV increment. If
+ // the original (narrow) increment did not wrap, the wider increment one
+ // should not wrap either. Set the flags to be the union of both wide
+ // increment and original increment; this ensures we preserve flags SCEV
+ // could infer for the wider increment. Limit this only to cases where
+ // both increments directly increment the corresponding PHI nodes and have
+ // the same opcode. It is not safe to re-use the flags from the original
+ // increment, if it is more complex and SCEV expansion may have yielded a
+ // more simplified wider increment.
+ bool MatchingOps =
+ match(OrigInc, m_c_BinOp(m_Specific(OrigPhi), m_Value())) &&
+ match(WideInc, m_c_BinOp(m_Specific(WidePhi), m_Value())) &&
+ OrigInc->getOpcode() == WideInc->getOpcode();
+ if (MatchingOps && isa<OverflowingBinaryOperator>(OrigInc) &&
+ isa<OverflowingBinaryOperator>(WideInc)) {
+ WideInc->setHasNoUnsignedWrap(WideInc->hasNoUnsignedWrap() ||
+ OrigInc->hasNoUnsignedWrap());
+ WideInc->setHasNoSignedWrap(WideInc->hasNoSignedWrap() ||
+ OrigInc->hasNoSignedWrap());
+ }
}
}