aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ScalarEvolution.cpp
diff options
context:
space:
mode:
authorPhilip Reames <preames@rivosinc.com>2023-03-22 09:51:58 -0700
committerPhilip Reames <listmail@philipreames.com>2023-03-22 12:06:28 -0700
commit6afcc54ac7d68fa2b28f0e7cbf9dc1d4ac7fb95e (patch)
tree4f4019faab6f912bf36e1e1fc8f0c39800e56506 /llvm/lib/Analysis/ScalarEvolution.cpp
parent7e5c48b8bd9ff0ee5de3ba28c833f1225f14e44d (diff)
downloadllvm-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.cpp12
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));