Skip to content

Commit d24f558

Browse files
committed
[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.)
1 parent c7b26bd commit d24f558

File tree

11 files changed

+135
-64
lines changed

11 files changed

+135
-64
lines changed

llvm/include/llvm/Analysis/ScalarEvolution.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1502,12 +1502,6 @@ class ScalarEvolution {
15021502
/// Mark predicate values currently being processed by isImpliedCond.
15031503
SmallPtrSet<const Value *, 6> PendingLoopPredicates;
15041504

1505-
/// Mark SCEVUnknown Phis currently being processed by getRangeRef.
1506-
SmallPtrSet<const PHINode *, 6> PendingPhiRanges;
1507-
1508-
/// Mark SCEVUnknown Phis currently being processed by getRangeRefIter.
1509-
SmallPtrSet<const PHINode *, 6> PendingPhiRangesIter;
1510-
15111505
// Mark SCEVUnknown Phis currently being processed by isImpliedViaMerge.
15121506
SmallPtrSet<const PHINode *, 6> PendingMerges;
15131507

llvm/lib/Analysis/ScalarEvolution.cpp

Lines changed: 109 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -6000,7 +6000,9 @@ static bool BrPHIToSelect(DominatorTree &DT, BranchInst *BI, PHINode *Merge,
60006000
return false;
60016001
}
60026002

6003-
const SCEV *ScalarEvolution::createNodeFromSelectLikePHI(PHINode *PN) {
6003+
static bool getOperandsForSelectLikePHI(DominatorTree &DT, PHINode *PN,
6004+
Value *&Cond, Value *&LHS,
6005+
Value *&RHS) {
60046006
auto IsReachable =
60056007
[&](BasicBlock *BB) { return DT.isReachableFromEntry(BB); };
60066008
if (PN->getNumIncomingValues() == 2 && all_of(PN->blocks(), IsReachable)) {
@@ -6020,29 +6022,23 @@ const SCEV *ScalarEvolution::createNodeFromSelectLikePHI(PHINode *PN) {
60206022
assert(IDom && "At least the entry block should dominate PN");
60216023

60226024
auto *BI = dyn_cast<BranchInst>(IDom->getTerminator());
6023-
Value *Cond = nullptr, *LHS = nullptr, *RHS = nullptr;
6024-
6025-
if (BI && BI->isConditional() &&
6026-
BrPHIToSelect(DT, BI, PN, Cond, LHS, RHS) &&
6027-
properlyDominates(getSCEV(LHS), PN->getParent()) &&
6028-
properlyDominates(getSCEV(RHS), PN->getParent()))
6029-
return createNodeForSelectOrPHI(PN, Cond, LHS, RHS);
6025+
return BI && BI->isConditional() &&
6026+
BrPHIToSelect(DT, BI, PN, Cond, LHS, RHS);
60306027
}
6028+
return false;
6029+
}
6030+
6031+
const SCEV *ScalarEvolution::createNodeFromSelectLikePHI(PHINode *PN) {
6032+
Value *Cond = nullptr, *LHS = nullptr, *RHS = nullptr;
6033+
if (getOperandsForSelectLikePHI(DT, PN, Cond, LHS, RHS) &&
6034+
properlyDominates(getSCEV(LHS), PN->getParent()) &&
6035+
properlyDominates(getSCEV(RHS), PN->getParent()))
6036+
return createNodeForSelectOrPHI(PN, Cond, LHS, RHS);
60316037

60326038
return nullptr;
60336039
}
60346040

6035-
/// Returns SCEV for the first operand of a phi if all phi operands have
6036-
/// identical opcodes and operands
6037-
/// eg.
6038-
/// a: %add = %a + %b
6039-
/// br %c
6040-
/// b: %add1 = %a + %b
6041-
/// br %c
6042-
/// c: %phi = phi [%add, a], [%add1, b]
6043-
/// scev(%phi) => scev(%add)
6044-
const SCEV *
6045-
ScalarEvolution::createNodeForPHIWithIdenticalOperands(PHINode *PN) {
6041+
static BinaryOperator *getCommonInstForPHI(PHINode *PN) {
60466042
BinaryOperator *CommonInst = nullptr;
60476043
// Check if instructions are identical.
60486044
for (Value *Incoming : PN->incoming_values()) {
@@ -6057,6 +6053,21 @@ ScalarEvolution::createNodeForPHIWithIdenticalOperands(PHINode *PN) {
60576053
CommonInst = IncomingInst;
60586054
}
60596055
}
6056+
return CommonInst;
6057+
}
6058+
6059+
/// Returns SCEV for the first operand of a phi if all phi operands have
6060+
/// identical opcodes and operands
6061+
/// eg.
6062+
/// a: %add = %a + %b
6063+
/// br %c
6064+
/// b: %add1 = %a + %b
6065+
/// br %c
6066+
/// c: %phi = phi [%add, a], [%add1, b]
6067+
/// scev(%phi) => scev(%add)
6068+
const SCEV *
6069+
ScalarEvolution::createNodeForPHIWithIdenticalOperands(PHINode *PN) {
6070+
BinaryOperator *CommonInst = getCommonInstForPHI(PN);
60606071
if (!CommonInst)
60616072
return nullptr;
60626073

@@ -6581,6 +6592,28 @@ getRangeForUnknownRecurrence(const SCEVUnknown *U) {
65816592
return FullSet;
65826593
}
65836594

6595+
// The goal of this function is to check if recursively visiting the operands
6596+
// of this PHI might lead to an infinite loop. If we do see such a loop,
6597+
// there's no good way to break it, so we avoid analyzing such cases.
6598+
//
6599+
// getRangeRef previously used a visited set to avoid infinite loops, but this
6600+
// caused other issues: the result was dependent on the order of getRangeRef
6601+
// calls, and the interaction with createSCEVIter could cause a stack overflow
6602+
// in some cases (see issue #148253).
6603+
//
6604+
// FIXME: The way this is implemented is overly conservative.
6605+
static bool RangeRefPHIAllowedOperands(DominatorTree &DT, PHINode *PH) {
6606+
Value *Cond = nullptr, *LHS = nullptr, *RHS = nullptr;
6607+
if (getOperandsForSelectLikePHI(DT, PH, Cond, LHS, RHS))
6608+
return true;
6609+
6610+
if (all_of(PH->operands(),
6611+
[&](Value *Operand) { return DT.dominates(Operand, PH); }))
6612+
return true;
6613+
6614+
return false;
6615+
}
6616+
65846617
const ConstantRange &
65856618
ScalarEvolution::getRangeRefIter(const SCEV *S,
65866619
ScalarEvolution::RangeSignHint SignHint) {
@@ -6636,8 +6669,8 @@ ScalarEvolution::getRangeRefIter(const SCEV *S,
66366669
continue;
66376670
}
66386671
// `SCEVUnknown`'s require special treatment.
6639-
if (const PHINode *P = dyn_cast<PHINode>(UnknownS->getValue())) {
6640-
if (!PendingPhiRangesIter.insert(P).second)
6672+
if (PHINode *P = dyn_cast<PHINode>(UnknownS->getValue())) {
6673+
if (!RangeRefPHIAllowedOperands(DT, P))
66416674
continue;
66426675
for (auto &Op : reverse(P->operands()))
66436676
AddToWorklist(getSCEV(Op));
@@ -6650,10 +6683,6 @@ ScalarEvolution::getRangeRefIter(const SCEV *S,
66506683
// their users in most cases.
66516684
for (const SCEV *P : reverse(drop_begin(WorkList))) {
66526685
getRangeRef(P, SignHint);
6653-
6654-
if (auto *UnknownS = dyn_cast<SCEVUnknown>(P))
6655-
if (const PHINode *P = dyn_cast<PHINode>(UnknownS->getValue()))
6656-
PendingPhiRangesIter.erase(P);
66576686
}
66586687
}
66596688

@@ -6963,8 +6992,13 @@ const ConstantRange &ScalarEvolution::getRangeRef(
69636992

69646993
// A range of Phi is a subset of union of all ranges of its input.
69656994
if (PHINode *Phi = dyn_cast<PHINode>(V)) {
6995+
// SCEVExpander sometimes creates SCEVUnknowns that are secretly
6996+
// AddRecs; return the range for the corresponding AddRec.
6997+
if (auto *AR = dyn_cast<SCEVAddRecExpr>(getSCEV(V)))
6998+
return getRangeRef(AR, SignHint, Depth + 1);
6999+
69667000
// Make sure that we do not run over cycled Phis.
6967-
if (PendingPhiRanges.insert(Phi).second) {
7001+
if (RangeRefPHIAllowedOperands(DT, Phi)) {
69687002
ConstantRange RangeFromOps(BitWidth, /*isFullSet=*/false);
69697003

69707004
for (const auto &Op : Phi->operands()) {
@@ -6976,9 +7010,6 @@ const ConstantRange &ScalarEvolution::getRangeRef(
69767010
}
69777011
ConservativeResult =
69787012
ConservativeResult.intersectWith(RangeFromOps, RangeType);
6979-
bool Erased = PendingPhiRanges.erase(Phi);
6980-
assert(Erased && "Failed to erase Phi properly?");
6981-
(void)Erased;
69827013
}
69837014
}
69847015

@@ -7657,7 +7688,55 @@ ScalarEvolution::getOperandsToCreate(Value *V, SmallVectorImpl<Value *> &Ops) {
76577688
return getUnknown(V);
76587689

76597690
case Instruction::PHI:
7660-
// Keep constructing SCEVs' for phis recursively for now.
7691+
// getNodeForPHI has four ways to turn a PHI into a SCEV; retrieve the
7692+
// relevant nodes for each of them.
7693+
//
7694+
// The first is just to call simplifyInstruction, and get something back
7695+
// that isn't a PHI.
7696+
if (Value *V = simplifyInstruction(
7697+
cast<PHINode>(U),
7698+
{getDataLayout(), &TLI, &DT, &AC, /*CtxI=*/nullptr,
7699+
/*UseInstrInfo=*/true, /*CanUseUndef=*/false})) {
7700+
assert(V);
7701+
Ops.push_back(V);
7702+
return nullptr;
7703+
}
7704+
// The second is createNodeForPHIWithIdenticalOperands: this looks for
7705+
// operands which all perform the same operation, but haven't been
7706+
// CSE'ed for whatever reason.
7707+
if (BinaryOperator *BO = getCommonInstForPHI(cast<PHINode>(U))) {
7708+
assert(BO);
7709+
Ops.push_back(BO);
7710+
return nullptr;
7711+
}
7712+
// The third is createNodeFromSelectLikePHI; this takes a PHI which
7713+
// is equivalent to a select, and analyzes it like a select.
7714+
{
7715+
Value *Cond = nullptr, *LHS = nullptr, *RHS = nullptr;
7716+
if (getOperandsForSelectLikePHI(DT, cast<PHINode>(U), Cond, LHS, RHS)) {
7717+
assert(Cond);
7718+
assert(LHS);
7719+
assert(RHS);
7720+
if (auto *CondICmp = dyn_cast<ICmpInst>(Cond)) {
7721+
Ops.push_back(CondICmp->getOperand(0));
7722+
Ops.push_back(CondICmp->getOperand(1));
7723+
}
7724+
Ops.push_back(Cond);
7725+
Ops.push_back(LHS);
7726+
Ops.push_back(RHS);
7727+
return nullptr;
7728+
}
7729+
}
7730+
// The fourth way is createAddRecFromPHI. It's complicated to handle here,
7731+
// so just construct it recursively.
7732+
//
7733+
// In addition to getNodeForPHI, also construct nodes which might be needed
7734+
// by getRangeRef.
7735+
if (RangeRefPHIAllowedOperands(DT, cast<PHINode>(U))) {
7736+
for (Value *V : cast<PHINode>(U)->operands())
7737+
Ops.push_back(V);
7738+
return nullptr;
7739+
}
76617740
return nullptr;
76627741

76637742
case Instruction::Select: {
@@ -13728,7 +13807,6 @@ ScalarEvolution::ScalarEvolution(ScalarEvolution &&Arg)
1372813807
DT(Arg.DT), LI(Arg.LI), CouldNotCompute(std::move(Arg.CouldNotCompute)),
1372913808
ValueExprMap(std::move(Arg.ValueExprMap)),
1373013809
PendingLoopPredicates(std::move(Arg.PendingLoopPredicates)),
13731-
PendingPhiRanges(std::move(Arg.PendingPhiRanges)),
1373213810
PendingMerges(std::move(Arg.PendingMerges)),
1373313811
ConstantMultipleCache(std::move(Arg.ConstantMultipleCache)),
1373413812
BackedgeTakenCounts(std::move(Arg.BackedgeTakenCounts)),
@@ -13771,7 +13849,6 @@ ScalarEvolution::~ScalarEvolution() {
1377113849
PredicatedBackedgeTakenCounts.clear();
1377213850

1377313851
assert(PendingLoopPredicates.empty() && "isImpliedCond garbage");
13774-
assert(PendingPhiRanges.empty() && "getRangeRef garbage");
1377513852
assert(PendingMerges.empty() && "isImpliedViaMerge garbage");
1377613853
assert(!WalkingBEDominatingConds && "isLoopBackedgeGuardedByCond garbage!");
1377713854
assert(!ProvingSplitPredicate && "ProvingSplitPredicate garbage!");

llvm/test/Analysis/ScalarEvolution/addrec-computed-during-addrec-calculation.ll

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,19 @@ define void @test(ptr %p) {
1212
; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
1313
; CHECK-NEXT: --> %iv U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop.header: Variant, %loop2: Invariant, %loop3: Invariant }
1414
; CHECK-NEXT: %iv2 = phi i32 [ %iv, %loop.header ], [ %iv2.next, %loop2 ]
15-
; CHECK-NEXT: --> {%iv,+,1}<%loop2> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop2: Computable, %loop.header: Variant }
15+
; CHECK-NEXT: --> {%iv,+,1}<nsw><%loop2> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop2: Computable, %loop.header: Variant }
1616
; CHECK-NEXT: %iv2.next = add i32 %iv2, 1
17-
; CHECK-NEXT: --> {(1 + %iv),+,1}<%loop2> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop2: Computable, %loop.header: Variant }
17+
; CHECK-NEXT: --> {(1 + %iv),+,1}<nw><%loop2> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop2: Computable, %loop.header: Variant }
1818
; CHECK-NEXT: %v = load i32, ptr %p, align 4
1919
; CHECK-NEXT: --> %v U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop2: Variant, %loop.header: Variant }
2020
; CHECK-NEXT: %iv2.ext = sext i32 %iv2 to i64
21-
; 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 }
21+
; 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 }
2222
; CHECK-NEXT: %iv3 = phi i64 [ %iv2.ext, %loop2.end ], [ %iv3.next, %loop3 ]
23-
; 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 }
23+
; 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 }
2424
; CHECK-NEXT: %iv3.next = add nsw i64 %iv3, 1
25-
; 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 }
25+
; 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 }
2626
; CHECK-NEXT: %iv.next = trunc i64 %iv3 to i32
27-
; 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 }
27+
; 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 }
2828
; CHECK-NEXT: Determining loop execution counts for: @test
2929
; CHECK-NEXT: Loop %loop2: Unpredictable backedge-taken count.
3030
; CHECK-NEXT: Loop %loop2: constant max backedge-taken count is i32 -1

llvm/test/Analysis/ScalarEvolution/outer_phi.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ define i32 @test_01(i32 %a, i32 %b) {
77
; CHECK-LABEL: 'test_01'
88
; CHECK-NEXT: Classifying expressions for: @test_01
99
; CHECK-NEXT: %outer.iv = phi i32 [ 0, %entry ], [ %iv.next, %outer.backedge ]
10-
; CHECK-NEXT: --> %outer.iv U: [0,-2147483647) S: [0,-2147483647) Exits: <<Unknown>> LoopDispositions: { %outer: Variant, %inner: Invariant }
10+
; CHECK-NEXT: --> %outer.iv U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %outer: Variant, %inner: Invariant }
1111
; CHECK-NEXT: %iv = phi i32 [ 0, %outer ], [ %iv.next, %inner.backedge ]
1212
; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%inner> U: [0,-2147483648) S: [0,-2147483648) Exits: <<Unknown>> LoopDispositions: { %inner: Computable, %outer: Variant }
1313
; CHECK-NEXT: %iv.next = add nuw nsw i32 %iv, 1

llvm/test/Analysis/ScalarEvolution/pr123550.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ define i32 @test() {
66
; CHECK-LABEL: 'test'
77
; CHECK-NEXT: Classifying expressions for: @test
88
; CHECK-NEXT: %phi = phi i32 [ -173, %bb ], [ %sub, %loop ]
9-
; CHECK-NEXT: --> %phi U: [-173,1) S: [-173,1) Exits: -173 LoopDispositions: { %loop: Variant }
9+
; CHECK-NEXT: --> %phi U: [-256,256) S: [-256,256) Exits: -173 LoopDispositions: { %loop: Variant }
1010
; CHECK-NEXT: %iv2 = phi i32 [ 1, %bb ], [ %iv2.inc, %loop ]
1111
; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,2) S: [1,2) Exits: 1 LoopDispositions: { %loop: Computable }
1212
; CHECK-NEXT: %srem = srem i32 729259140, %phi

llvm/test/Analysis/ScalarEvolution/pr49856.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ define void @test() {
55
; CHECK-LABEL: 'test'
66
; CHECK-NEXT: Classifying expressions for: @test
77
; CHECK-NEXT: %tmp = phi i32 [ 2, %bb ], [ %tmp2, %bb3 ]
8-
; CHECK-NEXT: --> %tmp U: [1,-2147483648) S: [0,-2147483648)
8+
; CHECK-NEXT: --> %tmp U: [0,-2147483648) S: [0,-2147483648)
99
; CHECK-NEXT: %tmp2 = add nuw nsw i32 %tmp, 1
1010
; CHECK-NEXT: --> (1 + %tmp)<nuw> U: [1,-2147483647) S: [1,-2147483647)
1111
; CHECK-NEXT: Determining loop execution counts for: @test

llvm/test/Analysis/ScalarEvolution/pr58402-large-number-of-zext-exprs.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ define i32 @pr58402_large_number_of_zext(ptr %dst) {
55
; CHECK-LABEL: 'pr58402_large_number_of_zext'
66
; CHECK-NEXT: Classifying expressions for: @pr58402_large_number_of_zext
77
; CHECK-NEXT: %d.0 = phi i32 [ 0, %entry ], [ %add7.15, %header ]
8-
; CHECK-NEXT: --> %d.0 U: [0,65) S: [0,65) Exits: <<Unknown>> LoopDispositions: { %header: Variant }
8+
; CHECK-NEXT: --> %d.0 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %header: Variant }
99
; CHECK-NEXT: %b.0 = phi i32 [ 59, %entry ], [ %b.0, %header ]
1010
; CHECK-NEXT: --> 59 U: [59,60) S: [59,60) Exits: 59 LoopDispositions: { %header: Invariant }
1111
; CHECK-NEXT: %conv.neg = sext i1 %cmp to i32

llvm/test/Analysis/ScalarEvolution/ranges.ll

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ define void @mul_6(i32 %n) {
308308
; CHECK-LABEL: 'mul_6'
309309
; CHECK-NEXT: Classifying expressions for: @mul_6
310310
; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
311-
; CHECK-NEXT: --> %iv U: [0,-1) S: [-2147483648,2147483645) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
311+
; CHECK-NEXT: --> %iv U: [0,-1) S: [-2147483648,2147483647) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
312312
; CHECK-NEXT: %iv.inc = mul nuw i32 %iv, 6
313313
; CHECK-NEXT: --> (6 * %iv) U: [0,-3) S: [-2147483648,2147483645) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
314314
; CHECK-NEXT: Determining loop execution counts for: @mul_6
@@ -358,7 +358,7 @@ define void @mul_8(i32 %n) {
358358
; CHECK-LABEL: 'mul_8'
359359
; CHECK-NEXT: Classifying expressions for: @mul_8
360360
; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
361-
; CHECK-NEXT: --> %iv U: [0,-7) S: [-2147483648,2147483585) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
361+
; CHECK-NEXT: --> %iv U: [0,-7) S: [-2147483648,2147483641) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
362362
; CHECK-NEXT: %iv.inc = mul nuw i32 %iv, 8
363363
; CHECK-NEXT: --> (8 * %iv) U: [0,-63) S: [-2147483648,2147483585) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
364364
; CHECK-NEXT: Determining loop execution counts for: @mul_8
@@ -408,7 +408,7 @@ define void @mul_10(i32 %n) {
408408
; CHECK-LABEL: 'mul_10'
409409
; CHECK-NEXT: Classifying expressions for: @mul_10
410410
; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
411-
; CHECK-NEXT: --> %iv U: [0,-1) S: [-2147483648,2147483645) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
411+
; CHECK-NEXT: --> %iv U: [0,-1) S: [-2147483648,2147483647) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
412412
; CHECK-NEXT: %iv.inc = mul nuw i32 %iv, 10
413413
; CHECK-NEXT: --> (10 * %iv) U: [0,-3) S: [-2147483648,2147483645) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
414414
; CHECK-NEXT: Determining loop execution counts for: @mul_10
@@ -433,7 +433,7 @@ define void @mul_8_wrap(i32 %n) {
433433
; CHECK-LABEL: 'mul_8_wrap'
434434
; CHECK-NEXT: Classifying expressions for: @mul_8_wrap
435435
; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
436-
; CHECK-NEXT: --> %iv U: [0,-7) S: [-2147483648,2147483585) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
436+
; CHECK-NEXT: --> %iv U: [0,-7) S: [-2147483648,2147483641) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
437437
; CHECK-NEXT: %iv.inc = mul i32 %iv, 8
438438
; CHECK-NEXT: --> (8 * %iv) U: [0,-63) S: [-2147483648,2147483585) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
439439
; CHECK-NEXT: Determining loop execution counts for: @mul_8_wrap
@@ -458,7 +458,7 @@ define void @mul_10_wrap(i32 %n) {
458458
; CHECK-LABEL: 'mul_10_wrap'
459459
; CHECK-NEXT: Classifying expressions for: @mul_10_wrap
460460
; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ]
461-
; CHECK-NEXT: --> %iv U: [0,-1) S: [-2147483648,2147483645) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
461+
; CHECK-NEXT: --> %iv U: [0,-1) S: [-2147483648,2147483647) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
462462
; CHECK-NEXT: %iv.inc = mul i32 %iv, 10
463463
; CHECK-NEXT: --> (10 * %iv) U: [0,-3) S: [-2147483648,2147483645) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
464464
; CHECK-NEXT: Determining loop execution counts for: @mul_10_wrap

0 commit comments

Comments
 (0)