[llvm] [SCEV] Don't blindly transfer nowrap flags to pre-inc addrec (PR #118959)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Fri Dec 6 04:08:29 PST 2024
https://github.com/nikic created https://github.com/llvm/llvm-project/pull/118959
>From https://reviews.llvm.org/D148931. Test updates incomplete.
>From d0106c99363d12ae11fac32a601fb74d074fe61a Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Fri, 21 Apr 2023 16:09:49 +0200
Subject: [PATCH] Check whether nowrap flags can be transferred to preinc
addrec
---
llvm/include/llvm/Analysis/ScalarEvolution.h | 14 ++-
llvm/lib/Analysis/ScalarEvolution.cpp | 110 ++++++++++++------
.../ScalarEvolution/decrementing_addrecs.ll | 10 +-
.../ScalarEvolution/flags-from-poison.ll | 8 +-
.../ScalarEvolution/max-expr-cache.ll | 8 +-
.../ScalarEvolution/nowrap-preinc-limits.ll | 57 +++++++--
llvm/test/Analysis/ScalarEvolution/pr27315.ll | 32 +++--
.../ScalarEvolution/range-signedness.ll | 4 +-
.../ScalarEvolution/smin-smax-folds.ll | 4 +-
.../Transforms/IndVarSimplify/X86/pr27133.ll | 6 +-
.../Transforms/IndVarSimplify/iv-poison.ll | 16 +--
.../Transforms/IndVarSimplify/lftr-pr31181.ll | 4 +-
llvm/test/Transforms/IndVarSimplify/lftr.ll | 11 +-
.../IndVarSimplify/no-iv-rewrite.ll | 6 +-
.../IndVarSimplify/pr30806-phi-scev.ll | 16 +--
.../test/Transforms/IndVarSimplify/pr55925.ll | 20 ++--
.../scev-expander-preserve-lcssa.ll | 2 +-
.../widen-nonnegative-countdown.ll | 25 ++--
llvm/test/Transforms/LoopIdiom/pr80954.ll | 15 +--
.../invalidate-scev-dispositions.ll | 2 +-
.../AMDGPU/lsr-invalid-ptr-extend.ll | 24 ++--
.../LoopStrengthReduce/X86/sibling-loops.ll | 4 +-
.../runtime-exit-phi-scev-invalidation.ll | 2 +-
.../LoopUnroll/wrong_assert_in_peeling.ll | 47 ++------
24 files changed, 247 insertions(+), 200 deletions(-)
diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h
index de74524c4b6fe4..50887c2c447430 100644
--- a/llvm/include/llvm/Analysis/ScalarEvolution.h
+++ b/llvm/include/llvm/Analysis/ScalarEvolution.h
@@ -2216,10 +2216,16 @@ class ScalarEvolution {
bool isSCEVExprNeverPoison(const Instruction *I);
/// This is like \c isSCEVExprNeverPoison but it specifically works for
- /// instructions that will get mapped to SCEV add recurrences. Return true
- /// if \p I will never generate poison under the assumption that \p I is an
- /// add recurrence on the loop \p L.
- bool isAddRecNeverPoison(const Instruction *I, const Loop *L);
+ /// instructions that will get mapped to SCEV post-inc add recurrences.
+ /// Return true if \p I will never generate poison under the assumption that
+ /// \p I is an add recurrence on the loop \p L.
+ bool isPostIncAddRecNeverPoison(const Instruction *I, const Loop *L);
+
+ /// Check whether nowrap flags from the IR increment operation can be
+ /// transferred to the pre-inc addrec.
+ bool canPreservePreIncAddRecNoWrapFlags(const Instruction *PreIncI,
+ const Instruction *PostIncI,
+ const Loop *L);
/// Similar to createAddRecFromPHI, but with the additional flexibility of
/// suggesting runtime overflow checks in case casts are encountered.
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index cad10486cbf3fa..2e275f7ec9e76b 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -5758,14 +5758,19 @@ const SCEV *ScalarEvolution::createSimpleAffineAddRec(PHINode *PN,
if (!Accum)
return nullptr;
- SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap;
+ SCEV::NoWrapFlags IRFlags = SCEV::FlagAnyWrap;
if (BO->IsNUW)
- Flags = setFlags(Flags, SCEV::FlagNUW);
+ IRFlags = setFlags(IRFlags, SCEV::FlagNUW);
if (BO->IsNSW)
- Flags = setFlags(Flags, SCEV::FlagNSW);
+ IRFlags = setFlags(IRFlags, SCEV::FlagNSW);
+ auto *BEInst = dyn_cast<Instruction>(BEValueV);
+ SCEV::NoWrapFlags PreIncFlags =
+ BEInst && canPreservePreIncAddRecNoWrapFlags(PN, BEInst, L)
+ ? IRFlags
+ : SCEV::FlagAnyWrap;
const SCEV *StartVal = getSCEV(StartValueV);
- const SCEV *PHISCEV = getAddRecExpr(StartVal, Accum, L, Flags);
+ const SCEV *PHISCEV = getAddRecExpr(StartVal, Accum, L, PreIncFlags);
insertValueToMap(PN, PHISCEV);
if (auto *AR = dyn_cast<SCEVAddRecExpr>(PHISCEV)) {
@@ -5777,11 +5782,11 @@ const SCEV *ScalarEvolution::createSimpleAffineAddRec(PHINode *PN,
// We can add Flags to the post-inc expression only if we
// know that it is *undefined behavior* for BEValueV to
// overflow.
- if (auto *BEInst = dyn_cast<Instruction>(BEValueV)) {
+ if (BEInst) {
assert(isLoopInvariant(Accum, L) &&
"Accum is defined outside L, but is not invariant?");
- if (isAddRecNeverPoison(BEInst, L))
- (void)getAddRecExpr(getAddExpr(StartVal, Accum), Accum, L, Flags);
+ if (isPostIncAddRecNeverPoison(BEInst, L))
+ (void)getAddRecExpr(getAddExpr(StartVal, Accum), Accum, L, IRFlags);
}
return PHISCEV;
@@ -5861,14 +5866,14 @@ const SCEV *ScalarEvolution::createAddRecFromPHI(PHINode *PN) {
if (isLoopInvariant(Accum, L) ||
(isa<SCEVAddRecExpr>(Accum) &&
cast<SCEVAddRecExpr>(Accum)->getLoop() == L)) {
- SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap;
+ SCEV::NoWrapFlags IRFlags = SCEV::FlagAnyWrap;
if (auto BO = MatchBinaryOp(BEValueV, getDataLayout(), AC, DT, PN)) {
if (BO->Opcode == Instruction::Add && BO->LHS == PN) {
if (BO->IsNUW)
- Flags = setFlags(Flags, SCEV::FlagNUW);
+ IRFlags = setFlags(IRFlags, SCEV::FlagNUW);
if (BO->IsNSW)
- Flags = setFlags(Flags, SCEV::FlagNSW);
+ IRFlags = setFlags(IRFlags, SCEV::FlagNSW);
}
} else if (GEPOperator *GEP = dyn_cast<GEPOperator>(BEValueV)) {
if (GEP->getOperand(0) == PN) {
@@ -5876,13 +5881,13 @@ const SCEV *ScalarEvolution::createAddRecFromPHI(PHINode *PN) {
// If the increment has any nowrap flags, then we know the address
// space cannot be wrapped around.
if (NW != GEPNoWrapFlags::none())
- Flags = setFlags(Flags, SCEV::FlagNW);
+ IRFlags = setFlags(IRFlags, SCEV::FlagNW);
// If the GEP is nuw or nusw with non-negative offset, we know that
// no unsigned wrap occurs. We cannot set the nsw flag as only the
// offset is treated as signed, while the base is unsigned.
if (NW.hasNoUnsignedWrap() ||
(NW.hasNoUnsignedSignedWrap() && isKnownNonNegative(Accum)))
- Flags = setFlags(Flags, SCEV::FlagNUW);
+ IRFlags = setFlags(IRFlags, SCEV::FlagNUW);
}
// We cannot transfer nuw and nsw flags from subtraction
@@ -5891,7 +5896,12 @@ const SCEV *ScalarEvolution::createAddRecFromPHI(PHINode *PN) {
}
const SCEV *StartVal = getSCEV(StartValueV);
- const SCEV *PHISCEV = getAddRecExpr(StartVal, Accum, L, Flags);
+ auto *BEInst = dyn_cast<Instruction>(BEValueV);
+ SCEV::NoWrapFlags PreIncFlags =
+ BEInst && canPreservePreIncAddRecNoWrapFlags(PN, BEInst, L)
+ ? IRFlags
+ : SCEV::FlagAnyWrap;
+ const SCEV *PHISCEV = getAddRecExpr(StartVal, Accum, L, PreIncFlags);
// Okay, for the entire analysis of this edge we assumed the PHI
// to be symbolic. We now need to go back and purge all of the
@@ -5908,9 +5918,9 @@ const SCEV *ScalarEvolution::createAddRecFromPHI(PHINode *PN) {
// We can add Flags to the post-inc expression only if we
// know that it is *undefined behavior* for BEValueV to
// overflow.
- if (auto *BEInst = dyn_cast<Instruction>(BEValueV))
- if (isLoopInvariant(Accum, L) && isAddRecNeverPoison(BEInst, L))
- (void)getAddRecExpr(getAddExpr(StartVal, Accum), Accum, L, Flags);
+ if (BEInst && isLoopInvariant(Accum, L) &&
+ isPostIncAddRecNeverPoison(BEInst, L))
+ (void)getAddRecExpr(getAddExpr(StartVal, Accum), Accum, L, IRFlags);
return PHISCEV;
}
@@ -7396,29 +7406,16 @@ bool ScalarEvolution::isSCEVExprNeverPoison(const Instruction *I) {
return isGuaranteedToTransferExecutionTo(DefI, I);
}
-bool ScalarEvolution::isAddRecNeverPoison(const Instruction *I, const Loop *L) {
- // If we know that \c I can never be poison period, then that's enough.
- if (isSCEVExprNeverPoison(I))
- return true;
-
- // If the loop only has one exit, then we know that, if the loop is entered,
- // any instruction dominating that exit will be executed. If any such
- // instruction would result in UB, the addrec cannot be poison.
- //
- // This is basically the same reasoning as in isSCEVExprNeverPoison(), but
- // also handles uses outside the loop header (they just need to dominate the
- // single exit).
-
- auto *ExitingBB = L->getExitingBlock();
- if (!ExitingBB || !loopHasNoAbnormalExits(L))
- return false;
-
+/// Check whether there is an instruction dominating BB that would cause
+/// undefined behavior if I is poison. (The caller is responsible for making
+/// sure the instruction actually executes.)
+static bool poisonCausesDominatingUB(const Instruction *I, const BasicBlock *BB,
+ const Loop *L, const DominatorTree &DT) {
SmallPtrSet<const Value *, 16> KnownPoison;
SmallVector<const Instruction *, 8> Worklist;
- // We start by assuming \c I, the post-inc add recurrence, is poison. Only
- // things that are known to be poison under that assumption go on the
- // Worklist.
+ // We start by assuming \c I is poison. Only things that are known to be
+ // poison under that assumption go on the Worklist.
KnownPoison.insert(I);
Worklist.push_back(I);
@@ -7428,7 +7425,7 @@ bool ScalarEvolution::isAddRecNeverPoison(const Instruction *I, const Loop *L) {
for (const Use &U : Poison->uses()) {
const Instruction *PoisonUser = cast<Instruction>(U.getUser());
if (mustTriggerUB(PoisonUser, KnownPoison) &&
- DT.dominates(PoisonUser->getParent(), ExitingBB))
+ DT.dominates(PoisonUser->getParent(), BB))
return true;
if (propagatesPoison(U) && L->contains(PoisonUser))
@@ -7440,6 +7437,45 @@ bool ScalarEvolution::isAddRecNeverPoison(const Instruction *I, const Loop *L) {
return false;
}
+bool ScalarEvolution::isPostIncAddRecNeverPoison(const Instruction *PostIncI,
+ const Loop *L) {
+ // If we know that \c PostIncI can never be poison period, then that's enough.
+ if (isSCEVExprNeverPoison(PostIncI))
+ return true;
+
+ // If the loop only has one exit, then we know that, if the loop is entered,
+ // any instruction dominating that exit will be executed. If any such
+ // instruction would result in UB, the addrec cannot be poison.
+ //
+ // This is basically the same reasoning as in isSCEVExprNeverPoison(), but
+ // also handles uses outside the loop header (they just need to dominate the
+ // single exit).
+
+ auto *ExitingBB = L->getExitingBlock();
+ if (!ExitingBB || !loopHasNoAbnormalExits(L))
+ return false;
+
+ return poisonCausesDominatingUB(PostIncI, ExitingBB, L, DT);
+}
+
+bool ScalarEvolution::canPreservePreIncAddRecNoWrapFlags(
+ const Instruction *PreIncI, const Instruction *PostIncI, const Loop *L) {
+ // If we know that PreIncI can never be poison period, then that's enough.
+ if (programUndefinedIfPoison(PreIncI))
+ return true;
+
+ // Nowrap flags are always valid on the first iteration. For subsequent
+ // iterations, we use the post-inc value after taking the loop latch. As such,
+ // if a poison post-inc value would cause UB in any instruction dominating
+ // the latch, we know that it cannot be poison.
+
+ auto *Latch = L->getLoopLatch();
+ if (!Latch)
+ return false;
+
+ return poisonCausesDominatingUB(PostIncI, Latch, L, DT);
+}
+
ScalarEvolution::LoopProperties
ScalarEvolution::getLoopProperties(const Loop *L) {
using LoopProperties = ScalarEvolution::LoopProperties;
diff --git a/llvm/test/Analysis/ScalarEvolution/decrementing_addrecs.ll b/llvm/test/Analysis/ScalarEvolution/decrementing_addrecs.ll
index c3a1943afd6bff..2cf41995496c66 100644
--- a/llvm/test/Analysis/ScalarEvolution/decrementing_addrecs.ll
+++ b/llvm/test/Analysis/ScalarEvolution/decrementing_addrecs.ll
@@ -34,11 +34,11 @@ define i32 @test_step_1_flags(i32 %n) {
; DEFAULT-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ]
; DEFAULT-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,2147483647) S: [0,2147483647) Exits: (-1 + %n) LoopDispositions: { %loop: Computable }
; DEFAULT-NEXT: %j = phi i32 [ %n.minus.1, %entry ], [ %j.next, %loop ]
-; DEFAULT-NEXT: --> {(-1 + %n),+,-1}<nsw><%loop> U: full-set S: full-set Exits: 0 LoopDispositions: { %loop: Computable }
+; DEFAULT-NEXT: --> {(-1 + %n),+,-1}<nw><%loop> U: full-set S: full-set Exits: 0 LoopDispositions: { %loop: Computable }
; DEFAULT-NEXT: %a = sub i32 %n, %i
; DEFAULT-NEXT: --> {%n,+,-1}<nw><%loop> U: full-set S: full-set Exits: 1 LoopDispositions: { %loop: Computable }
; DEFAULT-NEXT: %b = sub i32 %n.minus.1, %i
-; DEFAULT-NEXT: --> {(-1 + %n),+,-1}<nsw><%loop> U: full-set S: full-set Exits: 0 LoopDispositions: { %loop: Computable }
+; DEFAULT-NEXT: --> {(-1 + %n),+,-1}<nw><%loop> U: full-set S: full-set Exits: 0 LoopDispositions: { %loop: Computable }
; DEFAULT-NEXT: %c = sub i32 2147483647, %i
; DEFAULT-NEXT: --> {2147483647,+,-1}<nsw><%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: (-2147483648 + (-1 * %n)) LoopDispositions: { %loop: Computable }
; DEFAULT-NEXT: %i.next = add nuw nsw i32 %i, 1
@@ -58,17 +58,17 @@ define i32 @test_step_1_flags(i32 %n) {
; EXPENSIVE_SHARPENING-NEXT: %i = phi i32 [ 0, %entry ], [ %i.next, %loop ]
; EXPENSIVE_SHARPENING-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,2147483647) S: [0,2147483647) Exits: (-1 + %n) LoopDispositions: { %loop: Computable }
; EXPENSIVE_SHARPENING-NEXT: %j = phi i32 [ %n.minus.1, %entry ], [ %j.next, %loop ]
-; EXPENSIVE_SHARPENING-NEXT: --> {(-1 + %n),+,-1}<nsw><%loop> U: [0,2147483647) S: [0,2147483647) Exits: 0 LoopDispositions: { %loop: Computable }
+; EXPENSIVE_SHARPENING-NEXT: --> {(-1 + %n),+,-1}<nw><%loop> U: [0,2147483647) S: [0,2147483647) Exits: 0 LoopDispositions: { %loop: Computable }
; EXPENSIVE_SHARPENING-NEXT: %a = sub i32 %n, %i
; EXPENSIVE_SHARPENING-NEXT: --> {%n,+,-1}<nw><%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: 1 LoopDispositions: { %loop: Computable }
; EXPENSIVE_SHARPENING-NEXT: %b = sub i32 %n.minus.1, %i
-; EXPENSIVE_SHARPENING-NEXT: --> {(-1 + %n),+,-1}<nsw><%loop> U: [0,2147483647) S: [0,2147483647) Exits: 0 LoopDispositions: { %loop: Computable }
+; EXPENSIVE_SHARPENING-NEXT: --> {(-1 + %n),+,-1}<nw><%loop> U: [0,2147483647) S: [0,2147483647) Exits: 0 LoopDispositions: { %loop: Computable }
; EXPENSIVE_SHARPENING-NEXT: %c = sub i32 2147483647, %i
; EXPENSIVE_SHARPENING-NEXT: --> {2147483647,+,-1}<nsw><%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: (-2147483648 + (-1 * %n)) LoopDispositions: { %loop: Computable }
; EXPENSIVE_SHARPENING-NEXT: %i.next = add nuw nsw i32 %i, 1
; EXPENSIVE_SHARPENING-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %n LoopDispositions: { %loop: Computable }
; EXPENSIVE_SHARPENING-NEXT: %j.next = add nsw i32 %j, -1
-; EXPENSIVE_SHARPENING-NEXT: --> {(-2 + %n),+,-1}<nsw><%loop> U: full-set S: [-1,2147483646) Exits: -1 LoopDispositions: { %loop: Computable }
+; EXPENSIVE_SHARPENING-NEXT: --> {(-2 + %n),+,-1}<nw><%loop> U: full-set S: [-1,2147483646) Exits: -1 LoopDispositions: { %loop: Computable }
; EXPENSIVE_SHARPENING-NEXT: Determining loop execution counts for: @test_step_1_flags
; EXPENSIVE_SHARPENING-NEXT: Loop %loop: backedge-taken count is (-1 + %n)
; EXPENSIVE_SHARPENING-NEXT: Loop %loop: constant max backedge-taken count is i32 2147483646
diff --git a/llvm/test/Analysis/ScalarEvolution/flags-from-poison.ll b/llvm/test/Analysis/ScalarEvolution/flags-from-poison.ll
index 593888f5f7bd59..cf8f487ace5807 100644
--- a/llvm/test/Analysis/ScalarEvolution/flags-from-poison.ll
+++ b/llvm/test/Analysis/ScalarEvolution/flags-from-poison.ll
@@ -602,13 +602,13 @@ define void @test-add-not-header5(ptr %input, i32 %offset) {
; CHECK-LABEL: 'test-add-not-header5'
; CHECK-NEXT: Classifying expressions for: @test-add-not-header5
; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]
-; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %index32 = add nsw i32 %i, %offset
-; CHECK-NEXT: --> {%offset,+,1}<nw><%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: --> {%offset,+,1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %ptr = getelementptr inbounds float, ptr %input, i32 %index32
-; CHECK-NEXT: --> ((4 * (sext i32 {%offset,+,1}<nw><%loop> to i64))<nsw> + %input) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: --> ((4 * (sext i32 {%offset,+,1}<%loop> to i64))<nsw> + %input) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %nexti = add nsw i32 %i, 1
-; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
; CHECK-NEXT: Determining loop execution counts for: @test-add-not-header5
; CHECK-NEXT: Loop %loop: <multiple exits> Unpredictable backedge-taken count.
; CHECK-NEXT: Loop %loop: Unpredictable constant max backedge-taken count.
diff --git a/llvm/test/Analysis/ScalarEvolution/max-expr-cache.ll b/llvm/test/Analysis/ScalarEvolution/max-expr-cache.ll
index e1c05c4b431f39..794414a771e430 100644
--- a/llvm/test/Analysis/ScalarEvolution/max-expr-cache.ll
+++ b/llvm/test/Analysis/ScalarEvolution/max-expr-cache.ll
@@ -11,7 +11,7 @@ define void @smax(i32 %tmp3) {
; CHECK-LABEL: 'smax'
; CHECK-NEXT: Classifying expressions for: @smax
; CHECK-NEXT: %tmp5 = phi i64 [ %tmp62, %bb61 ], [ 0, %entry ]
-; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%bb4> U: [0,-9223372036854775808) S: [0,-9223372036854775808) Exits: <<Unknown>> LoopDispositions: { %bb4: Computable, %bb53: Invariant }
+; CHECK-NEXT: --> {0,+,1}<%bb4> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb4: Computable, %bb53: Invariant }
; CHECK-NEXT: %tmp6 = trunc i64 %tmp5 to i32
; CHECK-NEXT: --> {0,+,1}<%bb4> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb4: Computable, %bb53: Invariant }
; CHECK-NEXT: %tmp7 = shl nsw i32 %tmp6, 8
@@ -85,7 +85,7 @@ define void @smax(i32 %tmp3) {
; CHECK-NEXT: %tmp59 = add nsw i64 %tmp54, 1
; CHECK-NEXT: --> {(1 + undef),+,1}<nsw><%bb53> U: full-set S: full-set Exits: (zext i32 (0 smax %tmp49) to i64) LoopDispositions: { %bb53: Computable, %bb4: Variant }
; CHECK-NEXT: %tmp62 = add nuw nsw i64 %tmp5, 1
-; CHECK-NEXT: --> {1,+,1}<nuw><%bb4> U: [1,0) S: [1,0) Exits: <<Unknown>> LoopDispositions: { %bb4: Computable, %bb53: Invariant }
+; CHECK-NEXT: --> {1,+,1}<%bb4> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb4: Computable, %bb53: Invariant }
; CHECK-NEXT: Determining loop execution counts for: @smax
; CHECK-NEXT: Loop %bb53: backedge-taken count is (-1 + (zext i32 (0 smax %tmp49) to i64) + (-1 * undef))
; CHECK-NEXT: Loop %bb53: constant max backedge-taken count is i64 -1
@@ -170,7 +170,7 @@ define void @umax(i32 %tmp3) {
; CHECK-LABEL: 'umax'
; CHECK-NEXT: Classifying expressions for: @umax
; CHECK-NEXT: %tmp5 = phi i64 [ %tmp62, %bb61 ], [ 0, %entry ]
-; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%bb4> U: [0,-9223372036854775808) S: [0,-9223372036854775808) Exits: <<Unknown>> LoopDispositions: { %bb4: Computable, %bb53: Invariant }
+; CHECK-NEXT: --> {0,+,1}<%bb4> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb4: Computable, %bb53: Invariant }
; CHECK-NEXT: %tmp6 = trunc i64 %tmp5 to i32
; CHECK-NEXT: --> {0,+,1}<%bb4> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb4: Computable, %bb53: Invariant }
; CHECK-NEXT: %tmp7 = shl nsw i32 %tmp6, 8
@@ -244,7 +244,7 @@ define void @umax(i32 %tmp3) {
; CHECK-NEXT: %tmp59 = add nsw i64 %tmp54, 1
; CHECK-NEXT: --> {(1 + undef),+,1}<nsw><%bb53> U: full-set S: full-set Exits: (zext i32 %tmp49 to i64) LoopDispositions: { %bb53: Computable, %bb4: Variant }
; CHECK-NEXT: %tmp62 = add nuw nsw i64 %tmp5, 1
-; CHECK-NEXT: --> {1,+,1}<nuw><%bb4> U: [1,0) S: [1,0) Exits: <<Unknown>> LoopDispositions: { %bb4: Computable, %bb53: Invariant }
+; CHECK-NEXT: --> {1,+,1}<%bb4> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %bb4: Computable, %bb53: Invariant }
; CHECK-NEXT: Determining loop execution counts for: @umax
; CHECK-NEXT: Loop %bb53: backedge-taken count is (-1 + (zext i32 %tmp49 to i64) + (-1 * undef))
; CHECK-NEXT: Loop %bb53: constant max backedge-taken count is i64 -1
diff --git a/llvm/test/Analysis/ScalarEvolution/nowrap-preinc-limits.ll b/llvm/test/Analysis/ScalarEvolution/nowrap-preinc-limits.ll
index 3b414f2182ed56..6824c86624df83 100644
--- a/llvm/test/Analysis/ScalarEvolution/nowrap-preinc-limits.ll
+++ b/llvm/test/Analysis/ScalarEvolution/nowrap-preinc-limits.ll
@@ -1,45 +1,78 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 2
; RUN: opt -disable-output "-passes=print<scalar-evolution>" < %s 2>&1 | FileCheck %s
define void @f(ptr %condition) {
-; CHECK-LABEL: Classifying expressions for: @f
- entry:
+; CHECK-LABEL: 'f'
+; CHECK-NEXT: Classifying expressions for: @f
+; CHECK-NEXT: %idx = phi i32 [ 0, %entry ], [ %idx.inc, %loop ]
+; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: %idx.inc = add nsw i32 %idx, 1
+; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: %idx.inc2 = add i32 %idx.inc, 1
+; CHECK-NEXT: --> {2,+,1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: %idx.inc2.zext = zext i32 %idx.inc2 to i64
+; CHECK-NEXT: --> (zext i32 {2,+,1}<%loop> to i64) U: [0,4294967296) S: [0,4294967296) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: %c = load volatile i1, ptr %condition, align 1
+; CHECK-NEXT: --> %c U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
+; CHECK-NEXT: Determining loop execution counts for: @f
+; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count.
+; CHECK-NEXT: Loop %loop: Unpredictable constant max backedge-taken count.
+; CHECK-NEXT: Loop %loop: Unpredictable symbolic max backedge-taken count.
+; CHECK-NEXT: Loop %loop: Unpredictable predicated backedge-taken count.
+;
+ entry:
br label %loop
- loop:
+ loop:
%idx = phi i32 [ 0, %entry ], [ %idx.inc, %loop ]
%idx.inc = add nsw i32 %idx, 1
%idx.inc2 = add i32 %idx.inc, 1
%idx.inc2.zext = zext i32 %idx.inc2 to i64
-; CHECK: %idx.inc2.zext = zext i32 %idx.inc2 to i64
-; CHECK-NEXT: --> {2,+,1}<nuw><%loop>
%c = load volatile i1, ptr %condition
br i1 %c, label %loop, label %exit
- exit:
+ exit:
ret void
}
define void @g(ptr %condition) {
-; CHECK-LABEL: Classifying expressions for: @g
- entry:
+; CHECK-LABEL: 'g'
+; CHECK-NEXT: Classifying expressions for: @g
+; CHECK-NEXT: %idx = phi i32 [ 0, %entry ], [ %idx.inc, %loop ]
+; CHECK-NEXT: --> {0,+,3}<nuw><nsw><%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: %idx.inc = add nsw i32 %idx, 3
+; CHECK-NEXT: --> {3,+,3}<nuw><nsw><%loop> U: [3,-2147483648) S: [3,-2147483648) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: %idx.inc2 = add i32 %idx.inc, -1
+; CHECK-NEXT: --> {2,+,3}<nuw><nsw><%loop> U: [2,-2147483648) S: [2,-2147483648) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: %idx.inc2.sext = sext i32 %idx.inc2 to i64
+; CHECK-NEXT: --> {2,+,3}<nuw><nsw><%loop> U: [2,-9223372036854775808) S: [2,-9223372036854775808) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: %cond.gep = getelementptr inbounds i1, ptr %condition, i32 %idx.inc
+; CHECK-NEXT: --> {(3 + %condition)<nuw>,+,3}<nuw><%loop> U: [3,0) S: [3,0) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: %c = load volatile i1, ptr %cond.gep, align 1
+; CHECK-NEXT: --> %c U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
+; CHECK-NEXT: Determining loop execution counts for: @g
+; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count.
+; CHECK-NEXT: Loop %loop: Unpredictable constant max backedge-taken count.
+; CHECK-NEXT: Loop %loop: Unpredictable symbolic max backedge-taken count.
+; CHECK-NEXT: Loop %loop: Unpredictable predicated backedge-taken count.
+;
+ entry:
br label %loop
- loop:
+ loop:
%idx = phi i32 [ 0, %entry ], [ %idx.inc, %loop ]
%idx.inc = add nsw i32 %idx, 3
%idx.inc2 = add i32 %idx.inc, -1
%idx.inc2.sext = sext i32 %idx.inc2 to i64
-; CHECK: %idx.inc2.sext = sext i32 %idx.inc2 to i64
-; CHECK-NEXT: --> {2,+,3}<nuw><nsw><%loop>
%cond.gep = getelementptr inbounds i1, ptr %condition, i32 %idx.inc
%c = load volatile i1, ptr %cond.gep
br i1 %c, label %loop, label %exit
- exit:
+ exit:
ret void
}
diff --git a/llvm/test/Analysis/ScalarEvolution/pr27315.ll b/llvm/test/Analysis/ScalarEvolution/pr27315.ll
index 1c99075f5f1b4f..5f08b180f50588 100644
--- a/llvm/test/Analysis/ScalarEvolution/pr27315.ll
+++ b/llvm/test/Analysis/ScalarEvolution/pr27315.ll
@@ -1,16 +1,34 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 2
; RUN: opt -disable-output "-passes=print<scalar-evolution>" < %s 2>&1 | FileCheck %s
declare i1 @use(i64)
define void @f_0() {
-; CHECK-LABEL: Classifying expressions for: @f_0
+; CHECK-LABEL: 'f_0'
+; CHECK-NEXT: Classifying expressions for: @f_0
+; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.inc.nowrap, %be ]
+; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: %iv.inc.maywrap = add i32 %iv, 1
+; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: %iv.inc.maywrap.sext = sext i32 %iv.inc.maywrap to i64
+; CHECK-NEXT: --> (sext i32 {1,+,1}<%loop> to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: %cond0 = call i1 @use(i64 %iv.inc.maywrap.sext)
+; CHECK-NEXT: --> %cond0 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
+; CHECK-NEXT: %iv.inc.nowrap = add nsw i32 %iv, 1
+; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: %be.cond = call i1 @use(i64 0)
+; CHECK-NEXT: --> %be.cond U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
+; CHECK-NEXT: Determining loop execution counts for: @f_0
+; CHECK-NEXT: Loop %loop: <multiple exits> Unpredictable backedge-taken count.
+; CHECK-NEXT: exit count for loop: ***COULDNOTCOMPUTE***
+; CHECK-NEXT: exit count for be: ***COULDNOTCOMPUTE***
+; CHECK-NEXT: Loop %loop: Unpredictable constant max backedge-taken count.
+; CHECK-NEXT: Loop %loop: Unpredictable symbolic max backedge-taken count.
+; CHECK-NEXT: symbolic max exit count for loop: ***COULDNOTCOMPUTE***
+; CHECK-NEXT: symbolic max exit count for be: ***COULDNOTCOMPUTE***
+; CHECK-NEXT: Loop %loop: Unpredictable predicated backedge-taken count.
+;
-; CHECK: %iv = phi i32 [ 0, %entry ], [ %iv.inc.nowrap, %be ]
-; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop>
-; CHECK: %iv.inc.maywrap = add i32 %iv, 1
-; CHECK-NEXT: --> {1,+,1}<nuw><%loop>
-; CHECK: %iv.inc.maywrap.sext = sext i32 %iv.inc.maywrap to i64
-; CHECK-NEXT: --> (sext i32 {1,+,1}<nuw><%loop> to i64)
entry:
br label %loop
diff --git a/llvm/test/Analysis/ScalarEvolution/range-signedness.ll b/llvm/test/Analysis/ScalarEvolution/range-signedness.ll
index 2b91ac1109ed4a..8ef6398b5a5bdb 100644
--- a/llvm/test/Analysis/ScalarEvolution/range-signedness.ll
+++ b/llvm/test/Analysis/ScalarEvolution/range-signedness.ll
@@ -5,9 +5,9 @@ define void @x(ptr %cond) {
; CHECK-LABEL: 'x'
; CHECK-NEXT: Classifying expressions for: @x
; CHECK-NEXT: %idx = phi i8 [ 0, %entry ], [ %idx.inc, %loop ]
-; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-128) S: [0,-128) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %idx.inc = add nsw i8 %idx, 1
-; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: --> {1,+,1}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %c = load volatile i1, ptr %cond, align 1
; CHECK-NEXT: --> %c U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }
; CHECK-NEXT: Determining loop execution counts for: @x
diff --git a/llvm/test/Analysis/ScalarEvolution/smin-smax-folds.ll b/llvm/test/Analysis/ScalarEvolution/smin-smax-folds.ll
index e6872168d5bc22..154b1a23b79365 100644
--- a/llvm/test/Analysis/ScalarEvolution/smin-smax-folds.ll
+++ b/llvm/test/Analysis/ScalarEvolution/smin-smax-folds.ll
@@ -29,7 +29,7 @@ define void @smin_simplify_with_guard(i32 %n) {
; CHECK-LABEL: 'smin_simplify_with_guard'
; CHECK-NEXT: Classifying expressions for: @smin_simplify_with_guard
; CHECK-NEXT: %i.011 = phi i32 [ %n, %for.body.lr.ph ], [ %dec, %for.body ]
-; CHECK-NEXT: --> {%n,+,-1}<nsw><%for.body> U: full-set S: full-set Exits: 0 LoopDispositions: { %for.body: Computable }
+; CHECK-NEXT: --> {%n,+,-1}<nw><%for.body> U: full-set S: full-set Exits: 0 LoopDispositions: { %for.body: Computable }
; CHECK-NEXT: %dec = add nsw i32 %i.011, -1
; CHECK-NEXT: --> {(-1 + %n),+,-1}<nw><%for.body> U: full-set S: full-set Exits: -1 LoopDispositions: { %for.body: Computable }
; CHECK-NEXT: Determining loop execution counts for: @smin_simplify_with_guard
@@ -64,7 +64,7 @@ define void @smin_to_smax(i32 %n) {
; CHECK-LABEL: 'smin_to_smax'
; CHECK-NEXT: Classifying expressions for: @smin_to_smax
; CHECK-NEXT: %i.011 = phi i32 [ %n, %for.body.lr.ph ], [ %dec, %for.body ]
-; CHECK-NEXT: --> {%n,+,-1}<nsw><%for.body> U: full-set S: full-set Exits: (0 smin %n) LoopDispositions: { %for.body: Computable }
+; CHECK-NEXT: --> {%n,+,-1}<nw><%for.body> U: full-set S: full-set Exits: (0 smin %n) LoopDispositions: { %for.body: Computable }
; CHECK-NEXT: %dec = add nsw i32 %i.011, -1
; CHECK-NEXT: --> {(-1 + %n),+,-1}<nw><%for.body> U: full-set S: full-set Exits: (-1 + (0 smin %n)) LoopDispositions: { %for.body: Computable }
; CHECK-NEXT: Determining loop execution counts for: @smin_to_smax
diff --git a/llvm/test/Transforms/IndVarSimplify/X86/pr27133.ll b/llvm/test/Transforms/IndVarSimplify/X86/pr27133.ll
index b7d070045ea618..85c2a07f30ef19 100644
--- a/llvm/test/Transforms/IndVarSimplify/X86/pr27133.ll
+++ b/llvm/test/Transforms/IndVarSimplify/X86/pr27133.ll
@@ -8,8 +8,8 @@ define i32 @fn2() personality ptr @__CxxFrameHandler3 {
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[FOR_COND:%.*]]
; CHECK: for.cond:
-; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 0, [[ENTRY:%.*]] ]
-; CHECK-NEXT: [[INDVARS1:%.*]] = trunc i64 [[INDVARS_IV]] to i32
+; CHECK-NEXT: [[INDVARS1:%.*]] = phi i32 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[ENTRY:%.*]] ]
+; CHECK-NEXT: [[INDVARS_IV:%.*]] = sext i32 [[INDVARS1]] to i64
; CHECK-NEXT: invoke void @fn1(i64 [[INDVARS_IV]])
; CHECK-NEXT: to label [[FOR_INC]] unwind label [[CATCH_DISPATCH:%.*]]
; CHECK: catch.dispatch:
@@ -21,7 +21,7 @@ define i32 @fn2() personality ptr @__CxxFrameHandler3 {
; CHECK: exit:
; CHECK-NEXT: ret i32 [[C_0_LCSSA]]
; CHECK: for.inc:
-; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[INDVARS1]], 1
; CHECK-NEXT: br label [[FOR_COND]]
;
entry:
diff --git a/llvm/test/Transforms/IndVarSimplify/iv-poison.ll b/llvm/test/Transforms/IndVarSimplify/iv-poison.ll
index 383599f6143575..adb3132b35fe78 100644
--- a/llvm/test/Transforms/IndVarSimplify/iv-poison.ll
+++ b/llvm/test/Transforms/IndVarSimplify/iv-poison.ll
@@ -92,10 +92,10 @@ define i4 @iv_hoist_both_adds_nsw_extra_use(i4 %arg) {
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV_0:%.*]] = phi i4 [ 1, [[BB:%.*]] ], [ [[IV_0_NEXT:%.*]], [[LOOP]] ]
-; CHECK-NEXT: [[IV_0_NEXT]] = add nuw nsw i4 [[IV_0]], 1
+; CHECK-NEXT: [[IV_0_NEXT]] = add nsw i4 [[IV_0]], 1
; CHECK-NEXT: call void @use(i4 [[IV_0_NEXT]])
; CHECK-NEXT: call void @use(i4 [[IV_0_NEXT]])
-; CHECK-NEXT: [[DOTNOT_NOT:%.*]] = icmp ult i4 1, [[ARG:%.*]]
+; CHECK-NEXT: [[DOTNOT_NOT:%.*]] = icmp ult i4 [[IV_0]], [[ARG:%.*]]
; CHECK-NEXT: br i1 [[DOTNOT_NOT]], label [[EXIT:%.*]], label [[LOOP]]
; CHECK: exit:
; CHECK-NEXT: [[IV_1_NEXT_LCSSA:%.*]] = phi i4 [ [[IV_0_NEXT]], [[LOOP]] ]
@@ -124,10 +124,10 @@ define i4 @iv_hoist_both_adds_nsw_extra_use_incs_reordered(i4 %arg) {
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[IV_0:%.*]] = phi i4 [ 1, [[BB:%.*]] ], [ [[IV_0_NEXT:%.*]], [[LOOP]] ]
-; CHECK-NEXT: [[IV_0_NEXT]] = add nuw nsw i4 [[IV_0]], 1
+; CHECK-NEXT: [[IV_0_NEXT]] = add nsw i4 [[IV_0]], 1
; CHECK-NEXT: call void @use(i4 [[IV_0_NEXT]])
; CHECK-NEXT: call void @use(i4 [[IV_0_NEXT]])
-; CHECK-NEXT: [[DOTNOT_NOT:%.*]] = icmp ult i4 1, [[ARG:%.*]]
+; CHECK-NEXT: [[DOTNOT_NOT:%.*]] = icmp ult i4 [[IV_0]], [[ARG:%.*]]
; CHECK-NEXT: br i1 [[DOTNOT_NOT]], label [[EXIT:%.*]], label [[LOOP]]
; CHECK: exit:
; CHECK-NEXT: [[IV_1_NEXT_LCSSA:%.*]] = phi i4 [ [[IV_0_NEXT]], [[LOOP]] ]
@@ -217,7 +217,7 @@ define i4 @iv_hoist_nuw_poison2(i4 %0, i4 %end, i4 %start) {
; CHECK: loop:
; CHECK-NEXT: [[IV_0:%.*]] = phi i4 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_0_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[IV_0_NEXT]] = add i4 [[IV_0]], 1
-; CHECK-NEXT: [[DOTNOT_NOT:%.*]] = icmp ult i4 [[START]], [[END:%.*]]
+; CHECK-NEXT: [[DOTNOT_NOT:%.*]] = icmp ult i4 [[IV_0]], [[END:%.*]]
; CHECK-NEXT: br i1 [[DOTNOT_NOT]], label [[EXIT:%.*]], label [[LOOP]]
; CHECK: exit:
; CHECK-NEXT: [[IV_1_NEXT_LCSSA:%.*]] = phi i4 [ [[IV_0_NEXT]], [[LOOP]] ]
@@ -275,7 +275,7 @@ define i4 @iv_hoist_both_adds_nuw_extra_use(i4 %arg, i4 %start) {
; CHECK-NEXT: [[IV_0_NEXT]] = add nuw i4 [[IV_0]], 1
; CHECK-NEXT: call void @use(i4 [[IV_0_NEXT]])
; CHECK-NEXT: call void @use(i4 [[IV_0_NEXT]])
-; CHECK-NEXT: [[DOTNOT_NOT:%.*]] = icmp ult i4 [[START]], [[ARG:%.*]]
+; CHECK-NEXT: [[DOTNOT_NOT:%.*]] = icmp ult i4 [[IV_0]], [[ARG:%.*]]
; CHECK-NEXT: br i1 [[DOTNOT_NOT]], label [[EXIT:%.*]], label [[LOOP]]
; CHECK: exit:
; CHECK-NEXT: [[IV_1_NEXT_LCSSA:%.*]] = phi i4 [ [[IV_0_NEXT]], [[LOOP]] ]
@@ -307,7 +307,7 @@ define i4 @iv_hoist_both_adds_nuw_extra_use_incs_reordered(i4 %arg, i4 %start) {
; CHECK-NEXT: [[IV_0_NEXT]] = add nuw i4 [[IV_0]], 1
; CHECK-NEXT: call void @use(i4 [[IV_0_NEXT]])
; CHECK-NEXT: call void @use(i4 [[IV_0_NEXT]])
-; CHECK-NEXT: [[DOTNOT_NOT:%.*]] = icmp ult i4 [[START]], [[ARG:%.*]]
+; CHECK-NEXT: [[DOTNOT_NOT:%.*]] = icmp ult i4 [[IV_0]], [[ARG:%.*]]
; CHECK-NEXT: br i1 [[DOTNOT_NOT]], label [[EXIT:%.*]], label [[LOOP]]
; CHECK: exit:
; CHECK-NEXT: [[IV_1_NEXT_LCSSA:%.*]] = phi i4 [ [[IV_0_NEXT]], [[LOOP]] ]
@@ -338,7 +338,7 @@ define i4 @iv_hoist_nuw_poison_extra_use(i4 %0, i4 %end, i4 %start) {
; CHECK-NEXT: [[IV_0:%.*]] = phi i4 [ [[START:%.*]], [[ENTRY:%.*]] ], [ [[IV_0_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[IV_0_NEXT]] = add i4 [[IV_0]], 1
; CHECK-NEXT: call void @use(i4 [[IV_0_NEXT]])
-; CHECK-NEXT: [[DOTNOT_NOT:%.*]] = icmp ult i4 [[START]], [[END:%.*]]
+; CHECK-NEXT: [[DOTNOT_NOT:%.*]] = icmp ult i4 [[IV_0]], [[END:%.*]]
; CHECK-NEXT: br i1 [[DOTNOT_NOT]], label [[EXIT:%.*]], label [[LOOP]]
; CHECK: exit:
; CHECK-NEXT: [[IV_1_NEXT_LCSSA:%.*]] = phi i4 [ [[IV_0_NEXT]], [[LOOP]] ]
diff --git a/llvm/test/Transforms/IndVarSimplify/lftr-pr31181.ll b/llvm/test/Transforms/IndVarSimplify/lftr-pr31181.ll
index e836a7dfccea07..facb977a3cbc39 100644
--- a/llvm/test/Transforms/IndVarSimplify/lftr-pr31181.ll
+++ b/llvm/test/Transforms/IndVarSimplify/lftr-pr31181.ll
@@ -286,7 +286,7 @@ define i32 @switch_to_different_iv_first_poison(ptr %ptr, i1 %always_false) {
; CHECK-NEXT: store volatile i32 [[IV2]], ptr [[PTR]], align 4
; CHECK-NEXT: br label [[ALWAYS_TAKEN]]
; CHECK: always_taken:
-; CHECK-NEXT: [[IV2_INC]] = add nuw nsw i32 [[IV2]], 1
+; CHECK-NEXT: [[IV2_INC]] = add nuw i32 [[IV2]], 1
; CHECK-NEXT: [[IV_INC]] = add nsw i32 [[IV]], 1
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[IV2_INC]], -2147483628
; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_COND]], label [[FOR_END:%.*]]
@@ -329,7 +329,7 @@ define i32 @switch_to_different_iv_second_poison(ptr %ptr, i1 %always_false) {
; CHECK-NEXT: store volatile i32 [[IV2]], ptr [[PTR]], align 4
; CHECK-NEXT: br label [[ALWAYS_TAKEN]]
; CHECK: always_taken:
-; CHECK-NEXT: [[IV2_INC]] = add nsw i32 [[IV2]], 1
+; CHECK-NEXT: [[IV2_INC]] = add i32 [[IV2]], 1
; CHECK-NEXT: [[IV_INC]] = add nsw i32 [[IV]], 1
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[IV2_INC]], -2147483629
; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_COND]], label [[FOR_END:%.*]]
diff --git a/llvm/test/Transforms/IndVarSimplify/lftr.ll b/llvm/test/Transforms/IndVarSimplify/lftr.ll
index def2cd9b8c6792..5f9f721b498bd4 100644
--- a/llvm/test/Transforms/IndVarSimplify/lftr.ll
+++ b/llvm/test/Transforms/IndVarSimplify/lftr.ll
@@ -229,16 +229,13 @@ define void @test_udiv_as_shift(ptr %a, i8 %n) nounwind uwtable ssp {
; CHECK-NEXT: [[E:%.*]] = icmp sgt i8 [[N:%.*]], 3
; CHECK-NEXT: br i1 [[E]], label [[LOOP_PREHEADER:%.*]], label [[EXIT:%.*]]
; CHECK: loop.preheader:
-; CHECK-NEXT: [[TMP0:%.*]] = add i8 [[N]], 3
-; CHECK-NEXT: [[TMP1:%.*]] = lshr i8 [[TMP0]], 2
-; CHECK-NEXT: [[TMP2:%.*]] = add nuw nsw i8 [[TMP1]], 1
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
-; CHECK-NEXT: [[I1:%.*]] = phi i8 [ [[I1_INC:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
-; CHECK-NEXT: [[I1_INC]] = add nuw nsw i8 [[I1]], 1
+; CHECK-NEXT: [[I:%.*]] = phi i8 [ [[I_INC:%.*]], [[LOOP]] ], [ 0, [[LOOP_PREHEADER]] ]
+; CHECK-NEXT: [[I_INC]] = add nsw i8 [[I]], 4
; CHECK-NEXT: store volatile i8 0, ptr [[A:%.*]], align 1
-; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i8 [[I1_INC]], [[TMP2]]
-; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
+; CHECK-NEXT: [[C:%.*]] = icmp slt i8 [[I]], [[N]]
+; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
; CHECK: exit.loopexit:
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
diff --git a/llvm/test/Transforms/IndVarSimplify/no-iv-rewrite.ll b/llvm/test/Transforms/IndVarSimplify/no-iv-rewrite.ll
index 5bd28470ef76be..780a0229561861 100644
--- a/llvm/test/Transforms/IndVarSimplify/no-iv-rewrite.ll
+++ b/llvm/test/Transforms/IndVarSimplify/no-iv-rewrite.ll
@@ -469,8 +469,7 @@ define void @phiUsesTrunc(i1 %arg) nounwind {
; CHECK: for.body.preheader:
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
; CHECK: for.body:
-; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 1, [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ]
-; CHECK-NEXT: [[TMP0:%.*]] = trunc nuw nsw i64 [[INDVARS_IV]] to i32
+; CHECK-NEXT: [[TMP0:%.*]] = phi i32 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 1, [[FOR_BODY_PREHEADER]] ]
; CHECK-NEXT: br i1 [[ARG]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
; CHECK: if.then:
; CHECK-NEXT: br i1 [[ARG]], label [[IF_THEN33:%.*]], label [[FOR_INC]]
@@ -479,12 +478,13 @@ define void @phiUsesTrunc(i1 %arg) nounwind {
; CHECK: if.else:
; CHECK-NEXT: br i1 [[ARG]], label [[IF_THEN97:%.*]], label [[FOR_INC]]
; CHECK: if.then97:
+; CHECK-NEXT: [[INDVARS_IV:%.*]] = sext i32 [[TMP0]] to i64
; CHECK-NEXT: call void @use64(i64 [[INDVARS_IV]])
; CHECK-NEXT: br label [[FOR_INC]]
; CHECK: for.inc:
; CHECK-NEXT: [[KMIN_1:%.*]] = phi i32 [ [[TMP0]], [[IF_THEN33]] ], [ 0, [[IF_THEN]] ], [ [[TMP0]], [[IF_THEN97]] ], [ 0, [[IF_ELSE]] ]
; CHECK-NEXT: call void @use32(i32 [[KMIN_1]])
-; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT: [[INC]] = add nsw i32 [[TMP0]], 1
; CHECK-NEXT: br i1 [[ARG]], label [[FOR_BODY]], label [[FOR_END_LOOPEXIT:%.*]]
; CHECK: for.end.loopexit:
; CHECK-NEXT: br label [[FOR_END]]
diff --git a/llvm/test/Transforms/IndVarSimplify/pr30806-phi-scev.ll b/llvm/test/Transforms/IndVarSimplify/pr30806-phi-scev.ll
index 6a2bbfa5447a9d..a2dee39fb1c764 100644
--- a/llvm/test/Transforms/IndVarSimplify/pr30806-phi-scev.ll
+++ b/llvm/test/Transforms/IndVarSimplify/pr30806-phi-scev.ll
@@ -40,16 +40,16 @@ define void @foo(ptr %buf, i32 %denominator, ptr %flag) local_unnamed_addr {
; CHECK: while.body.lr.ph:
; CHECK-NEXT: br label [[WHILE_BODY:%.*]]
; CHECK: while.body:
-; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_LR_PH]] ]
; CHECK-NEXT: [[BUF_ADDR_07:%.*]] = phi ptr [ [[BUF]], [[WHILE_BODY_LR_PH]] ], [ [[CALL:%.*]], [[WHILE_BODY]] ]
-; CHECK-NEXT: [[TMP2:%.*]] = sext i32 [[DIV]] to i64
-; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], [[TMP2]]
-; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr @theSize, align 4
-; CHECK-NEXT: store i32 [[TMP3]], ptr [[I]], align 4
-; CHECK-NEXT: call void @bar(ptr nonnull [[I]], i64 [[INDVARS_IV_NEXT]])
+; CHECK-NEXT: [[INX_06:%.*]] = phi i32 [ 0, [[WHILE_BODY_LR_PH]] ], [ [[ADD:%.*]], [[WHILE_BODY]] ]
+; CHECK-NEXT: [[ADD]] = add nsw i32 [[INX_06]], [[DIV]]
+; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr @theSize, align 4
+; CHECK-NEXT: store i32 [[TMP2]], ptr [[I]], align 4
+; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[ADD]] to i64
+; CHECK-NEXT: call void @bar(ptr nonnull [[I]], i64 [[CONV]])
; CHECK-NEXT: [[CALL]] = call ptr @processBuf(ptr [[BUF_ADDR_07]])
-; CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[FLAG]], align 4
-; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[TMP4]], 0
+; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[FLAG]], align 4
+; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[TMP3]], 0
; CHECK-NEXT: br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
; CHECK: while.end.loopexit:
; CHECK-NEXT: br label [[WHILE_END]]
diff --git a/llvm/test/Transforms/IndVarSimplify/pr55925.ll b/llvm/test/Transforms/IndVarSimplify/pr55925.ll
index 2ad187add4e107..c0bc9961bcbeb0 100644
--- a/llvm/test/Transforms/IndVarSimplify/pr55925.ll
+++ b/llvm/test/Transforms/IndVarSimplify/pr55925.ll
@@ -13,14 +13,14 @@ define void @test(ptr %p) personality ptr undef {
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
-; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ]
-; CHECK-NEXT: [[TMP0:%.*]] = trunc nuw i64 [[INDVARS_IV]] to i32
+; CHECK-NEXT: [[TMP0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
; CHECK-NEXT: [[RES:%.*]] = invoke i32 @foo(i32 returned [[TMP0]])
; CHECK-NEXT: to label [[LOOP_LATCH]] unwind label [[EXIT:%.*]]
; CHECK: loop.latch:
-; CHECK-NEXT: [[TMP1:%.*]] = trunc nuw i64 [[INDVARS_IV]] to i32
-; CHECK-NEXT: [[TMP2:%.*]] = call i32 @foo(i32 [[TMP1]])
-; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1
+; CHECK-NEXT: [[EXT:%.*]] = zext i32 [[TMP0]] to i64
+; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 [[EXT]]
+; CHECK-NEXT: [[IV_NEXT]] = add i32 [[TMP0]], 1
+; CHECK-NEXT: [[TMP1:%.*]] = call i32 @foo(i32 [[TMP0]])
; CHECK-NEXT: br label [[LOOP]]
; CHECK: exit:
; CHECK-NEXT: [[LP:%.*]] = landingpad { ptr, i32 }
@@ -53,19 +53,19 @@ define void @test_critedge(i1 %c, ptr %p) personality ptr undef {
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
-; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ], [ 0, [[ENTRY:%.*]] ]
+; CHECK-NEXT: [[TMP0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
; CHECK-NEXT: br i1 [[C:%.*]], label [[LOOP_INVOKE:%.*]], label [[LOOP_OTHER:%.*]]
; CHECK: loop.invoke:
-; CHECK-NEXT: [[TMP0:%.*]] = trunc nuw i64 [[INDVARS_IV]] to i32
-; CHECK-NEXT: [[TMP1:%.*]] = trunc nuw i64 [[INDVARS_IV]] to i32
; CHECK-NEXT: [[RES:%.*]] = invoke i32 @foo(i32 returned [[TMP0]])
; CHECK-NEXT: to label [[LOOP_LATCH]] unwind label [[EXIT:%.*]]
; CHECK: loop.other:
; CHECK-NEXT: br label [[LOOP_LATCH]]
; CHECK: loop.latch:
-; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[TMP1]], [[LOOP_INVOKE]] ], [ 0, [[LOOP_OTHER]] ]
+; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[TMP0]], [[LOOP_INVOKE]] ], [ 0, [[LOOP_OTHER]] ]
+; CHECK-NEXT: [[EXT:%.*]] = zext i32 [[TMP0]] to i64
+; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 [[EXT]]
+; CHECK-NEXT: [[IV_NEXT]] = add i32 [[TMP0]], 1
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @foo(i32 [[PHI]])
-; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add i64 [[INDVARS_IV]], 1
; CHECK-NEXT: br label [[LOOP]]
; CHECK: exit:
; CHECK-NEXT: [[LP:%.*]] = landingpad { ptr, i32 }
diff --git a/llvm/test/Transforms/IndVarSimplify/scev-expander-preserve-lcssa.ll b/llvm/test/Transforms/IndVarSimplify/scev-expander-preserve-lcssa.ll
index 14e06fe06b4126..a478e46e8a59bd 100644
--- a/llvm/test/Transforms/IndVarSimplify/scev-expander-preserve-lcssa.ll
+++ b/llvm/test/Transforms/IndVarSimplify/scev-expander-preserve-lcssa.ll
@@ -437,7 +437,7 @@ define void @test6(i8 %x) {
; CHECK-NEXT: br label [[WHILE_COND192]]
; CHECK: while.cond215:
; CHECK-NEXT: [[I_8_IN:%.*]] = phi i32 [ [[I_8:%.*]], [[WHILE_COND215]] ], [ [[I_7_LCSSA]], [[WHILE_COND215_PREHEADER]] ]
-; CHECK-NEXT: [[I_8]] = add nuw nsw i32 [[I_8_IN]], 1
+; CHECK-NEXT: [[I_8]] = add nsw i32 [[I_8_IN]], 1
; CHECK-NEXT: [[IDXPROM216:%.*]] = sext i32 [[I_8]] to i64
; CHECK-NEXT: [[ARRAYIDX217:%.*]] = getelementptr inbounds [512 x i8], ptr null, i64 0, i64 [[IDXPROM216]]
; CHECK-NEXT: br label [[WHILE_COND215]]
diff --git a/llvm/test/Transforms/IndVarSimplify/widen-nonnegative-countdown.ll b/llvm/test/Transforms/IndVarSimplify/widen-nonnegative-countdown.ll
index 9c8983421029f5..fdd02ed95ed8d4 100644
--- a/llvm/test/Transforms/IndVarSimplify/widen-nonnegative-countdown.ll
+++ b/llvm/test/Transforms/IndVarSimplify/widen-nonnegative-countdown.ll
@@ -255,14 +255,13 @@ define void @sext_preinc(ptr %A, i32 %start) {
; CHECK-NEXT: [[NONPOS:%.*]] = icmp slt i32 [[START:%.*]], 2
; CHECK-NEXT: br i1 [[NONPOS]], label [[EXIT:%.*]], label [[FOR_BODY_PREHEADER:%.*]]
; CHECK: for.body.preheader:
-; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[START]] to i64
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
; CHECK: for.body:
-; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ]
+; CHECK-NEXT: [[TMP1:%.*]] = phi i32 [ [[INC_US:%.*]], [[FOR_BODY]] ], [ [[START]], [[FOR_BODY_PREHEADER]] ]
+; CHECK-NEXT: [[INDVARS_IV:%.*]] = sext i32 [[TMP1]] to i64
; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]])
-; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
-; CHECK-NEXT: [[TMP1:%.*]] = trunc nsw i64 [[INDVARS_IV]] to i32
+; CHECK-NEXT: [[INC_US]] = add nsw i32 [[TMP1]], -1
; CHECK-NEXT: [[CMP2_US:%.*]] = icmp ugt i32 [[TMP1]], 6
; CHECK-NEXT: br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT_LOOPEXIT:%.*]]
; CHECK: exit.loopexit:
@@ -552,18 +551,15 @@ define void @sext_preinc_offset_constant_one(ptr %A, i32 %start) {
; CHECK-NEXT: [[NONPOS:%.*]] = icmp slt i32 [[START:%.*]], 2
; CHECK-NEXT: br i1 [[NONPOS]], label [[EXIT:%.*]], label [[FOR_BODY_PREHEADER:%.*]]
; CHECK: for.body.preheader:
-; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[START]] to i64
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
; CHECK: for.body:
-; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ]
-; CHECK-NEXT: [[TMP1:%.*]] = trunc nsw i64 [[INDVARS_IV]] to i32
+; CHECK-NEXT: [[TMP1:%.*]] = phi i32 [ [[INC_US:%.*]], [[FOR_BODY]] ], [ [[START]], [[FOR_BODY_PREHEADER]] ]
; CHECK-NEXT: [[ADD_US:%.*]] = add nuw i32 [[TMP1]], 1
; CHECK-NEXT: [[IDXPROM_US:%.*]] = sext i32 [[ADD_US]] to i64
; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]]
; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]])
-; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
-; CHECK-NEXT: [[TMP2:%.*]] = trunc nsw i64 [[INDVARS_IV]] to i32
-; CHECK-NEXT: [[CMP2_US:%.*]] = icmp ugt i32 [[TMP2]], 6
+; CHECK-NEXT: [[INC_US]] = add nsw i32 [[TMP1]], -1
+; CHECK-NEXT: [[CMP2_US:%.*]] = icmp ugt i32 [[TMP1]], 6
; CHECK-NEXT: br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT_LOOPEXIT:%.*]]
; CHECK: exit.loopexit:
; CHECK-NEXT: br label [[EXIT]]
@@ -847,18 +843,15 @@ define void @sext_preinc_offset_constant_minus_one(ptr %A, i32 %start) {
; CHECK-NEXT: [[NONPOS:%.*]] = icmp slt i32 [[START:%.*]], 2
; CHECK-NEXT: br i1 [[NONPOS]], label [[EXIT:%.*]], label [[FOR_BODY_PREHEADER:%.*]]
; CHECK: for.body.preheader:
-; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[START]] to i64
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
; CHECK: for.body:
-; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ]
-; CHECK-NEXT: [[TMP1:%.*]] = trunc nsw i64 [[INDVARS_IV]] to i32
+; CHECK-NEXT: [[TMP1:%.*]] = phi i32 [ [[INC_US:%.*]], [[FOR_BODY]] ], [ [[START]], [[FOR_BODY_PREHEADER]] ]
; CHECK-NEXT: [[ADD_US:%.*]] = add i32 [[TMP1]], -1
; CHECK-NEXT: [[IDXPROM_US:%.*]] = sext i32 [[ADD_US]] to i64
; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]]
; CHECK-NEXT: tail call void @use_ptr(ptr [[ARRAYIDX_US]])
-; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
-; CHECK-NEXT: [[TMP2:%.*]] = trunc nsw i64 [[INDVARS_IV]] to i32
-; CHECK-NEXT: [[CMP2_US:%.*]] = icmp ugt i32 [[TMP2]], 6
+; CHECK-NEXT: [[INC_US]] = add nsw i32 [[TMP1]], -1
+; CHECK-NEXT: [[CMP2_US:%.*]] = icmp ugt i32 [[TMP1]], 6
; CHECK-NEXT: br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT_LOOPEXIT:%.*]]
; CHECK: exit.loopexit:
; CHECK-NEXT: br label [[EXIT]]
diff --git a/llvm/test/Transforms/LoopIdiom/pr80954.ll b/llvm/test/Transforms/LoopIdiom/pr80954.ll
index 55bdcb44c2c283..98f6e42dda7382 100644
--- a/llvm/test/Transforms/LoopIdiom/pr80954.ll
+++ b/llvm/test/Transforms/LoopIdiom/pr80954.ll
@@ -9,19 +9,12 @@ define void @test(ptr %p, i8 %arg, i64 %arg1, i32 %arg2) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[SEXT:%.*]] = sext i8 [[ARG]] to i64
; CHECK-NEXT: [[ADD:%.*]] = add i64 [[ARG1]], -1
-; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[ARG2]] to i64
-; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[ARG1]], [[TMP0]]
-; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[TMP1]], [[SEXT]]
-; CHECK-NEXT: [[TMP3:%.*]] = add i64 [[TMP2]], -1
-; CHECK-NEXT: [[TMP4:%.*]] = shl i64 [[TMP3]], 2
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
-; CHECK-NEXT: [[LOOP_IDIOM_IV:%.*]] = phi ptr [ [[SCEVGEP:%.*]], [[LATCH:%.*]] ], [ [[P]], [[ENTRY:%.*]] ]
-; CHECK-NEXT: [[INDVAR:%.*]] = phi i64 [ [[INDVAR_NEXT:%.*]], [[LATCH]] ], [ 0, [[ENTRY]] ]
-; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[IV_NEXT:%.*]], [[LATCH]] ]
+; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ]
; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[ARG2]], [[ENTRY]] ], [ [[ADD9:%.*]], [[LATCH]] ]
-; CHECK-NEXT: [[TMP5:%.*]] = shl i64 [[INDVAR]], 2
-; CHECK-NEXT: [[TMP6:%.*]] = add i64 [[TMP4]], [[TMP5]]
+; CHECK-NEXT: [[TMP0:%.*]] = shl i64 [[IV]], 2
+; CHECK-NEXT: [[LOOP_IDIOM_IV:%.*]] = getelementptr i8, ptr [[P]], i64 [[TMP0]]
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[LOOP_IDIOM_IV]], i8 0, i64 0, i1 false)
; CHECK-NEXT: br label [[LOOP2:%.*]]
; CHECK: loop2:
@@ -36,8 +29,6 @@ define void @test(ptr %p, i8 %arg, i64 %arg1, i32 %arg2) {
; CHECK-NEXT: [[ADD11:%.*]] = add i64 [[ADD]], [[SEXT10]]
; CHECK-NEXT: [[ADD12:%.*]] = add i64 [[ADD11]], [[SEXT]]
; CHECK-NEXT: [[IV_NEXT]] = add i64 [[ADD12]], [[IV]]
-; CHECK-NEXT: [[INDVAR_NEXT]] = add i64 [[INDVAR]], 1
-; CHECK-NEXT: [[SCEVGEP]] = getelementptr i8, ptr [[LOOP_IDIOM_IV]], i64 [[TMP6]]
; CHECK-NEXT: br label [[LOOP]]
;
entry:
diff --git a/llvm/test/Transforms/LoopSimplifyCFG/invalidate-scev-dispositions.ll b/llvm/test/Transforms/LoopSimplifyCFG/invalidate-scev-dispositions.ll
index efb2765a854a06..9f459caab7cd47 100644
--- a/llvm/test/Transforms/LoopSimplifyCFG/invalidate-scev-dispositions.ll
+++ b/llvm/test/Transforms/LoopSimplifyCFG/invalidate-scev-dispositions.ll
@@ -72,7 +72,7 @@ define void @test_remove_instrs_in_exit_block() {
; INDVARS-NEXT: [[IV_NEXT]] = add nuw nsw i16 [[IV]], 1
; INDVARS-NEXT: br label [[INNER]]
; INDVARS: outer.latch:
-; INDVARS-NEXT: [[OUTER_IV_NEXT]] = add nuw nsw i16 [[OUTER_IV]], 1
+; INDVARS-NEXT: [[OUTER_IV_NEXT]] = add nsw i16 [[OUTER_IV]], 1
; INDVARS-NEXT: [[CMP_2:%.*]] = icmp eq i16 poison, [[OUTER_IV]]
; INDVARS-NEXT: br i1 [[CMP_2]], label [[OUTER_HEADER]], label [[EXIT:%.*]]
; INDVARS: exit:
diff --git a/llvm/test/Transforms/LoopStrengthReduce/AMDGPU/lsr-invalid-ptr-extend.ll b/llvm/test/Transforms/LoopStrengthReduce/AMDGPU/lsr-invalid-ptr-extend.ll
index 8111eeb6ec71d5..abe8246a7e7e84 100644
--- a/llvm/test/Transforms/LoopStrengthReduce/AMDGPU/lsr-invalid-ptr-extend.ll
+++ b/llvm/test/Transforms/LoopStrengthReduce/AMDGPU/lsr-invalid-ptr-extend.ll
@@ -16,22 +16,24 @@ define amdgpu_kernel void @scaledregtest() local_unnamed_addr {
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
; CHECK: loopexit:
-; CHECK-NEXT: [[SCEVGEP11_LCSSA:%.*]] = phi ptr addrspace(5) [ [[SCEVGEP11:%.*]], [[FOR_BODY]] ]
-; CHECK-NEXT: [[SCEVGEP13_LCSSA:%.*]] = phi ptr [ [[SCEVGEP13:%.*]], [[FOR_BODY]] ]
+; CHECK-NEXT: [[LSR_IV_NEXT4_LCSSA:%.*]] = phi i32 [ [[LSR_IV_NEXT4:%.*]], [[FOR_BODY]] ]
+; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[LSR_IV_NEXT4_LCSSA]], -1
+; CHECK-NEXT: [[CONV:%.*]] = zext i32 [[TMP1]] to i64
; CHECK-NEXT: br label [[FOR_BODY_1:%.*]]
; CHECK: for.body.1:
-; CHECK-NEXT: [[LSR_IV5:%.*]] = phi ptr addrspace(5) [ [[SCEVGEP6:%.*]], [[FOR_BODY_1]] ], [ [[SCEVGEP11_LCSSA]], [[LOOPEXIT:%.*]] ]
-; CHECK-NEXT: [[LSR_IV1:%.*]] = phi ptr [ [[SCEVGEP2:%.*]], [[FOR_BODY_1]] ], [ [[SCEVGEP13_LCSSA]], [[LOOPEXIT]] ]
+; CHECK-NEXT: [[LSR_IV2:%.*]] = phi i32 [ [[LSR_IV_NEXT2:%.*]], [[FOR_BODY_1]] ], [ [[LSR_IV_NEXT4_LCSSA]], [[LOOPEXIT:%.*]] ]
+; CHECK-NEXT: [[CONV_1:%.*]] = phi i64 [ [[CONV_2:%.*]], [[FOR_BODY_1]] ], [ [[CONV]], [[LOOPEXIT]] ]
+; CHECK-NEXT: [[IDXPROM:%.*]] = trunc i64 [[CONV_1]] to i32
+; CHECK-NEXT: [[LSR_IV5:%.*]] = getelementptr inbounds ptr, ptr addrspace(5) null, i32 [[IDXPROM]]
; CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr addrspace(5) [[LSR_IV5]], align 8
+; CHECK-NEXT: [[LSR_IV1:%.*]] = getelementptr inbounds ptr, ptr null, i64 [[CONV_1]]
; CHECK-NEXT: store ptr [[TMP0]], ptr [[LSR_IV1]], align 8
-; CHECK-NEXT: [[SCEVGEP2]] = getelementptr i8, ptr [[LSR_IV1]], i64 8
-; CHECK-NEXT: [[SCEVGEP6]] = getelementptr i8, ptr addrspace(5) [[LSR_IV5]], i32 8
+; CHECK-NEXT: [[CONV_2]] = zext i32 [[LSR_IV2]] to i64
+; CHECK-NEXT: [[LSR_IV_NEXT2]] = add i32 [[LSR_IV2]], 1
; CHECK-NEXT: br label [[FOR_BODY_1]]
; CHECK: for.body:
-; CHECK-NEXT: [[LSR_IV12:%.*]] = phi ptr [ [[SCEVGEP13]], [[FOR_BODY]] ], [ null, [[ENTRY:%.*]] ]
-; CHECK-NEXT: [[LSR_IV10:%.*]] = phi ptr addrspace(5) [ [[SCEVGEP11]], [[FOR_BODY]] ], [ null, [[ENTRY]] ]
-; CHECK-NEXT: [[SCEVGEP11]] = getelementptr i8, ptr addrspace(5) [[LSR_IV10]], i32 64
-; CHECK-NEXT: [[SCEVGEP13]] = getelementptr i8, ptr [[LSR_IV12]], i64 64
+; CHECK-NEXT: [[LSR_IV3:%.*]] = phi i32 [ [[LSR_IV_NEXT4]], [[FOR_BODY]] ], [ 1, [[ENTRY:%.*]] ]
+; CHECK-NEXT: [[LSR_IV_NEXT4]] = add i32 [[LSR_IV3]], 8
; CHECK-NEXT: br i1 false, label [[LOOPEXIT]], label [[FOR_BODY]]
;
entry:
@@ -62,7 +64,7 @@ for.body:
define protected amdgpu_kernel void @baseregtest(i32 %n, i32 %lda, i1 %arg) local_unnamed_addr {
; CHECK-LABEL: @baseregtest(
; CHECK-NEXT: entry:
-; CHECK-NEXT: br i1 %arg, label [[EXIT:%.*]], label [[IF_END:%.*]]
+; CHECK-NEXT: br i1 [[ARG:%.*]], label [[EXIT:%.*]], label [[IF_END:%.*]]
; CHECK: if.end:
; CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @foo()
; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[TMP0]], 3
diff --git a/llvm/test/Transforms/LoopStrengthReduce/X86/sibling-loops.ll b/llvm/test/Transforms/LoopStrengthReduce/X86/sibling-loops.ll
index 11c8ae61b30641..3e80bb9744f843 100644
--- a/llvm/test/Transforms/LoopStrengthReduce/X86/sibling-loops.ll
+++ b/llvm/test/Transforms/LoopStrengthReduce/X86/sibling-loops.ll
@@ -17,7 +17,7 @@ define void @foo(i64 %N) local_unnamed_addr {
; CHECK: do.body:
; CHECK-NEXT: [[I_0:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[DO_BODY]] ]
; CHECK-NEXT: tail call void @goo(i64 [[I_0]], i64 [[I_0]])
-; CHECK-NEXT: [[INC]] = add nuw i64 [[I_0]], 1
+; CHECK-NEXT: [[INC]] = add i64 [[I_0]], 1
; CHECK-NEXT: [[T0:%.*]] = load i64, ptr @cond, align 8
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i64 [[T0]], 0
; CHECK-NEXT: br i1 [[TOBOOL]], label [[DO_BODY2_PREHEADER:%.*]], label [[DO_BODY]]
@@ -27,7 +27,7 @@ define void @foo(i64 %N) local_unnamed_addr {
; CHECK-NEXT: [[I_1:%.*]] = phi i64 [ [[INC3:%.*]], [[DO_BODY2]] ], [ 0, [[DO_BODY2_PREHEADER]] ]
; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INC]], [[I_1]]
; CHECK-NEXT: tail call void @goo(i64 [[I_1]], i64 [[TMP0]])
-; CHECK-NEXT: [[INC3]] = add nuw i64 [[I_1]], 1
+; CHECK-NEXT: [[INC3]] = add i64 [[I_1]], 1
; CHECK-NEXT: [[T1:%.*]] = load i64, ptr @cond, align 8
; CHECK-NEXT: [[TOBOOL6:%.*]] = icmp eq i64 [[T1]], 0
; CHECK-NEXT: br i1 [[TOBOOL6]], label [[DO_BODY8_PREHEADER:%.*]], label [[DO_BODY2]]
diff --git a/llvm/test/Transforms/LoopUnroll/runtime-exit-phi-scev-invalidation.ll b/llvm/test/Transforms/LoopUnroll/runtime-exit-phi-scev-invalidation.ll
index a97b39494b2ef8..be44e6d5bd3d5d 100644
--- a/llvm/test/Transforms/LoopUnroll/runtime-exit-phi-scev-invalidation.ll
+++ b/llvm/test/Transforms/LoopUnroll/runtime-exit-phi-scev-invalidation.ll
@@ -96,7 +96,7 @@ define void @pr56282() {
; CHECK: inner.2.preheader:
; CHECK-NEXT: br label [[INNER_2]]
; CHECK: inner.2:
-; CHECK-NEXT: [[OUTER_IV_NEXT]] = add nuw i64 [[OUTER_IV]], 1
+; CHECK-NEXT: [[OUTER_IV_NEXT]] = add i64 [[OUTER_IV]], 1
; CHECK-NEXT: br label [[OUTER_HEADER]]
; CHECK: exit:
; CHECK-NEXT: ret void
diff --git a/llvm/test/Transforms/LoopUnroll/wrong_assert_in_peeling.ll b/llvm/test/Transforms/LoopUnroll/wrong_assert_in_peeling.ll
index 32f8baeb8d69fb..37b77ca5c44b9f 100644
--- a/llvm/test/Transforms/LoopUnroll/wrong_assert_in_peeling.ll
+++ b/llvm/test/Transforms/LoopUnroll/wrong_assert_in_peeling.ll
@@ -9,58 +9,29 @@ define i32 @test() {
; CHECK-NEXT: br label [[BB1:%.*]]
; CHECK: bb1:
; CHECK-NEXT: [[TMP:%.*]] = phi i32 [ -147, [[BB:%.*]] ], [ [[TMP14:%.*]], [[BB13:%.*]] ]
-; CHECK-NEXT: br label [[BB2_PEEL_BEGIN:%.*]]
-; CHECK: bb2.peel.begin:
-; CHECK-NEXT: br label [[BB2_PEEL:%.*]]
-; CHECK: bb2.peel:
-; CHECK-NEXT: [[TMP4_PEEL:%.*]] = add nsw i32 undef, [[TMP]]
-; CHECK-NEXT: br label [[BB5_PEEL:%.*]]
-; CHECK: bb5.peel:
-; CHECK-NEXT: [[TMP6_PEEL:%.*]] = icmp eq i32 undef, 33
-; CHECK-NEXT: br i1 [[TMP6_PEEL]], label [[BB7_PEEL:%.*]], label [[BB15_LOOPEXIT2:%.*]]
-; CHECK: bb7.peel:
-; CHECK-NEXT: [[TMP8_PEEL:%.*]] = sub nsw i32 undef, undef
-; CHECK-NEXT: [[TMP9_PEEL:%.*]] = icmp eq i32 [[TMP8_PEEL]], 0
-; CHECK-NEXT: br i1 [[TMP9_PEEL]], label [[BB10_PEEL:%.*]], label [[BB10_PEEL]]
-; CHECK: bb10.peel:
-; CHECK-NEXT: [[TMP11_PEEL:%.*]] = icmp eq i8 undef, 0
-; CHECK-NEXT: br i1 [[TMP11_PEEL]], label [[BB12_PEEL:%.*]], label [[BB17_LOOPEXIT3:%.*]]
-; CHECK: bb12.peel:
-; CHECK-NEXT: br i1 false, label [[BB13]], label [[BB2_PEEL_NEXT:%.*]]
-; CHECK: bb2.peel.next:
-; CHECK-NEXT: br label [[BB2_PEEL_NEXT1:%.*]]
-; CHECK: bb2.peel.next1:
-; CHECK-NEXT: br label [[BB1_PEEL_NEWPH:%.*]]
-; CHECK: bb1.peel.newph:
; CHECK-NEXT: br label [[BB2:%.*]]
; CHECK: bb2:
-; CHECK-NEXT: [[TMP3:%.*]] = phi i32 [ [[TMP4_PEEL]], [[BB1_PEEL_NEWPH]] ], [ [[TMP4:%.*]], [[BB12:%.*]] ]
+; CHECK-NEXT: [[TMP3:%.*]] = phi i32 [ undef, [[BB1]] ], [ [[TMP4:%.*]], [[BB12:%.*]] ]
; CHECK-NEXT: [[TMP4]] = add nsw i32 [[TMP3]], [[TMP]]
; CHECK-NEXT: br label [[BB5:%.*]]
; CHECK: bb5:
-; CHECK-NEXT: br i1 undef, label [[BB7:%.*]], label [[BB15_LOOPEXIT:%.*]]
+; CHECK-NEXT: [[TMP6:%.*]] = icmp eq i32 undef, 33
+; CHECK-NEXT: br i1 [[TMP6]], label [[BB7:%.*]], label [[BB15:%.*]]
; CHECK: bb7:
-; CHECK-NEXT: br i1 undef, label [[BB10:%.*]], label [[BB10]]
+; CHECK-NEXT: [[TMP8:%.*]] = sub nsw i32 [[TMP3]], undef
+; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 0
+; CHECK-NEXT: br i1 [[TMP9]], label [[BB10:%.*]], label [[BB10]]
; CHECK: bb10:
-; CHECK-NEXT: br i1 undef, label [[BB12]], label [[BB17_LOOPEXIT:%.*]]
+; CHECK-NEXT: [[TMP11:%.*]] = icmp eq i8 undef, 0
+; CHECK-NEXT: br i1 [[TMP11]], label [[BB12]], label [[BB17:%.*]]
; CHECK: bb12:
-; CHECK-NEXT: br i1 false, label [[BB13_LOOPEXIT:%.*]], label [[BB2]], !llvm.loop [[LOOP0:![0-9]+]]
-; CHECK: bb13.loopexit:
-; CHECK-NEXT: br label [[BB13]]
+; CHECK-NEXT: br i1 false, label [[BB13]], label [[BB2]]
; CHECK: bb13:
; CHECK-NEXT: [[TMP14]] = add nsw i32 [[TMP]], -1
; CHECK-NEXT: br label [[BB1]]
-; CHECK: bb15.loopexit:
-; CHECK-NEXT: br label [[BB15:%.*]]
-; CHECK: bb15.loopexit2:
-; CHECK-NEXT: br label [[BB15]]
; CHECK: bb15:
; CHECK-NEXT: [[TMP16:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 17) [ "deopt"() ]
; CHECK-NEXT: ret i32 [[TMP16]]
-; CHECK: bb17.loopexit:
-; CHECK-NEXT: br label [[BB17:%.*]]
-; CHECK: bb17.loopexit3:
-; CHECK-NEXT: br label [[BB17]]
; CHECK: bb17:
; CHECK-NEXT: [[TMP18:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 6) [ "deopt"() ]
; CHECK-NEXT: ret i32 [[TMP18]]
More information about the llvm-commits
mailing list