diff options
author | Philip Reames <preames@rivosinc.com> | 2023-03-22 09:51:58 -0700 |
---|---|---|
committer | Philip Reames <listmail@philipreames.com> | 2023-03-22 12:06:28 -0700 |
commit | 6afcc54ac7d68fa2b28f0e7cbf9dc1d4ac7fb95e (patch) | |
tree | 4f4019faab6f912bf36e1e1fc8f0c39800e56506 /llvm/lib/Analysis/ScalarEvolution.cpp | |
parent | 7e5c48b8bd9ff0ee5de3ba28c833f1225f14e44d (diff) | |
download | llvm-6afcc54ac7d68fa2b28f0e7cbf9dc1d4ac7fb95e.zip llvm-6afcc54ac7d68fa2b28f0e7cbf9dc1d4ac7fb95e.tar.gz llvm-6afcc54ac7d68fa2b28f0e7cbf9dc1d4ac7fb95e.tar.bz2 |
[SCEV] Infer no-self-wrap via constant ranges
Without this, pointer IVs in loops with small constant trip counts couldn't be proven no-self-wrap. This came up in a new LSR transform, but may also benefit other SCEV consumers as well.
Differential Revision: https://reviews.llvm.org/D146596
Diffstat (limited to 'llvm/lib/Analysis/ScalarEvolution.cpp')
-rw-r--r-- | llvm/lib/Analysis/ScalarEvolution.cpp | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index df525f4..df872f6 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -4988,6 +4988,18 @@ ScalarEvolution::proveNoWrapViaConstantRanges(const SCEVAddRecExpr *AR) { SCEV::NoWrapFlags Result = SCEV::FlagAnyWrap; + if (!AR->hasNoSelfWrap()) { + const SCEV *BECount = getConstantMaxBackedgeTakenCount(AR->getLoop()); + if (const SCEVConstant *BECountMax = dyn_cast<SCEVConstant>(BECount)) { + ConstantRange StepCR = getSignedRange(AR->getStepRecurrence(*this)); + const APInt &BECountAP = BECountMax->getAPInt(); + unsigned NoOverflowBitWidth = + BECountAP.getActiveBits() + StepCR.getMinSignedBits(); + if (NoOverflowBitWidth <= getTypeSizeInBits(AR->getType())) + Result = ScalarEvolution::setFlags(Result, SCEV::FlagNW); + } + } + if (!AR->hasNoSignedWrap()) { ConstantRange AddRecRange = getSignedRange(AR); ConstantRange IncRange = getSignedRange(AR->getStepRecurrence(*this)); |