[llvm] [WIP][ScalarEvolution] Limit recursion in getRangeRef for PHI nodes. (PR #152823)
Eli Friedman via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 8 20:39:58 PDT 2025
https://github.com/efriedma-quic created https://github.com/llvm/llvm-project/pull/152823
Restrict PHI nodes that getRangeRef is allowed to recursively examine so we don't need a "visited" set. And fix createSCEVIter so it creates all the relevant SCEV nodes before getRangeRef tries to examine them.
The tests that are affected have induction variables that aren't AddRecs. (Other cases are theoretically affected, but don't seem to show up in our tests.)
>From 1f02eb76ccbade4c0762df15a06f4bfce7045a57 Mon Sep 17 00:00:00 2001
From: Eli Friedman <efriedma at quicinc.com>
Date: Fri, 8 Aug 2025 19:43:09 -0700
Subject: [PATCH] [WIP][ScalarEvolution] Limit recursion in getRangeRef for PHI
nodes.
Restrict PHI nodes that getRangeRef is allowed to recursively examine so
we don't need a "visited" set. And fix createSCEVIter so it creates all
the relevant SCEV nodes before getRangeRef tries to examine them.
The tests that are affected have induction variables that aren't
AddRecs. (Other cases are theoretically affected, but don't seem to
show up in our tests.)
---
llvm/include/llvm/Analysis/ScalarEvolution.h | 6 -
llvm/lib/Analysis/ScalarEvolution.cpp | 141 ++++++++++++++----
...drec-computed-during-addrec-calculation.ll | 12 +-
.../Analysis/ScalarEvolution/outer_phi.ll | 2 +-
.../test/Analysis/ScalarEvolution/pr123550.ll | 2 +-
llvm/test/Analysis/ScalarEvolution/pr49856.ll | 2 +-
.../pr58402-large-number-of-zext-exprs.ll | 2 +-
llvm/test/Analysis/ScalarEvolution/ranges.ll | 10 +-
.../ScalarEvolution/shift-recurrences.ll | 16 +-
.../LICM/update-scev-after-hoist.ll | 4 +-
.../LoopVectorize/create-induction-resume.ll | 2 +-
11 files changed, 135 insertions(+), 64 deletions(-)
diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h
index 167845ce646b9..0ba707e12666f 100644
--- a/llvm/include/llvm/Analysis/ScalarEvolution.h
+++ b/llvm/include/llvm/Analysis/ScalarEvolution.h
@@ -1500,12 +1500,6 @@ class ScalarEvolution {
/// Mark predicate values currently being processed by isImpliedCond.
SmallPtrSet<const Value *, 6> PendingLoopPredicates;
- /// Mark SCEVUnknown Phis currently being processed by getRangeRef.
- SmallPtrSet<const PHINode *, 6> PendingPhiRanges;
-
- /// Mark SCEVUnknown Phis currently being processed by getRangeRefIter.
- SmallPtrSet<const PHINode *, 6> PendingPhiRangesIter;
-
// Mark SCEVUnknown Phis currently being processed by isImpliedViaMerge.
SmallPtrSet<const PHINode *, 6> PendingMerges;
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 0990a0daac80c..98f4cf40a5718 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -5963,7 +5963,9 @@ static bool BrPHIToSelect(DominatorTree &DT, BranchInst *BI, PHINode *Merge,
return false;
}
-const SCEV *ScalarEvolution::createNodeFromSelectLikePHI(PHINode *PN) {
+static bool getOperandsForSelectLikePHI(DominatorTree &DT, PHINode *PN,
+ Value *&Cond, Value *&LHS,
+ Value *&RHS) {
auto IsReachable =
[&](BasicBlock *BB) { return DT.isReachableFromEntry(BB); };
if (PN->getNumIncomingValues() == 2 && all_of(PN->blocks(), IsReachable)) {
@@ -5983,29 +5985,23 @@ const SCEV *ScalarEvolution::createNodeFromSelectLikePHI(PHINode *PN) {
assert(IDom && "At least the entry block should dominate PN");
auto *BI = dyn_cast<BranchInst>(IDom->getTerminator());
- Value *Cond = nullptr, *LHS = nullptr, *RHS = nullptr;
-
- if (BI && BI->isConditional() &&
- BrPHIToSelect(DT, BI, PN, Cond, LHS, RHS) &&
- properlyDominates(getSCEV(LHS), PN->getParent()) &&
- properlyDominates(getSCEV(RHS), PN->getParent()))
- return createNodeForSelectOrPHI(PN, Cond, LHS, RHS);
+ return BI && BI->isConditional() &&
+ BrPHIToSelect(DT, BI, PN, Cond, LHS, RHS);
}
+ return false;
+}
+
+const SCEV *ScalarEvolution::createNodeFromSelectLikePHI(PHINode *PN) {
+ Value *Cond = nullptr, *LHS = nullptr, *RHS = nullptr;
+ if (getOperandsForSelectLikePHI(DT, PN, Cond, LHS, RHS) &&
+ properlyDominates(getSCEV(LHS), PN->getParent()) &&
+ properlyDominates(getSCEV(RHS), PN->getParent()))
+ return createNodeForSelectOrPHI(PN, Cond, LHS, RHS);
return nullptr;
}
-/// Returns SCEV for the first operand of a phi if all phi operands have
-/// identical opcodes and operands
-/// eg.
-/// a: %add = %a + %b
-/// br %c
-/// b: %add1 = %a + %b
-/// br %c
-/// c: %phi = phi [%add, a], [%add1, b]
-/// scev(%phi) => scev(%add)
-const SCEV *
-ScalarEvolution::createNodeForPHIWithIdenticalOperands(PHINode *PN) {
+static BinaryOperator *getCommonInstForPHI(PHINode *PN) {
BinaryOperator *CommonInst = nullptr;
// Check if instructions are identical.
for (Value *Incoming : PN->incoming_values()) {
@@ -6020,6 +6016,21 @@ ScalarEvolution::createNodeForPHIWithIdenticalOperands(PHINode *PN) {
CommonInst = IncomingInst;
}
}
+ return CommonInst;
+}
+
+/// Returns SCEV for the first operand of a phi if all phi operands have
+/// identical opcodes and operands
+/// eg.
+/// a: %add = %a + %b
+/// br %c
+/// b: %add1 = %a + %b
+/// br %c
+/// c: %phi = phi [%add, a], [%add1, b]
+/// scev(%phi) => scev(%add)
+const SCEV *
+ScalarEvolution::createNodeForPHIWithIdenticalOperands(PHINode *PN) {
+ BinaryOperator *CommonInst = getCommonInstForPHI(PN);
if (!CommonInst)
return nullptr;
@@ -6544,6 +6555,28 @@ getRangeForUnknownRecurrence(const SCEVUnknown *U) {
return FullSet;
}
+// The goal of this function is to check if recursively visiting the operands
+// of this PHI might lead to an infinite loop. If we do see such a loop,
+// there's no good way to break it, so we avoid analyzing such cases.
+//
+// getRangeRef previously used a visited set to avoid infinite loops, but this
+// caused other issues: the result was dependent on the order of getRangeRef
+// calls, and the interaction with createSCEVIter could cause a stack overflow
+// in some cases (see issue #148253).
+//
+// FIXME: The way this is implemented is overly conservative.
+static bool RangeRefPHIAllowedOperands(DominatorTree &DT, PHINode *PH) {
+ Value *Cond = nullptr, *LHS = nullptr, *RHS = nullptr;
+ if (getOperandsForSelectLikePHI(DT, PH, Cond, LHS, RHS))
+ return true;
+
+ if (all_of(PH->operands(),
+ [&](Value *Operand) { return DT.dominates(Operand, PH); }))
+ return true;
+
+ return false;
+}
+
const ConstantRange &
ScalarEvolution::getRangeRefIter(const SCEV *S,
ScalarEvolution::RangeSignHint SignHint) {
@@ -6599,8 +6632,8 @@ ScalarEvolution::getRangeRefIter(const SCEV *S,
continue;
}
// `SCEVUnknown`'s require special treatment.
- if (const PHINode *P = dyn_cast<PHINode>(UnknownS->getValue())) {
- if (!PendingPhiRangesIter.insert(P).second)
+ if (PHINode *P = dyn_cast<PHINode>(UnknownS->getValue())) {
+ if (!RangeRefPHIAllowedOperands(DT, P))
continue;
for (auto &Op : reverse(P->operands()))
AddToWorklist(getSCEV(Op));
@@ -6613,10 +6646,6 @@ ScalarEvolution::getRangeRefIter(const SCEV *S,
// their users in most cases.
for (const SCEV *P : reverse(drop_begin(WorkList))) {
getRangeRef(P, SignHint);
-
- if (auto *UnknownS = dyn_cast<SCEVUnknown>(P))
- if (const PHINode *P = dyn_cast<PHINode>(UnknownS->getValue()))
- PendingPhiRangesIter.erase(P);
}
}
@@ -6926,8 +6955,13 @@ const ConstantRange &ScalarEvolution::getRangeRef(
// A range of Phi is a subset of union of all ranges of its input.
if (PHINode *Phi = dyn_cast<PHINode>(V)) {
+ // SCEVExpander sometimes creates SCEVUnknowns that are secretly
+ // AddRecs; return the range for the corresponding AddRec.
+ if (auto *AR = dyn_cast<SCEVAddRecExpr>(getSCEV(V)))
+ return getRangeRef(AR, SignHint, Depth + 1);
+
// Make sure that we do not run over cycled Phis.
- if (PendingPhiRanges.insert(Phi).second) {
+ if (RangeRefPHIAllowedOperands(DT, Phi)) {
ConstantRange RangeFromOps(BitWidth, /*isFullSet=*/false);
for (const auto &Op : Phi->operands()) {
@@ -6939,9 +6973,6 @@ const ConstantRange &ScalarEvolution::getRangeRef(
}
ConservativeResult =
ConservativeResult.intersectWith(RangeFromOps, RangeType);
- bool Erased = PendingPhiRanges.erase(Phi);
- assert(Erased && "Failed to erase Phi properly?");
- (void)Erased;
}
}
@@ -7612,7 +7643,55 @@ ScalarEvolution::getOperandsToCreate(Value *V, SmallVectorImpl<Value *> &Ops) {
return getUnknown(V);
case Instruction::PHI:
- // Keep constructing SCEVs' for phis recursively for now.
+ // getNodeForPHI has four ways to turn a PHI into a SCEV; retrieve the
+ // relevant nodes for each of them.
+ //
+ // The first is just to call simplifyInstruction, and get something back
+ // that isn't a PHI.
+ if (Value *V = simplifyInstruction(
+ cast<PHINode>(U),
+ {getDataLayout(), &TLI, &DT, &AC, /*CtxI=*/nullptr,
+ /*UseInstrInfo=*/true, /*CanUseUndef=*/false})) {
+ assert(V);
+ Ops.push_back(V);
+ return nullptr;
+ }
+ // The second is createNodeForPHIWithIdenticalOperands: this looks for
+ // operands which all perform the same operation, but haven't been
+ // CSE'ed for whatever reason.
+ if (BinaryOperator *BO = getCommonInstForPHI(cast<PHINode>(U))) {
+ assert(BO);
+ Ops.push_back(BO);
+ return nullptr;
+ }
+ // The third is createNodeFromSelectLikePHI; this takes a PHI which
+ // is equivalent to a select, and analyzes it like a select.
+ {
+ Value *Cond = nullptr, *LHS = nullptr, *RHS = nullptr;
+ if (getOperandsForSelectLikePHI(DT, cast<PHINode>(U), Cond, LHS, RHS)) {
+ assert(Cond);
+ assert(LHS);
+ assert(RHS);
+ if (auto *CondICmp = dyn_cast<ICmpInst>(Cond)) {
+ Ops.push_back(CondICmp->getOperand(0));
+ Ops.push_back(CondICmp->getOperand(1));
+ }
+ Ops.push_back(Cond);
+ Ops.push_back(LHS);
+ Ops.push_back(RHS);
+ return nullptr;
+ }
+ }
+ // The fourth way is createAddRecFromPHI. It's complicated to handle here,
+ // so just construct it recursively.
+ //
+ // In addition to getNodeForPHI, also construct nodes which might be needed
+ // by getRangeRef.
+ if (RangeRefPHIAllowedOperands(DT, cast<PHINode>(U))) {
+ for (Value *V : cast<PHINode>(U)->operands())
+ Ops.push_back(V);
+ return nullptr;
+ }
return nullptr;
case Instruction::Select: {
@@ -13683,7 +13762,6 @@ ScalarEvolution::ScalarEvolution(ScalarEvolution &&Arg)
DT(Arg.DT), LI(Arg.LI), CouldNotCompute(std::move(Arg.CouldNotCompute)),
ValueExprMap(std::move(Arg.ValueExprMap)),
PendingLoopPredicates(std::move(Arg.PendingLoopPredicates)),
- PendingPhiRanges(std::move(Arg.PendingPhiRanges)),
PendingMerges(std::move(Arg.PendingMerges)),
ConstantMultipleCache(std::move(Arg.ConstantMultipleCache)),
BackedgeTakenCounts(std::move(Arg.BackedgeTakenCounts)),
@@ -13726,7 +13804,6 @@ ScalarEvolution::~ScalarEvolution() {
PredicatedBackedgeTakenCounts.clear();
assert(PendingLoopPredicates.empty() && "isImpliedCond garbage");
- assert(PendingPhiRanges.empty() && "getRangeRef garbage");
assert(PendingMerges.empty() && "isImpliedViaMerge garbage");
assert(!WalkingBEDominatingConds && "isLoopBackedgeGuardedByCond garbage!");
assert(!ProvingSplitPredicate && "ProvingSplitPredicate garbage!");
diff --git a/llvm/test/Analysis/ScalarEvolution/addrec-computed-during-addrec-calculation.ll b/llvm/test/Analysis/ScalarEvolution/addrec-computed-during-addrec-calculation.ll
index aab2c49e2973d..fad5c3a144e17 100644
--- a/llvm/test/Analysis/ScalarEvolution/addrec-computed-during-addrec-calculation.ll
+++ b/llvm/test/Analysis/ScalarEvolution/addrec-computed-during-addrec-calculation.ll
@@ -12,19 +12,19 @@ define void @test(ptr %p) {
; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
; CHECK-NEXT: --> %iv U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop.header: Variant, %loop2: Invariant, %loop3: Invariant }
; CHECK-NEXT: %iv2 = phi i32 [ %iv, %loop.header ], [ %iv2.next, %loop2 ]
-; CHECK-NEXT: --> {%iv,+,1}<%loop2> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop2: Computable, %loop.header: Variant }
+; CHECK-NEXT: --> {%iv,+,1}<nsw><%loop2> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop2: Computable, %loop.header: Variant }
; CHECK-NEXT: %iv2.next = add i32 %iv2, 1
-; CHECK-NEXT: --> {(1 + %iv),+,1}<%loop2> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop2: Computable, %loop.header: Variant }
+; CHECK-NEXT: --> {(1 + %iv),+,1}<nw><%loop2> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop2: Computable, %loop.header: Variant }
; CHECK-NEXT: %v = load i32, ptr %p, align 4
; CHECK-NEXT: --> %v U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop2: Variant, %loop.header: Variant }
; CHECK-NEXT: %iv2.ext = sext i32 %iv2 to i64
-; CHECK-NEXT: --> (sext i32 {%iv,+,1}<%loop2> to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648) Exits: <<Unknown>> LoopDispositions: { %loop.header: Variant, %loop2: Computable, %loop3: Invariant }
+; CHECK-NEXT: --> {(sext i32 %iv to i64),+,1}<nsw><%loop2> U: [-2147483648,6442450943) S: [-2147483648,6442450943) Exits: <<Unknown>> LoopDispositions: { %loop.header: Variant, %loop2: Computable, %loop3: Invariant }
; CHECK-NEXT: %iv3 = phi i64 [ %iv2.ext, %loop2.end ], [ %iv3.next, %loop3 ]
-; CHECK-NEXT: --> {(sext i32 {%iv,+,1}<%loop2> to i64),+,1}<nsw><%loop3> U: [-2147483648,2147483648) S: [-2147483648,2147483648) Exits: (sext i32 {%iv,+,1}<%loop2> to i64) LoopDispositions: { %loop3: Computable, %loop.header: Variant }
+; CHECK-NEXT: --> {{\{\{}}(sext i32 %iv to i64),+,1}<nsw><%loop2>,+,1}<nsw><%loop3> U: [-2147483648,6442450943) S: [-2147483648,6442450943) Exits: {(sext i32 %iv to i64),+,1}<nsw><%loop2> LoopDispositions: { %loop3: Computable, %loop.header: Variant }
; CHECK-NEXT: %iv3.next = add nsw i64 %iv3, 1
-; CHECK-NEXT: --> {(1 + (sext i32 {%iv,+,1}<%loop2> to i64))<nsw>,+,1}<nsw><%loop3> U: [-2147483647,2147483649) S: [-2147483647,2147483649) Exits: (1 + (sext i32 {%iv,+,1}<%loop2> to i64))<nsw> LoopDispositions: { %loop3: Computable, %loop.header: Variant }
+; CHECK-NEXT: --> {{\{\{}}(1 + (sext i32 %iv to i64))<nsw>,+,1}<nsw><%loop2>,+,1}<nsw><%loop3> U: [-2147483647,6442450944) S: [-2147483647,6442450944) Exits: {(1 + (sext i32 %iv to i64))<nsw>,+,1}<nsw><%loop2> LoopDispositions: { %loop3: Computable, %loop.header: Variant }
; CHECK-NEXT: %iv.next = trunc i64 %iv3 to i32
-; CHECK-NEXT: --> {{\{\{}}%iv,+,1}<%loop2>,+,1}<%loop3> U: full-set S: full-set --> {%iv,+,1}<%loop2> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop.header: Variant, %loop2: Variant, %loop3: Computable }
+; CHECK-NEXT: --> {{\{\{}}%iv,+,1}<nsw><%loop2>,+,1}<%loop3> U: full-set S: full-set --> {%iv,+,1}<nsw><%loop2> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop.header: Variant, %loop2: Variant, %loop3: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test
; CHECK-NEXT: Loop %loop2: Unpredictable backedge-taken count.
; CHECK-NEXT: Loop %loop2: constant max backedge-taken count is i32 -1
diff --git a/llvm/test/Analysis/ScalarEvolution/outer_phi.ll b/llvm/test/Analysis/ScalarEvolution/outer_phi.ll
index e4a9753b24054..f4dc712f02220 100644
--- a/llvm/test/Analysis/ScalarEvolution/outer_phi.ll
+++ b/llvm/test/Analysis/ScalarEvolution/outer_phi.ll
@@ -7,7 +7,7 @@ define i32 @test_01(i32 %a, i32 %b) {
; CHECK-LABEL: 'test_01'
; CHECK-NEXT: Classifying expressions for: @test_01
; CHECK-NEXT: %outer.iv = phi i32 [ 0, %entry ], [ %iv.next, %outer.backedge ]
-; CHECK-NEXT: --> %outer.iv U: [0,-2147483647) S: [0,-2147483647) Exits: <<Unknown>> LoopDispositions: { %outer: Variant, %inner: Invariant }
+; CHECK-NEXT: --> %outer.iv U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %outer: Variant, %inner: Invariant }
; CHECK-NEXT: %iv = phi i32 [ 0, %outer ], [ %iv.next, %inner.backedge ]
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%inner> U: [0,-2147483648) S: [0,-2147483648) Exits: <<Unknown>> LoopDispositions: { %inner: Computable, %outer: Variant }
; CHECK-NEXT: %iv.next = add nuw nsw i32 %iv, 1
diff --git a/llvm/test/Analysis/ScalarEvolution/pr123550.ll b/llvm/test/Analysis/ScalarEvolution/pr123550.ll
index 709da00935ef3..196f03cad51cd 100644
--- a/llvm/test/Analysis/ScalarEvolution/pr123550.ll
+++ b/llvm/test/Analysis/ScalarEvolution/pr123550.ll
@@ -6,7 +6,7 @@ define i32 @test() {
; CHECK-LABEL: 'test'
; CHECK-NEXT: Classifying expressions for: @test
; CHECK-NEXT: %phi = phi i32 [ -173, %bb ], [ %sub, %loop ]
-; CHECK-NEXT: --> %phi U: [-173,1) S: [-173,1) Exits: -173 LoopDispositions: { %loop: Variant }
+; CHECK-NEXT: --> %phi U: [-256,256) S: [-256,256) Exits: -173 LoopDispositions: { %loop: Variant }
; CHECK-NEXT: %iv2 = phi i32 [ 1, %bb ], [ %iv2.inc, %loop ]
; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,2) S: [1,2) Exits: 1 LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %srem = srem i32 729259140, %phi
diff --git a/llvm/test/Analysis/ScalarEvolution/pr49856.ll b/llvm/test/Analysis/ScalarEvolution/pr49856.ll
index 751677f1f9f80..ec62f57cc5bb2 100644
--- a/llvm/test/Analysis/ScalarEvolution/pr49856.ll
+++ b/llvm/test/Analysis/ScalarEvolution/pr49856.ll
@@ -5,7 +5,7 @@ define void @test() {
; CHECK-LABEL: 'test'
; CHECK-NEXT: Classifying expressions for: @test
; CHECK-NEXT: %tmp = phi i32 [ 2, %bb ], [ %tmp2, %bb3 ]
-; CHECK-NEXT: --> %tmp U: [1,-2147483648) S: [0,-2147483648)
+; CHECK-NEXT: --> %tmp U: [0,-2147483648) S: [0,-2147483648)
; CHECK-NEXT: %tmp2 = add nuw nsw i32 %tmp, 1
; CHECK-NEXT: --> (1 + %tmp)<nuw> U: [1,-2147483647) S: [1,-2147483647)
; CHECK-NEXT: Determining loop execution counts for: @test
diff --git a/llvm/test/Analysis/ScalarEvolution/pr58402-large-number-of-zext-exprs.ll b/llvm/test/Analysis/ScalarEvolution/pr58402-large-number-of-zext-exprs.ll
index c79befac2fb1d..0bedc20661633 100644
--- a/llvm/test/Analysis/ScalarEvolution/pr58402-large-number-of-zext-exprs.ll
+++ b/llvm/test/Analysis/ScalarEvolution/pr58402-large-number-of-zext-exprs.ll
@@ -5,7 +5,7 @@ define i32 @pr58402_large_number_of_zext(ptr %dst) {
; CHECK-LABEL: 'pr58402_large_number_of_zext'
; CHECK-NEXT: Classifying expressions for: @pr58402_large_number_of_zext
; CHECK-NEXT: %d.0 = phi i32 [ 0, %entry ], [ %add7.15, %header ]
-; CHECK-NEXT: --> %d.0 U: [0,65) S: [0,65) Exits: <<Unknown>> LoopDispositions: { %header: Variant }
+; CHECK-NEXT: --> %d.0 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %header: Variant }
; CHECK-NEXT: %b.0 = phi i32 [ 59, %entry ], [ %b.0, %header ]
; CHECK-NEXT: --> 59 U: [59,60) S: [59,60) Exits: 59 LoopDispositions: { %header: Invariant }
; CHECK-NEXT: %conv.neg = sext i1 %cmp to i32
diff --git a/llvm/test/Analysis/ScalarEvolution/ranges.ll b/llvm/test/Analysis/ScalarEvolution/ranges.ll
index cf9d999a6a1ff..cf54b1e63ad39 100644
--- a/llvm/test/Analysis/ScalarEvolution/ranges.ll
+++ b/llvm/test/Analysis/ScalarEvolution/ranges.ll
@@ -308,7 +308,7 @@ define void @mul_6(i32 %n) {
; CHECK-LABEL: 'mul_6'
; CHECK-NEXT: Classifying expressions for: @mul_6
; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
-; CHECK-NEXT: --> %iv U: [0,-1) S: [-2147483648,2147483645) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
+; CHECK-NEXT: --> %iv U: [0,-1) S: [-2147483648,2147483647) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
; CHECK-NEXT: %iv.inc = mul nuw i32 %iv, 6
; CHECK-NEXT: --> (6 * %iv) U: [0,-3) S: [-2147483648,2147483645) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
; CHECK-NEXT: Determining loop execution counts for: @mul_6
@@ -358,7 +358,7 @@ define void @mul_8(i32 %n) {
; CHECK-LABEL: 'mul_8'
; CHECK-NEXT: Classifying expressions for: @mul_8
; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
-; CHECK-NEXT: --> %iv U: [0,-7) S: [-2147483648,2147483585) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
+; CHECK-NEXT: --> %iv U: [0,-7) S: [-2147483648,2147483641) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
; CHECK-NEXT: %iv.inc = mul nuw i32 %iv, 8
; CHECK-NEXT: --> (8 * %iv) U: [0,-63) S: [-2147483648,2147483585) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
; CHECK-NEXT: Determining loop execution counts for: @mul_8
@@ -408,7 +408,7 @@ define void @mul_10(i32 %n) {
; CHECK-LABEL: 'mul_10'
; CHECK-NEXT: Classifying expressions for: @mul_10
; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
-; CHECK-NEXT: --> %iv U: [0,-1) S: [-2147483648,2147483645) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
+; CHECK-NEXT: --> %iv U: [0,-1) S: [-2147483648,2147483647) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
; CHECK-NEXT: %iv.inc = mul nuw i32 %iv, 10
; CHECK-NEXT: --> (10 * %iv) U: [0,-3) S: [-2147483648,2147483645) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
; CHECK-NEXT: Determining loop execution counts for: @mul_10
@@ -433,7 +433,7 @@ define void @mul_8_wrap(i32 %n) {
; CHECK-LABEL: 'mul_8_wrap'
; CHECK-NEXT: Classifying expressions for: @mul_8_wrap
; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
-; CHECK-NEXT: --> %iv U: [0,-7) S: [-2147483648,2147483585) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
+; CHECK-NEXT: --> %iv U: [0,-7) S: [-2147483648,2147483641) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
; CHECK-NEXT: %iv.inc = mul i32 %iv, 8
; CHECK-NEXT: --> (8 * %iv) U: [0,-63) S: [-2147483648,2147483585) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
; CHECK-NEXT: Determining loop execution counts for: @mul_8_wrap
@@ -458,7 +458,7 @@ define void @mul_10_wrap(i32 %n) {
; CHECK-LABEL: 'mul_10_wrap'
; CHECK-NEXT: Classifying expressions for: @mul_10_wrap
; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
-; CHECK-NEXT: --> %iv U: [0,-1) S: [-2147483648,2147483645) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
+; CHECK-NEXT: --> %iv U: [0,-1) S: [-2147483648,2147483647) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
; CHECK-NEXT: %iv.inc = mul i32 %iv, 10
; CHECK-NEXT: --> (10 * %iv) U: [0,-3) S: [-2147483648,2147483645) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
; CHECK-NEXT: Determining loop execution counts for: @mul_10_wrap
diff --git a/llvm/test/Analysis/ScalarEvolution/shift-recurrences.ll b/llvm/test/Analysis/ScalarEvolution/shift-recurrences.ll
index 6cd709bfff68f..c4303604e9bea 100644
--- a/llvm/test/Analysis/ScalarEvolution/shift-recurrences.ll
+++ b/llvm/test/Analysis/ScalarEvolution/shift-recurrences.ll
@@ -73,7 +73,7 @@ define void @test_ashr_ones(i1 %arg) {
; CHECK-LABEL: 'test_ashr_ones'
; CHECK-NEXT: Classifying expressions for: @test_ashr_ones
; CHECK-NEXT: %iv.ashr = phi i64 [ -1023, %entry ], [ %iv.ashr.next, %loop ]
-; CHECK-NEXT: --> %iv.ashr U: [-1023,0) S: [-1023,0) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
+; CHECK-NEXT: --> %iv.ashr U: [-1024,0) S: [-1024,0) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
; CHECK-NEXT: %iv.ashr.next = ashr i64 %iv.ashr, 1
; CHECK-NEXT: --> %iv.ashr.next U: [-512,0) S: [-512,0) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
; CHECK-NEXT: Determining loop execution counts for: @test_ashr_ones
@@ -96,7 +96,7 @@ define void @test_ashr_ones2(i1 %arg) {
; CHECK-LABEL: 'test_ashr_ones2'
; CHECK-NEXT: Classifying expressions for: @test_ashr_ones2
; CHECK-NEXT: %iv.ashr = phi i64 [ %iv.ashr.next, %loop ], [ -1023, %entry ]
-; CHECK-NEXT: --> %iv.ashr U: [-1023,0) S: [-1023,0) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
+; CHECK-NEXT: --> %iv.ashr U: [-1024,0) S: [-1024,0) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
; CHECK-NEXT: %iv.ashr.next = ashr i64 %iv.ashr, 1
; CHECK-NEXT: --> %iv.ashr.next U: [-512,0) S: [-512,0) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
; CHECK-NEXT: Determining loop execution counts for: @test_ashr_ones2
@@ -167,7 +167,7 @@ define void @test_shl(i1 %arg) {
; CHECK-LABEL: 'test_shl'
; CHECK-NEXT: Classifying expressions for: @test_shl
; CHECK-NEXT: %iv.shl = phi i64 [ 8, %entry ], [ %iv.shl.next, %loop ]
-; CHECK-NEXT: --> %iv.shl U: [0,-7) S: [-9223372036854775808,9223372036854775793) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
+; CHECK-NEXT: --> %iv.shl U: [0,-7) S: [-9223372036854775808,9223372036854775801) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
; CHECK-NEXT: %iv.shl.next = shl i64 %iv.shl, 1
; CHECK-NEXT: --> (2 * %iv.shl) U: [0,-15) S: [-9223372036854775808,9223372036854775793) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
; CHECK-NEXT: Determining loop execution counts for: @test_shl
@@ -288,7 +288,7 @@ define void @test_shl5(i1 %arg) {
; CHECK-NEXT: %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,62) S: [0,62) Exits: 61 LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.shl = phi i64 [ 4, %entry ], [ %iv.shl.next, %loop ]
-; CHECK-NEXT: --> %iv.shl U: [0,-3) S: [-9223372036854775808,9223372036854775801) Exits: -9223372036854775808 LoopDispositions: { %loop: Variant }
+; CHECK-NEXT: --> %iv.shl U: [0,-3) S: [-9223372036854775808,9223372036854775805) Exits: -9223372036854775808 LoopDispositions: { %loop: Variant }
; CHECK-NEXT: %iv.next = add i64 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,63) S: [1,63) Exits: 62 LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.shl.next = shl i64 %iv.shl, 1
@@ -440,7 +440,7 @@ define void @nonloop_recurrence() {
; CHECK-LABEL: 'nonloop_recurrence'
; CHECK-NEXT: Classifying expressions for: @nonloop_recurrence
; CHECK-NEXT: %tmp = phi i32 [ 2, %bb ], [ %tmp2, %bb3 ]
-; CHECK-NEXT: --> %tmp U: [1,-2147483648) S: [0,-2147483648)
+; CHECK-NEXT: --> %tmp U: [0,-2147483648) S: [0,-2147483648)
; CHECK-NEXT: %tmp2 = add nuw nsw i32 %tmp, 1
; CHECK-NEXT: --> (1 + %tmp)<nuw> U: [1,-2147483647) S: [1,-2147483647)
; CHECK-NEXT: Determining loop execution counts for: @nonloop_recurrence
@@ -464,7 +464,7 @@ define void @nonloop_recurrence_2() {
; CHECK-LABEL: 'nonloop_recurrence_2'
; CHECK-NEXT: Classifying expressions for: @nonloop_recurrence_2
; CHECK-NEXT: %tmp = phi i32 [ 2, %loop ], [ %tmp2, %bb3 ]
-; CHECK-NEXT: --> %tmp U: [1,-2147483648) S: [0,-2147483648) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
+; CHECK-NEXT: --> %tmp U: [0,-2147483648) S: [0,-2147483648) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
; CHECK-NEXT: %tmp2 = add nuw nsw i32 %tmp, 1
; CHECK-NEXT: --> (1 + %tmp)<nuw> U: [1,-2147483647) S: [1,-2147483647) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
; CHECK-NEXT: Determining loop execution counts for: @nonloop_recurrence_2
@@ -649,7 +649,7 @@ define void @test_lshr_tc_negative() {
; CHECK-NEXT: %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,5) S: [0,5) Exits: 4 LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.lshr = phi i8 [ -1, %entry ], [ %iv.lshr.next, %loop ]
-; CHECK-NEXT: --> %iv.lshr U: [15,0) S: [-1,-128) Exits: 15 LoopDispositions: { %loop: Variant }
+; CHECK-NEXT: --> %iv.lshr U: [15,0) S: [15,0) Exits: 15 LoopDispositions: { %loop: Variant }
; CHECK-NEXT: %iv.next = add i64 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,6) S: [1,6) Exits: 5 LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.lshr.next = lshr i8 %iv.lshr, 1
@@ -681,7 +681,7 @@ define void @test_lshr_tc_either(i1 %a) {
; CHECK-NEXT: %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,5) S: [0,5) Exits: 4 LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.lshr = phi i8 [ %start, %entry ], [ %iv.lshr.next, %loop ]
-; CHECK-NEXT: --> %iv.lshr U: [-1,-128) S: [-1,-128) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
+; CHECK-NEXT: --> %iv.lshr U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
; CHECK-NEXT: %iv.next = add i64 %iv, 1
; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,6) S: [1,6) Exits: 5 LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.lshr.next = lshr i8 %iv.lshr, 1
diff --git a/llvm/test/Transforms/LICM/update-scev-after-hoist.ll b/llvm/test/Transforms/LICM/update-scev-after-hoist.ll
index e303d04ce3191..e2b34db1b026c 100644
--- a/llvm/test/Transforms/LICM/update-scev-after-hoist.ll
+++ b/llvm/test/Transforms/LICM/update-scev-after-hoist.ll
@@ -5,9 +5,9 @@ define i16 @main() {
; SCEV-EXPR-LABEL: 'main'
; SCEV-EXPR-NEXT: Classifying expressions for: @main
; SCEV-EXPR-NEXT: %mul = phi i16 [ 1, %entry ], [ %mul.n.3.reass, %loop ]
-; SCEV-EXPR-NEXT: --> %mul U: [0,-15) S: [-32768,32753) Exits: 4096 LoopDispositions: { %loop: Variant }
+; SCEV-EXPR-NEXT: --> %mul U: [0,-14) S: [0,-14) Exits: 4096 LoopDispositions: { %loop: Variant }
; SCEV-EXPR-NEXT: %div = phi i16 [ 32767, %entry ], [ %div.n.3, %loop ]
-; SCEV-EXPR-NEXT: --> %div U: [-2048,-32768) S: [-2048,-32768) Exits: 7 LoopDispositions: { %loop: Variant }
+; SCEV-EXPR-NEXT: --> %div U: full-set S: full-set Exits: 7 LoopDispositions: { %loop: Variant }
; SCEV-EXPR-NEXT: %mul.n.reass.reass = mul i16 %mul, 8
; SCEV-EXPR-NEXT: --> (8 * %mul) U: [0,-7) S: [-32768,32761) Exits: -32768 LoopDispositions: { %loop: Variant }
; SCEV-EXPR-NEXT: %div.n = sdiv i16 %div, 2
diff --git a/llvm/test/Transforms/LoopVectorize/create-induction-resume.ll b/llvm/test/Transforms/LoopVectorize/create-induction-resume.ll
index 71273a30f846d..c35bc64d7a157 100644
--- a/llvm/test/Transforms/LoopVectorize/create-induction-resume.ll
+++ b/llvm/test/Transforms/LoopVectorize/create-induction-resume.ll
@@ -16,7 +16,7 @@ define void @test(i32 %arg, i32 %L1.limit, i32 %L2.switch, i1 %c, ptr %dst) {
; CHECK-NEXT: [[INDVAR:%.*]] = phi i32 [ [[INDVAR_NEXT:%.*]], [[L1_BACKEDGE]] ], [ 0, [[L1_PREHEADER]] ]
; CHECK-NEXT: [[L1_SUM:%.*]] = phi i32 [ [[ARG]], [[L1_PREHEADER]] ], [ [[L1_SUM_NEXT:%.*]], [[L1_BACKEDGE]] ]
; CHECK-NEXT: [[L1_IV:%.*]] = phi i32 [ 1, [[L1_PREHEADER]] ], [ [[L1_IV_NEXT:%.*]], [[L1_BACKEDGE]] ]
-; CHECK-NEXT: [[TMP1:%.*]] = mul nsw i32 [[INDVAR]], -1
+; CHECK-NEXT: [[TMP1:%.*]] = mul i32 [[INDVAR]], -1
; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], -2
; CHECK-NEXT: br i1 [[C:%.*]], label [[L1_BACKEDGE]], label [[L1_EARLY_EXIT:%.*]]
; CHECK: L1.backedge:
More information about the llvm-commits
mailing list