diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h index 858c1d5392071..ca0f97d7b000b 100644 --- a/llvm/include/llvm/Analysis/ScalarEvolution.h +++ b/llvm/include/llvm/Analysis/ScalarEvolution.h @@ -1502,12 +1502,6 @@ class ScalarEvolution { /// Mark predicate values currently being processed by isImpliedCond. SmallPtrSet PendingLoopPredicates; - /// Mark SCEVUnknown Phis currently being processed by getRangeRef. - SmallPtrSet PendingPhiRanges; - - /// Mark SCEVUnknown Phis currently being processed by getRangeRefIter. - SmallPtrSet PendingPhiRangesIter; - // Mark SCEVUnknown Phis currently being processed by isImpliedViaMerge. SmallPtrSet PendingMerges; diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index 27e6e7e8806c3..6c30d692b8b49 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -6000,7 +6000,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)) { @@ -6020,29 +6022,23 @@ const SCEV *ScalarEvolution::createNodeFromSelectLikePHI(PHINode *PN) { assert(IDom && "At least the entry block should dominate PN"); auto *BI = dyn_cast(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()) { @@ -6057,6 +6053,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; @@ -6581,6 +6592,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) { @@ -6636,8 +6669,8 @@ ScalarEvolution::getRangeRefIter(const SCEV *S, continue; } // `SCEVUnknown`'s require special treatment. - if (const PHINode *P = dyn_cast(UnknownS->getValue())) { - if (!PendingPhiRangesIter.insert(P).second) + if (PHINode *P = dyn_cast(UnknownS->getValue())) { + if (!RangeRefPHIAllowedOperands(DT, P)) continue; for (auto &Op : reverse(P->operands())) AddToWorklist(getSCEV(Op)); @@ -6650,10 +6683,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(P)) - if (const PHINode *P = dyn_cast(UnknownS->getValue())) - PendingPhiRangesIter.erase(P); } } @@ -6963,8 +6992,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(V)) { + // SCEVExpander sometimes creates SCEVUnknowns that are secretly + // AddRecs; return the range for the corresponding AddRec. + if (auto *AR = dyn_cast(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()) { @@ -6976,9 +7010,6 @@ const ConstantRange &ScalarEvolution::getRangeRef( } ConservativeResult = ConservativeResult.intersectWith(RangeFromOps, RangeType); - bool Erased = PendingPhiRanges.erase(Phi); - assert(Erased && "Failed to erase Phi properly?"); - (void)Erased; } } @@ -7657,7 +7688,55 @@ ScalarEvolution::getOperandsToCreate(Value *V, SmallVectorImpl &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(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(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(U), Cond, LHS, RHS)) { + assert(Cond); + assert(LHS); + assert(RHS); + if (auto *CondICmp = dyn_cast(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(U))) { + for (Value *V : cast(U)->operands()) + Ops.push_back(V); + return nullptr; + } return nullptr; case Instruction::Select: { @@ -13728,7 +13807,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)), @@ -13771,7 +13849,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: <> 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: <> LoopDispositions: { %loop2: Computable, %loop.header: Variant } +; CHECK-NEXT: --> {%iv,+,1}<%loop2> U: full-set S: full-set Exits: <> 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: <> LoopDispositions: { %loop2: Computable, %loop.header: Variant } +; CHECK-NEXT: --> {(1 + %iv),+,1}<%loop2> U: full-set S: full-set Exits: <> 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: <> 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: <> LoopDispositions: { %loop.header: Variant, %loop2: Computable, %loop3: Invariant } +; CHECK-NEXT: --> {(sext i32 %iv to i64),+,1}<%loop2> U: [-2147483648,6442450943) S: [-2147483648,6442450943) Exits: <> 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}<%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}<%loop2>,+,1}<%loop3> U: [-2147483648,6442450943) S: [-2147483648,6442450943) Exits: {(sext i32 %iv to i64),+,1}<%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)),+,1}<%loop3> U: [-2147483647,2147483649) S: [-2147483647,2147483649) Exits: (1 + (sext i32 {%iv,+,1}<%loop2> to i64)) LoopDispositions: { %loop3: Computable, %loop.header: Variant } +; CHECK-NEXT: --> {{\{\{}}(1 + (sext i32 %iv to i64)),+,1}<%loop2>,+,1}<%loop3> U: [-2147483647,6442450944) S: [-2147483647,6442450944) Exits: {(1 + (sext i32 %iv to i64)),+,1}<%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: <> LoopDispositions: { %loop.header: Variant, %loop2: Variant, %loop3: Computable } +; CHECK-NEXT: --> {{\{\{}}%iv,+,1}<%loop2>,+,1}<%loop3> U: full-set S: full-set --> {%iv,+,1}<%loop2> U: full-set S: full-set Exits: <> 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: <> LoopDispositions: { %outer: Variant, %inner: Invariant } +; CHECK-NEXT: --> %outer.iv U: full-set S: full-set Exits: <> LoopDispositions: { %outer: Variant, %inner: Invariant } ; CHECK-NEXT: %iv = phi i32 [ 0, %outer ], [ %iv.next, %inner.backedge ] ; CHECK-NEXT: --> {0,+,1}<%inner> U: [0,-2147483648) S: [0,-2147483648) Exits: <> 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}<%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) 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: <> LoopDispositions: { %header: Variant } +; CHECK-NEXT: --> %d.0 U: full-set S: full-set Exits: <> 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: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> %iv U: [0,-1) S: [-2147483648,2147483647) Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %iv.inc = mul nuw i32 %iv, 6 ; CHECK-NEXT: --> (6 * %iv) U: [0,-3) S: [-2147483648,2147483645) Exits: <> 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: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> %iv U: [0,-7) S: [-2147483648,2147483641) Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %iv.inc = mul nuw i32 %iv, 8 ; CHECK-NEXT: --> (8 * %iv) U: [0,-63) S: [-2147483648,2147483585) Exits: <> 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: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> %iv U: [0,-1) S: [-2147483648,2147483647) Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %iv.inc = mul nuw i32 %iv, 10 ; CHECK-NEXT: --> (10 * %iv) U: [0,-3) S: [-2147483648,2147483645) Exits: <> 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: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> %iv U: [0,-7) S: [-2147483648,2147483641) Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %iv.inc = mul i32 %iv, 8 ; CHECK-NEXT: --> (8 * %iv) U: [0,-63) S: [-2147483648,2147483585) Exits: <> 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: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> %iv U: [0,-1) S: [-2147483648,2147483647) Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %iv.inc = mul i32 %iv, 10 ; CHECK-NEXT: --> (10 * %iv) U: [0,-3) S: [-2147483648,2147483645) Exits: <> 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: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> %iv.ashr U: [-1024,0) S: [-1024,0) Exits: <> 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: <> 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: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> %iv.ashr U: [-1024,0) S: [-1024,0) Exits: <> 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: <> 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: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> %iv.shl U: [0,-7) S: [-9223372036854775808,9223372036854775801) Exits: <> 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: <> 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}<%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}<%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) 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: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> %tmp U: [0,-2147483648) S: [0,-2147483648) Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %tmp2 = add nuw nsw i32 %tmp, 1 ; CHECK-NEXT: --> (1 + %tmp) U: [1,-2147483647) S: [1,-2147483647) Exits: <> 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}<%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}<%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}<%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: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> %iv.lshr U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %iv.next = add i64 %iv, 1 ; CHECK-NEXT: --> {1,+,1}<%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 8f9045350813a..1b99212be7c02 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, %loop ] -; SCEV-EXPR-NEXT: --> %mul U: [0,-15) S: [-32768,32753) Exits: 4096 LoopDispositions: { %loop: Variant } +; SCEV-EXPR-NEXT: --> %mul U: full-set S: full-set 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 fbdc11dd98479..51f959f2fc483 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: