[llvm] [IndVars] Use context for proving same sign (PR #181093)

Max Kazantsev via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 12 00:55:55 PST 2026


https://github.com/xortator updated https://github.com/llvm/llvm-project/pull/181093

>From d3e23fcb70233550f2fdee4a28924142584ee684 Mon Sep 17 00:00:00 2001
From: Max Kazantsev <xortator at yandex.ru>
Date: Thu, 12 Feb 2026 09:27:06 +0300
Subject: [PATCH 1/2] [Test] Add motivating test on signed/unsigned comparison
 inference

These tests demonstrate that IndVars sometimes cannot turn a signed comparison
into an equivalent unsigned counterpart due to lack of contextual info.
---
 .../samesign-signed-comparison.ll             | 209 ++++++++++++++++++
 1 file changed, 209 insertions(+)
 create mode 100644 llvm/test/Transforms/IndVarSimplify/samesign-signed-comparison.ll

diff --git a/llvm/test/Transforms/IndVarSimplify/samesign-signed-comparison.ll b/llvm/test/Transforms/IndVarSimplify/samesign-signed-comparison.ll
new file mode 100644
index 0000000000000..b4f9aab897964
--- /dev/null
+++ b/llvm/test/Transforms/IndVarSimplify/samesign-signed-comparison.ll
@@ -0,0 +1,209 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -passes=indvars -S < %s | FileCheck %s
+
+; Make sure that IV starting from zero turns to unsigned.
+define i32 @test_01(i32 %start, i32 %end, ptr %p) {
+; CHECK-LABEL: define i32 @test_01(
+; CHECK-SAME: i32 [[START:%.*]], i32 [[END:%.*]], ptr [[P:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br label %[[LOOP:.*]]
+; CHECK:       [[LOOP]]:
+; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[BACKEDGE:.*]] ]
+; CHECK-NEXT:    br i1 true, label %[[CHECKED:.*]], label %[[BAD:.*]]
+; CHECK:       [[CHECKED]]:
+; CHECK-NEXT:    [[LEN:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG0:![0-9]+]], !invariant.load [[META1:![0-9]+]], !noundef [[META1]]
+; CHECK-NEXT:    [[CMP_S:%.*]] = icmp samesign ult i32 [[I]], [[LEN]]
+; CHECK-NEXT:    br i1 [[CMP_S]], label %[[BACKEDGE]], label %[[BAD]]
+; CHECK:       [[BACKEDGE]]:
+; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[I]], 1
+; CHECK-NEXT:    [[LOOP_COND:%.*]] = call i1 @cond()
+; CHECK-NEXT:    br i1 [[LOOP_COND]], label %[[LOOP]], label %[[GOOD:.*]]
+; CHECK:       [[GOOD]]:
+; CHECK-NEXT:    ret i32 42
+; CHECK:       [[BAD]]:
+; CHECK-NEXT:    ret i32 -1
+;
+entry:
+  br label %loop
+
+loop:
+  %i = phi i32 [0, %entry], [%iv.next, %backedge]
+  %cond_i = icmp sge i32 %i, 0
+  br i1 %cond_i, label %checked, label %bad
+
+checked:
+  %len = load i32, ptr %p, align 4, !invariant.load !0, !noundef !0, !range !1
+  %cmp_s = icmp slt i32 %i, %len
+  br i1 %cmp_s, label %backedge, label %bad
+
+backedge:
+  %iv.next = add i32 %i, 1
+  %loop_cond = call i1 @cond()
+  br i1 %loop_cond, label %loop, label %good
+
+good:
+  ret i32 42
+
+bad:
+  ret i32 -1
+}
+
+; Make sure that IV starting from zero turns to unsigned even if comparison is a part of AND.
+define i32 @test_02(i32 %start, i32 %end, ptr %p) {
+; CHECK-LABEL: define i32 @test_02(
+; CHECK-SAME: i32 [[START:%.*]], i32 [[END:%.*]], ptr [[P:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br label %[[LOOP:.*]]
+; CHECK:       [[LOOP]]:
+; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[BACKEDGE:.*]] ]
+; CHECK-NEXT:    br i1 true, label %[[CHECKED:.*]], label %[[BAD:.*]]
+; CHECK:       [[CHECKED]]:
+; CHECK-NEXT:    [[LEN:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG0]], !invariant.load [[META1]], !noundef [[META1]]
+; CHECK-NEXT:    [[CMP_S:%.*]] = icmp samesign ult i32 [[I]], [[LEN]]
+; CHECK-NEXT:    [[CMP_U:%.*]] = icmp samesign ult i32 [[I]], [[LEN]]
+; CHECK-NEXT:    [[CMP_BOTH:%.*]] = and i1 [[CMP_S]], [[CMP_U]]
+; CHECK-NEXT:    br i1 [[CMP_BOTH]], label %[[BACKEDGE]], label %[[BAD]]
+; CHECK:       [[BACKEDGE]]:
+; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[I]], 1
+; CHECK-NEXT:    [[LOOP_COND:%.*]] = call i1 @cond()
+; CHECK-NEXT:    br i1 [[LOOP_COND]], label %[[LOOP]], label %[[GOOD:.*]]
+; CHECK:       [[GOOD]]:
+; CHECK-NEXT:    ret i32 42
+; CHECK:       [[BAD]]:
+; CHECK-NEXT:    ret i32 -1
+;
+entry:
+  br label %loop
+
+loop:
+  %i = phi i32 [0, %entry], [%iv.next, %backedge]
+  %cond_i = icmp sge i32 %i, 0
+  br i1 %cond_i, label %checked, label %bad
+
+checked:
+  %len = load i32, ptr %p, align 4, !invariant.load !0, !noundef !0, !range !1
+  %cmp_s = icmp slt i32 %i, %len
+  %cmp_u = icmp ult i32 %i, %len
+  %cmp_both = and i1 %cmp_s, %cmp_u
+  br i1 %cmp_both, label %backedge, label %bad
+
+backedge:
+  %iv.next = add i32 %i, 1
+  %loop_cond = call i1 @cond()
+  br i1 %loop_cond, label %loop, label %good
+
+good:
+  ret i32 42
+
+bad:
+  ret i32 -1
+}
+
+; TODO: i is known non-negative from dominating condition. Turn comparison to unsigned.
+define i32 @test_03(i32 %start, i32 %end, ptr %p) {
+; CHECK-LABEL: define i32 @test_03(
+; CHECK-SAME: i32 [[START:%.*]], i32 [[END:%.*]], ptr [[P:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br label %[[LOOP:.*]]
+; CHECK:       [[LOOP]]:
+; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[START]], %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[BACKEDGE:.*]] ]
+; CHECK-NEXT:    [[COND_I:%.*]] = icmp sge i32 [[I]], 0
+; CHECK-NEXT:    br i1 [[COND_I]], label %[[CHECKED:.*]], label %[[BAD:.*]]
+; CHECK:       [[CHECKED]]:
+; CHECK-NEXT:    [[LEN:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG0]], !invariant.load [[META1]], !noundef [[META1]]
+; CHECK-NEXT:    [[CMP_S:%.*]] = icmp slt i32 [[I]], [[LEN]]
+; CHECK-NEXT:    br i1 [[CMP_S]], label %[[BACKEDGE]], label %[[BAD]]
+; CHECK:       [[BACKEDGE]]:
+; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[I]], 1
+; CHECK-NEXT:    [[LOOP_COND:%.*]] = call i1 @cond()
+; CHECK-NEXT:    br i1 [[LOOP_COND]], label %[[LOOP]], label %[[GOOD:.*]]
+; CHECK:       [[GOOD]]:
+; CHECK-NEXT:    ret i32 42
+; CHECK:       [[BAD]]:
+; CHECK-NEXT:    ret i32 -1
+;
+entry:
+  br label %loop
+
+loop:
+  %i = phi i32 [%start, %entry], [%iv.next, %backedge]
+  %cond_i = icmp sge i32 %i, 0
+  br i1 %cond_i, label %checked, label %bad
+
+checked:
+  %len = load i32, ptr %p, align 4, !invariant.load !0, !noundef !0, !range !1
+  %cmp_s = icmp slt i32 %i, %len
+  br i1 %cmp_s, label %backedge, label %bad
+
+backedge:
+  %iv.next = add i32 %i, 1
+  %loop_cond = call i1 @cond()
+  br i1 %loop_cond, label %loop, label %good
+
+good:
+  ret i32 42
+
+bad:
+  ret i32 -1
+}
+
+; TODO: i is known non-negative from dominating condition. Turn comparison to unsigned even if it's a part of AND.
+define i32 @test_04(i32 %start, i32 %end, ptr %p) {
+; CHECK-LABEL: define i32 @test_04(
+; CHECK-SAME: i32 [[START:%.*]], i32 [[END:%.*]], ptr [[P:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br label %[[LOOP:.*]]
+; CHECK:       [[LOOP]]:
+; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[START]], %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[BACKEDGE:.*]] ]
+; CHECK-NEXT:    [[COND_I:%.*]] = icmp sge i32 [[I]], 0
+; CHECK-NEXT:    br i1 [[COND_I]], label %[[CHECKED:.*]], label %[[BAD:.*]]
+; CHECK:       [[CHECKED]]:
+; CHECK-NEXT:    [[LEN:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG0]], !invariant.load [[META1]], !noundef [[META1]]
+; CHECK-NEXT:    [[CMP_U:%.*]] = icmp slt i32 [[I]], [[LEN]]
+; CHECK-NEXT:    [[CMP_U1:%.*]] = icmp ult i32 [[I]], [[LEN]]
+; CHECK-NEXT:    [[CMP_BOTH:%.*]] = and i1 [[CMP_U]], [[CMP_U1]]
+; CHECK-NEXT:    br i1 [[CMP_BOTH]], label %[[BACKEDGE]], label %[[BAD]]
+; CHECK:       [[BACKEDGE]]:
+; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[I]], 1
+; CHECK-NEXT:    [[LOOP_COND:%.*]] = call i1 @cond()
+; CHECK-NEXT:    br i1 [[LOOP_COND]], label %[[LOOP]], label %[[GOOD:.*]]
+; CHECK:       [[GOOD]]:
+; CHECK-NEXT:    ret i32 42
+; CHECK:       [[BAD]]:
+; CHECK-NEXT:    ret i32 -1
+;
+entry:
+  br label %loop
+
+loop:
+  %i = phi i32 [%start, %entry], [%iv.next, %backedge]
+  %cond_i = icmp sge i32 %i, 0
+  br i1 %cond_i, label %checked, label %bad
+
+checked:
+  %len = load i32, ptr %p, align 4, !invariant.load !0, !noundef !0, !range !1
+  %cmp_s = icmp slt i32 %i, %len
+  %cmp_u = icmp ult i32 %i, %len
+  %cmp_both = and i1 %cmp_s, %cmp_u
+  br i1 %cmp_both, label %backedge, label %bad
+
+backedge:
+  %iv.next = add i32 %i, 1
+  %loop_cond = call i1 @cond()
+  br i1 %loop_cond, label %loop, label %good
+
+good:
+  ret i32 42
+
+bad:
+  ret i32 -1
+}
+
+!0 = !{}
+!1 = !{i32 0, i32 10000}
+
+declare i1 @cond() readonly
+;.
+; CHECK: [[RNG0]] = !{i32 0, i32 10000}
+; CHECK: [[META1]] = !{}
+;.

>From 2c4b4c15e0e3f86faba95400410c9d73004b35f9 Mon Sep 17 00:00:00 2001
From: Max Kazantsev <xortator at yandex.ru>
Date: Thu, 12 Feb 2026 09:49:09 +0300
Subject: [PATCH 2/2] [IndVars] Use context for proving same sign

IndVars already uses context to prove other facts around this place.
This patch takes its advantage to prove same sign of comparison
operands and infer unsigned predicate/samesign flag.
---
 llvm/include/llvm/Analysis/ScalarEvolution.h  |  5 ++++
 llvm/lib/Analysis/ScalarEvolution.cpp         | 14 +++++++++++
 llvm/lib/Transforms/Utils/SimplifyIndVar.cpp  |  2 +-
 .../IndVarSimplify/AArch64/widen-loop-comp.ll |  2 +-
 .../IndVarSimplify/canonicalize-cmp.ll        |  4 ++--
 .../IndVarSimplify/eliminate-comparison.ll    |  6 +++--
 .../IndVarSimplify/eliminate-exit.ll          |  2 +-
 .../eliminate-overflow-modified.ll            | 23 ++++++++++++++-----
 llvm/test/Transforms/IndVarSimplify/guards.ll |  4 ++--
 .../Transforms/IndVarSimplify/lftr-promote.ll |  2 +-
 .../IndVarSimplify/lrev-existing-umin.ll      |  2 +-
 .../promote-iv-to-eliminate-casts.ll          | 10 ++++----
 .../IndVarSimplify/rewrite-loop-exit-value.ll |  4 ++--
 .../samesign-signed-comparison.ll             | 10 ++++----
 .../Transforms/LoopSimplify/merge-exits.ll    |  4 ++--
 .../Transforms/LoopUnroll/peel-loop-inner.ll  |  2 +-
 .../peel-loop-min-max-intrinsics.ll           |  4 ++--
 .../Transforms/LoopUnroll/peel-loop-nests.ll  | 14 +++++------
 llvm/test/Transforms/LoopUnroll/peel-loop.ll  |  4 ++--
 .../PhaseOrdering/AArch64/interleave_vec.ll   |  2 +-
 .../PhaseOrdering/branch-dom-cond.ll          |  2 +-
 .../PhaseOrdering/loop-access-checks.ll       |  2 +-
 22 files changed, 77 insertions(+), 47 deletions(-)

diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h
index 6aff53a1e7b70..4a5d53008abfd 100644
--- a/llvm/include/llvm/Analysis/ScalarEvolution.h
+++ b/llvm/include/llvm/Analysis/ScalarEvolution.h
@@ -1091,6 +1091,11 @@ class ScalarEvolution {
   /// Return true if we know that S1 and S2 must have the same sign.
   LLVM_ABI bool haveSameSign(const SCEV *S1, const SCEV *S2);
 
+  /// Return true if we know that \p S1 and \p S2 must have the same sign in the
+  /// context of \p CtxI.
+  LLVM_ABI bool haveSameSignAt(const SCEV *S1, const SCEV *S2,
+                               const Instruction *CtxI);
+
   /// Splits SCEV expression \p S into two SCEVs. One of them is obtained from
   /// \p S by substitution of all AddRec sub-expression related to loop \p L
   /// with initial value of that SCEV. The second is obtained from \p S by
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 45f1b543b8fc7..75fd0e8568189 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -11185,6 +11185,20 @@ bool ScalarEvolution::haveSameSign(const SCEV *S1, const SCEV *S2) {
           (isKnownNegative(S1) && isKnownNegative(S2)));
 }
 
+bool ScalarEvolution::haveSameSignAt(const SCEV *S1, const SCEV *S2,
+                                     const Instruction *CtxI) {
+  auto IsKnownNonNegative = [this, CtxI](const SCEV *S) {
+    return isKnownPredicateAt(ICmpInst::ICMP_SGE, S, getZero(S->getType()),
+                              CtxI);
+  };
+  auto IsKnownNegative = [this, CtxI](const SCEV *S) {
+    return isKnownPredicateAt(ICmpInst::ICMP_SLT, S, getZero(S->getType()),
+                              CtxI);
+  };
+  return ((IsKnownNonNegative(S1) && IsKnownNonNegative(S2)) ||
+          (IsKnownNegative(S1) && IsKnownNegative(S2)));
+}
+
 std::pair<const SCEV *, const SCEV *>
 ScalarEvolution::SplitIntoInitAndPostInc(const Loop *L, const SCEV *S) {
   // Compute SCEV on entry of loop L.
diff --git a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
index 792c1ac31c2ba..fc60886d0615a 100644
--- a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
@@ -290,7 +290,7 @@ void SimplifyIndvar::eliminateIVComparison(ICmpInst *ICmp,
 
   if ((ICmpInst::isSigned(OriginalPred) ||
        (ICmpInst::isUnsigned(OriginalPred) && !ICmp->hasSameSign())) &&
-      SE->haveSameSign(S, X)) {
+      SE->haveSameSignAt(S, X, CtxI)) {
     // Set the samesign flag on the compare if legal, and canonicalize to
     // the unsigned variant (for signed compares) hoping that it will open
     // the doors for other optimizations.  Note that we cannot rely on Pred
diff --git a/llvm/test/Transforms/IndVarSimplify/AArch64/widen-loop-comp.ll b/llvm/test/Transforms/IndVarSimplify/AArch64/widen-loop-comp.ll
index d4498baf0577a..5ec21859745a1 100644
--- a/llvm/test/Transforms/IndVarSimplify/AArch64/widen-loop-comp.ll
+++ b/llvm/test/Transforms/IndVarSimplify/AArch64/widen-loop-comp.ll
@@ -405,7 +405,7 @@ define i32 @test8(ptr %a, i32 %b, i32 %init) {
 ; CHECK:       for.cond:
 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_COND_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ]
 ; CHECK-NEXT:    [[SUM_0:%.*]] = phi i32 [ [[ADD:%.*]], [[FOR_BODY]] ], [ 0, [[FOR_COND_PREHEADER]] ]
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i64 [[INDVARS_IV]], [[TMP1]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ule i64 [[INDVARS_IV]], [[TMP1]]
 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
 ; CHECK:       for.body:
 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
diff --git a/llvm/test/Transforms/IndVarSimplify/canonicalize-cmp.ll b/llvm/test/Transforms/IndVarSimplify/canonicalize-cmp.ll
index 6ac09fafcb7a4..d9114a5e31c7d 100644
--- a/llvm/test/Transforms/IndVarSimplify/canonicalize-cmp.ll
+++ b/llvm/test/Transforms/IndVarSimplify/canonicalize-cmp.ll
@@ -151,7 +151,7 @@ define i32 @test_03(ptr %p, ptr %capacity_p, ptr %num_elements_p) {
 ; CHECK:       loop:
 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
 ; CHECK-NEXT:    [[BYTES_TO_WRITE:%.*]] = sub nuw nsw i32 [[CAPACITY]], [[IV]]
-; CHECK-NEXT:    [[CAPACITY_CHECK:%.*]] = icmp slt i32 [[BYTES_TO_WRITE]], 4
+; CHECK-NEXT:    [[CAPACITY_CHECK:%.*]] = icmp samesign ult i32 [[BYTES_TO_WRITE]], 4
 ; CHECK-NEXT:    br i1 [[CAPACITY_CHECK]], label [[OUT_OF_BOUNDS:%.*]], label [[BACKEDGE]]
 ; CHECK:       backedge:
 ; CHECK-NEXT:    [[EL_PTR:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 [[IV]]
@@ -199,7 +199,7 @@ define i32 @test_04(ptr %p, ptr %capacity_p, ptr %num_elements_p) {
 ; CHECK:       loop:
 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
 ; CHECK-NEXT:    [[BYTES_TO_WRITE:%.*]] = sub nuw nsw i32 [[CAPACITY]], [[IV]]
-; CHECK-NEXT:    [[CAPACITY_CHECK:%.*]] = icmp sle i32 [[BYTES_TO_WRITE]], 3
+; CHECK-NEXT:    [[CAPACITY_CHECK:%.*]] = icmp samesign ule i32 [[BYTES_TO_WRITE]], 3
 ; CHECK-NEXT:    br i1 [[CAPACITY_CHECK]], label [[OUT_OF_BOUNDS:%.*]], label [[BACKEDGE]]
 ; CHECK:       backedge:
 ; CHECK-NEXT:    [[EL_PTR:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 [[IV]]
diff --git a/llvm/test/Transforms/IndVarSimplify/eliminate-comparison.ll b/llvm/test/Transforms/IndVarSimplify/eliminate-comparison.ll
index 08f9856ac603d..31f01c0eb3a9d 100644
--- a/llvm/test/Transforms/IndVarSimplify/eliminate-comparison.ll
+++ b/llvm/test/Transforms/IndVarSimplify/eliminate-comparison.ll
@@ -827,11 +827,13 @@ define void @func_22(ptr %length.ptr) {
 ; CHECK-NEXT:    [[ENTRY_COND:%.*]] = icmp sgt i32 [[LENGTH]], 1
 ; CHECK-NEXT:    br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[LEAVE:%.*]]
 ; CHECK:       loop.preheader:
+; CHECK-NEXT:    [[TMP0:%.*]] = add nuw nsw i32 [[LENGTH]], 1
 ; CHECK-NEXT:    br label [[LOOP:%.*]]
 ; CHECK:       loop:
 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[IV_INC:%.*]], [[BE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
 ; CHECK-NEXT:    [[IV_INC]] = add nuw nsw i32 [[IV]], 1
-; CHECK-NEXT:    br i1 true, label [[BE]], label [[LEAVE_LOOPEXIT:%.*]]
+; CHECK-NEXT:    [[EXITCOND1:%.*]] = icmp ne i32 [[IV]], [[TMP0]]
+; CHECK-NEXT:    br i1 [[EXITCOND1]], label [[BE]], label [[LEAVE_LOOPEXIT:%.*]]
 ; CHECK:       be:
 ; CHECK-NEXT:    call void @side_effect()
 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i32 [[IV_INC]], [[LENGTH]]
@@ -917,7 +919,7 @@ define void @func_24(ptr %init.ptr) {
 ; CHECK-NEXT:    br i1 true, label [[BE]], label [[LEAVE_LOOPEXIT:%.*]]
 ; CHECK:       be:
 ; CHECK-NEXT:    call void @side_effect()
-; CHECK-NEXT:    [[BE_COND:%.*]] = icmp sgt i32 [[IV_DEC]], 4
+; CHECK-NEXT:    [[BE_COND:%.*]] = icmp samesign ugt i32 [[IV_DEC]], 4
 ; CHECK-NEXT:    br i1 [[BE_COND]], label [[LOOP]], label [[LEAVE_LOOPEXIT]]
 ; CHECK:       leave.loopexit:
 ; CHECK-NEXT:    br label [[LEAVE]]
diff --git a/llvm/test/Transforms/IndVarSimplify/eliminate-exit.ll b/llvm/test/Transforms/IndVarSimplify/eliminate-exit.ll
index b20891d2f9ed8..b3cbee8475344 100644
--- a/llvm/test/Transforms/IndVarSimplify/eliminate-exit.ll
+++ b/llvm/test/Transforms/IndVarSimplify/eliminate-exit.ll
@@ -161,7 +161,7 @@ define void @ult_const_max(i64 %n) {
 ; CHECK-NEXT:    br i1 true, label [[LATCH]], label [[EXIT_LOOPEXIT:%.*]]
 ; CHECK:       latch:
 ; CHECK-NEXT:    call void @side_effect()
-; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i64 [[IV]], [[N]]
+; CHECK-NEXT:    [[CMP2:%.*]] = icmp samesign ult i64 [[IV]], [[N]]
 ; CHECK-NEXT:    br i1 [[CMP2]], label [[LOOP]], label [[EXIT_LOOPEXIT]]
 ; CHECK:       exit.loopexit:
 ; CHECK-NEXT:    br label [[EXIT]]
diff --git a/llvm/test/Transforms/IndVarSimplify/eliminate-overflow-modified.ll b/llvm/test/Transforms/IndVarSimplify/eliminate-overflow-modified.ll
index b91c1aeaa7128..f1896ba72006e 100644
--- a/llvm/test/Transforms/IndVarSimplify/eliminate-overflow-modified.ll
+++ b/llvm/test/Transforms/IndVarSimplify/eliminate-overflow-modified.ll
@@ -1,17 +1,28 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
 ; RUN: opt < %s -passes=indvars -S -o - | FileCheck %s
 
 ; When eliminating the overflow intrinsic the indvars pass would incorrectly
 ; return a false Modified status. This was caught by the pass return
 ; status check that is hidden under EXPENSIVE_CHECKS.
 
-; CHECK-LABEL: for.body:
-; CHECK-NEXT: %0 = phi i16 [ %1, %for.body ], [ undef, %for.body.preheader ]
-; CHECK-NEXT: %1 = add nsw i16 %0, -1
-; CHECK-NEXT: %cmp = icmp sgt i16 %1, 0
-; CHECK-NEXT:  call void @llvm.assume(i1 %cmp)
-
 ; Function Attrs: nounwind
 define void @foo() #0 {
+; CHECK-LABEL: define void @foo(
+; CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i16 undef, 0
+; CHECK-NEXT:    br i1 [[CMP1]], label %[[FOR_BODY_PREHEADER:.*]], label %[[FOR_END:.*]]
+; CHECK:       [[FOR_BODY_PREHEADER]]:
+; CHECK-NEXT:    br label %[[FOR_BODY:.*]]
+; CHECK:       [[FOR_BODY]]:
+; CHECK-NEXT:    [[TMP0:%.*]] = phi i16 [ [[TMP1:%.*]], %[[FOR_BODY]] ], [ undef, %[[FOR_BODY_PREHEADER]] ]
+; CHECK-NEXT:    [[TMP1]] = add nsw i16 [[TMP0]], -1
+; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i16 [[TMP1]], 0
+; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
+; CHECK-NEXT:    br label %[[FOR_BODY]]
+; CHECK:       [[FOR_END]]:
+; CHECK-NEXT:    ret void
+;
 entry:
   %cmp1 = icmp sgt i16 undef, 0
   br i1 %cmp1, label %for.body.preheader, label %for.end
diff --git a/llvm/test/Transforms/IndVarSimplify/guards.ll b/llvm/test/Transforms/IndVarSimplify/guards.ll
index 431b4b189ca60..07726cb75bb6d 100644
--- a/llvm/test/Transforms/IndVarSimplify/guards.ll
+++ b/llvm/test/Transforms/IndVarSimplify/guards.ll
@@ -106,7 +106,7 @@ define void @test_3(ptr %cond_buf, ptr %len_buf) {
 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_INC:%.*]], [[LOOP]] ]
 ; CHECK-NEXT:    [[IV_INC]] = add nsw i32 [[IV]], 1
 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 true) [ "deopt"() ]
-; CHECK-NEXT:    [[IV_INC_CMP:%.*]] = icmp slt i32 [[IV_INC]], [[LEN]]
+; CHECK-NEXT:    [[IV_INC_CMP:%.*]] = icmp samesign ult i32 [[IV_INC]], [[LEN]]
 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[IV_INC_CMP]]) [ "deopt"() ]
 ; CHECK-NEXT:    [[BECOND:%.*]] = load volatile i1, ptr [[COND_BUF]], align 1
 ; CHECK-NEXT:    br i1 [[BECOND]], label [[LOOP]], label [[LEAVE:%.*]]
@@ -155,7 +155,7 @@ define void @test_4(ptr %cond_buf, ptr %len_buf) {
 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[IV_INC_CMP]]) [ "deopt"() ]
 ; CHECK-NEXT:    br label [[BE]]
 ; CHECK:       be:
-; CHECK-NEXT:    [[IV_CMP:%.*]] = icmp slt i32 [[IV]], [[LEN]]
+; CHECK-NEXT:    [[IV_CMP:%.*]] = icmp samesign ult i32 [[IV]], [[LEN]]
 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[IV_CMP]]) [ "deopt"() ]
 ; CHECK-NEXT:    [[BECOND:%.*]] = load volatile i1, ptr [[COND_BUF]], align 1
 ; CHECK-NEXT:    br i1 [[BECOND]], label [[LOOP]], label [[LEAVE:%.*]]
diff --git a/llvm/test/Transforms/IndVarSimplify/lftr-promote.ll b/llvm/test/Transforms/IndVarSimplify/lftr-promote.ll
index 037662db9baca..418c6c5578554 100644
--- a/llvm/test/Transforms/IndVarSimplify/lftr-promote.ll
+++ b/llvm/test/Transforms/IndVarSimplify/lftr-promote.ll
@@ -26,7 +26,7 @@ define void @foo(ptr %p, i32 %n) nounwind {
 ; CHECK-NEXT:    [[TMP7]] = add nuw nsw i32 [[I_01]], 1
 ; CHECK-NEXT:    br label [[BB3]]
 ; CHECK:       bb3:
-; CHECK-NEXT:    [[TMP8:%.*]] = icmp slt i32 [[TMP7]], [[N]]
+; CHECK-NEXT:    [[TMP8:%.*]] = icmp samesign ult i32 [[TMP7]], [[N]]
 ; CHECK-NEXT:    br i1 [[TMP8]], label [[BB2]], label [[BB3_RETURN_CRIT_EDGE:%.*]]
 ; CHECK:       bb3.return_crit_edge:
 ; CHECK-NEXT:    br label [[RETURN]]
diff --git a/llvm/test/Transforms/IndVarSimplify/lrev-existing-umin.ll b/llvm/test/Transforms/IndVarSimplify/lrev-existing-umin.ll
index 305ecb9ffe756..cf0abf6ca736d 100644
--- a/llvm/test/Transforms/IndVarSimplify/lrev-existing-umin.ll
+++ b/llvm/test/Transforms/IndVarSimplify/lrev-existing-umin.ll
@@ -23,7 +23,7 @@ define void @f(i32 %length.i.88, i32 %length.i, ptr %tmp12, i32 %tmp10, ptr %tmp
 ; CHECK-NEXT:    [[ADDR22:%.*]] = getelementptr inbounds i8, ptr [[TMP12:%.*]], i64 [[TMP16]]
 ; CHECK-NEXT:    store i8 [[TMP21]], ptr [[ADDR22]], align 1
 ; CHECK-NEXT:    [[TMP22]] = add nuw nsw i32 [[V_1]], 1
-; CHECK-NEXT:    [[TMP23:%.*]] = icmp slt i32 [[TMP22]], [[TMP14]]
+; CHECK-NEXT:    [[TMP23:%.*]] = icmp samesign ult i32 [[TMP22]], [[TMP14]]
 ; CHECK-NEXT:    br i1 [[TMP23]], label [[NOT_ZERO11]], label [[MAIN_EXIT_SELECTOR:%.*]]
 ; CHECK:       main.exit.selector:
 ; CHECK-NEXT:    [[TMP22_LCSSA:%.*]] = phi i32 [ [[TMP22]], [[NOT_ZERO11]] ]
diff --git a/llvm/test/Transforms/IndVarSimplify/promote-iv-to-eliminate-casts.ll b/llvm/test/Transforms/IndVarSimplify/promote-iv-to-eliminate-casts.ll
index 3f0ada281b1e3..f67e2670adaf6 100644
--- a/llvm/test/Transforms/IndVarSimplify/promote-iv-to-eliminate-casts.ll
+++ b/llvm/test/Transforms/IndVarSimplify/promote-iv-to-eliminate-casts.ll
@@ -196,8 +196,8 @@ define void @promote_latch_condition_decrementing_loop_01(ptr %p, ptr %a) {
 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ], [ [[TMP0]], [[PREHEADER]] ]
 ; CHECK-NEXT:    [[EL:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
 ; CHECK-NEXT:    store atomic i32 0, ptr [[EL]] unordered, align 4
+; CHECK-NEXT:    [[LOOPCOND:%.*]] = icmp samesign ult i64 [[INDVARS_IV]], 1
 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
-; CHECK-NEXT:    [[LOOPCOND:%.*]] = icmp slt i64 [[INDVARS_IV]], 1
 ; CHECK-NEXT:    br i1 [[LOOPCOND]], label [[LOOPEXIT_LOOPEXIT:%.*]], label [[LOOP]]
 ;
 
@@ -240,8 +240,8 @@ define void @promote_latch_condition_decrementing_loop_02(ptr %p, ptr %a) {
 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ], [ [[TMP0]], [[PREHEADER]] ]
 ; CHECK-NEXT:    [[EL:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
 ; CHECK-NEXT:    store atomic i32 0, ptr [[EL]] unordered, align 4
+; CHECK-NEXT:    [[LOOPCOND:%.*]] = icmp samesign ult i64 [[INDVARS_IV]], 1
 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
-; CHECK-NEXT:    [[LOOPCOND:%.*]] = icmp slt i64 [[INDVARS_IV]], 1
 ; CHECK-NEXT:    br i1 [[LOOPCOND]], label [[LOOPEXIT_LOOPEXIT:%.*]], label [[LOOP]]
 ;
 
@@ -284,8 +284,8 @@ define void @promote_latch_condition_decrementing_loop_03(ptr %p, ptr %a) {
 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ], [ [[TMP1]], [[PREHEADER]] ]
 ; CHECK-NEXT:    [[EL:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
 ; CHECK-NEXT:    store atomic i32 0, ptr [[EL]] unordered, align 4
+; CHECK-NEXT:    [[LOOPCOND:%.*]] = icmp samesign ult i64 [[INDVARS_IV]], 1
 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
-; CHECK-NEXT:    [[LOOPCOND:%.*]] = icmp slt i64 [[INDVARS_IV]], 1
 ; CHECK-NEXT:    br i1 [[LOOPCOND]], label [[LOOPEXIT_LOOPEXIT:%.*]], label [[LOOP]]
 ;
 
@@ -336,8 +336,8 @@ define void @promote_latch_condition_decrementing_loop_04(ptr %p, ptr %a, i1 %co
 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ], [ [[TMP0]], [[PREHEADER]] ]
 ; CHECK-NEXT:    [[EL:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
 ; CHECK-NEXT:    store atomic i32 0, ptr [[EL]] unordered, align 4
+; CHECK-NEXT:    [[LOOPCOND:%.*]] = icmp samesign ult i64 [[INDVARS_IV]], 1
 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
-; CHECK-NEXT:    [[LOOPCOND:%.*]] = icmp slt i64 [[INDVARS_IV]], 1
 ; CHECK-NEXT:    br i1 [[LOOPCOND]], label [[LOOPEXIT_LOOPEXIT:%.*]], label [[LOOP]]
 ;
 
@@ -398,8 +398,8 @@ define void @promote_latch_condition_decrementing_loop_05(ptr %p, ptr %a, i1 %co
 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[LOOP]] ], [ [[TMP0]], [[PREHEADER]] ]
 ; CHECK-NEXT:    [[EL:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
 ; CHECK-NEXT:    store atomic i32 0, ptr [[EL]] unordered, align 4
+; CHECK-NEXT:    [[LOOPCOND:%.*]] = icmp samesign ult i64 [[INDVARS_IV]], 1
 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
-; CHECK-NEXT:    [[LOOPCOND:%.*]] = icmp slt i64 [[INDVARS_IV]], 1
 ; CHECK-NEXT:    br i1 [[LOOPCOND]], label [[LOOPEXIT_LOOPEXIT:%.*]], label [[LOOP]]
 ;
 
diff --git a/llvm/test/Transforms/IndVarSimplify/rewrite-loop-exit-value.ll b/llvm/test/Transforms/IndVarSimplify/rewrite-loop-exit-value.ll
index fa47d06d859e9..43cbdaf2ed00b 100644
--- a/llvm/test/Transforms/IndVarSimplify/rewrite-loop-exit-value.ll
+++ b/llvm/test/Transforms/IndVarSimplify/rewrite-loop-exit-value.ll
@@ -214,7 +214,7 @@ define i32 @vscale_slt_with_vp_umin(ptr nocapture %A, i32 %n) mustprogress vscal
 ; CHECK-NEXT:    [[VF_CAPPED:%.*]] = call i32 @llvm.umin.i32(i32 [[VF]], i32 [[LEFT]])
 ; CHECK-NEXT:    store i32 [[VF_CAPPED]], ptr [[A:%.*]], align 4
 ; CHECK-NEXT:    [[ADD]] = add nuw nsw i32 [[I_05]], [[VF]]
-; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[ADD]], [[N]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ult i32 [[ADD]], [[N]]
 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
 ; CHECK:       for.end:
 ; CHECK-NEXT:    [[TMP0:%.*]] = add nsw i32 [[N]], -1
@@ -267,7 +267,7 @@ define i32 @vscale_slt_with_vp_umin2(ptr nocapture %A, i32 %n) mustprogress vsca
 ; CHECK-NEXT:    [[VF_CAPPED:%.*]] = call i32 @llvm.umin.i32(i32 [[VF]], i32 [[LEFT]])
 ; CHECK-NEXT:    store i32 [[VF_CAPPED]], ptr [[A:%.*]], align 4
 ; CHECK-NEXT:    [[ADD]] = add nuw nsw i32 [[I_05]], [[VF]]
-; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[ADD]], [[N]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ult i32 [[ADD]], [[N]]
 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END:%.*]]
 ; CHECK:       for.end:
 ; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[N]], -1
diff --git a/llvm/test/Transforms/IndVarSimplify/samesign-signed-comparison.ll b/llvm/test/Transforms/IndVarSimplify/samesign-signed-comparison.ll
index b4f9aab897964..be6d93907c103 100644
--- a/llvm/test/Transforms/IndVarSimplify/samesign-signed-comparison.ll
+++ b/llvm/test/Transforms/IndVarSimplify/samesign-signed-comparison.ll
@@ -99,7 +99,7 @@ bad:
   ret i32 -1
 }
 
-; TODO: i is known non-negative from dominating condition. Turn comparison to unsigned.
+; i is known non-negative from dominating condition. Turn comparison to unsigned.
 define i32 @test_03(i32 %start, i32 %end, ptr %p) {
 ; CHECK-LABEL: define i32 @test_03(
 ; CHECK-SAME: i32 [[START:%.*]], i32 [[END:%.*]], ptr [[P:%.*]]) {
@@ -111,7 +111,7 @@ define i32 @test_03(i32 %start, i32 %end, ptr %p) {
 ; CHECK-NEXT:    br i1 [[COND_I]], label %[[CHECKED:.*]], label %[[BAD:.*]]
 ; CHECK:       [[CHECKED]]:
 ; CHECK-NEXT:    [[LEN:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG0]], !invariant.load [[META1]], !noundef [[META1]]
-; CHECK-NEXT:    [[CMP_S:%.*]] = icmp slt i32 [[I]], [[LEN]]
+; CHECK-NEXT:    [[CMP_S:%.*]] = icmp samesign ult i32 [[I]], [[LEN]]
 ; CHECK-NEXT:    br i1 [[CMP_S]], label %[[BACKEDGE]], label %[[BAD]]
 ; CHECK:       [[BACKEDGE]]:
 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[I]], 1
@@ -147,7 +147,7 @@ bad:
   ret i32 -1
 }
 
-; TODO: i is known non-negative from dominating condition. Turn comparison to unsigned even if it's a part of AND.
+; i is known non-negative from dominating condition. Turn comparison to unsigned even if it's a part of AND.
 define i32 @test_04(i32 %start, i32 %end, ptr %p) {
 ; CHECK-LABEL: define i32 @test_04(
 ; CHECK-SAME: i32 [[START:%.*]], i32 [[END:%.*]], ptr [[P:%.*]]) {
@@ -159,8 +159,8 @@ define i32 @test_04(i32 %start, i32 %end, ptr %p) {
 ; CHECK-NEXT:    br i1 [[COND_I]], label %[[CHECKED:.*]], label %[[BAD:.*]]
 ; CHECK:       [[CHECKED]]:
 ; CHECK-NEXT:    [[LEN:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG0]], !invariant.load [[META1]], !noundef [[META1]]
-; CHECK-NEXT:    [[CMP_U:%.*]] = icmp slt i32 [[I]], [[LEN]]
-; CHECK-NEXT:    [[CMP_U1:%.*]] = icmp ult i32 [[I]], [[LEN]]
+; CHECK-NEXT:    [[CMP_U:%.*]] = icmp samesign ult i32 [[I]], [[LEN]]
+; CHECK-NEXT:    [[CMP_U1:%.*]] = icmp samesign ult i32 [[I]], [[LEN]]
 ; CHECK-NEXT:    [[CMP_BOTH:%.*]] = and i1 [[CMP_U]], [[CMP_U1]]
 ; CHECK-NEXT:    br i1 [[CMP_BOTH]], label %[[BACKEDGE]], label %[[BAD]]
 ; CHECK:       [[BACKEDGE]]:
diff --git a/llvm/test/Transforms/LoopSimplify/merge-exits.ll b/llvm/test/Transforms/LoopSimplify/merge-exits.ll
index 10e634fd47a1a..ce6a362a6fe8a 100644
--- a/llvm/test/Transforms/LoopSimplify/merge-exits.ll
+++ b/llvm/test/Transforms/LoopSimplify/merge-exits.ll
@@ -30,7 +30,7 @@ define float @test1(ptr %pTmp1, ptr %peakWeight, i32 %bandEdgeIndex) nounwind {
 ; CHECK-NEXT:    [[T8:%.*]] = load float, ptr [[T7]], align 4
 ; CHECK-NEXT:    [[T9]] = fadd float [[T8]], [[PEAKCOUNT_02]]
 ; CHECK-NEXT:    [[T10:%.*]] = fcmp olt float [[T4]], 2.500000e+00
-; CHECK-NEXT:    [[T12:%.*]] = icmp sgt i64 [[TMP0]], [[INDVARS_IV_NEXT]]
+; CHECK-NEXT:    [[T12:%.*]] = icmp samesign ugt i64 [[TMP0]], [[INDVARS_IV_NEXT]]
 ; CHECK-NEXT:    [[OR_COND:%.*]] = and i1 [[T10]], [[T12]]
 ; CHECK-NEXT:    br i1 [[OR_COND]], label [[BB]], label [[BB1_BB3_CRIT_EDGE:%.*]]
 ; CHECK:       bb1.bb3_crit_edge:
@@ -101,7 +101,7 @@ define float @merge_branches_profile_metadata(ptr %pTmp1, ptr %peakWeight, i32 %
 ; CHECK-NEXT:    [[T8:%.*]] = load float, ptr [[T7]], align 4
 ; CHECK-NEXT:    [[T9]] = fadd float [[T8]], [[PEAKCOUNT_02]]
 ; CHECK-NEXT:    [[T10:%.*]] = fcmp olt float [[T4]], 2.500000e+00
-; CHECK-NEXT:    [[T12:%.*]] = icmp sgt i64 [[TMP0]], [[INDVARS_IV_NEXT]]
+; CHECK-NEXT:    [[T12:%.*]] = icmp samesign ugt i64 [[TMP0]], [[INDVARS_IV_NEXT]]
 ; CHECK-NEXT:    [[OR_COND:%.*]] = and i1 [[T10]], [[T12]]
 ; CHECK-NEXT:    br i1 [[OR_COND]], label [[BB]], label [[BB1_BB3_CRIT_EDGE:%.*]], !prof [[PROF1:![0-9]+]]
 ; CHECK:       bb1.bb3_crit_edge:
diff --git a/llvm/test/Transforms/LoopUnroll/peel-loop-inner.ll b/llvm/test/Transforms/LoopUnroll/peel-loop-inner.ll
index fa39b77aae36a..503560125145b 100644
--- a/llvm/test/Transforms/LoopUnroll/peel-loop-inner.ll
+++ b/llvm/test/Transforms/LoopUnroll/peel-loop-inner.ll
@@ -15,7 +15,7 @@ define void @basic(i32 %K, i32 %N) {
 ; CHECK:       inner:
 ; CHECK-NEXT:    [[J:%.*]] = phi i32 [ [[J_INC:%.*]], [[INNER]] ], [ 3, [[INNER_PEEL2]] ]
 ; CHECK-NEXT:    [[J_INC]] = add nuw nsw i32 [[J]], 1
-; CHECK-NEXT:    [[CMP_INNER:%.*]] = icmp slt i32 [[J_INC]], [[K]]
+; CHECK-NEXT:    [[CMP_INNER:%.*]] = icmp samesign ult i32 [[J_INC]], [[K]]
 ; CHECK-NEXT:    br i1 [[CMP_INNER]], label [[INNER]], label [[OUTER_BACKEDGE]], !llvm.loop [[LOOP0:![0-9]+]]
 ; CHECK:       outer.backedge:
 ; CHECK-NEXT:    [[I_INC]] = add i32 [[I]], 1
diff --git a/llvm/test/Transforms/LoopUnroll/peel-loop-min-max-intrinsics.ll b/llvm/test/Transforms/LoopUnroll/peel-loop-min-max-intrinsics.ll
index c699450afb6e5..b5401573f6f15 100644
--- a/llvm/test/Transforms/LoopUnroll/peel-loop-min-max-intrinsics.ll
+++ b/llvm/test/Transforms/LoopUnroll/peel-loop-min-max-intrinsics.ll
@@ -156,7 +156,7 @@ define void @test_smax(i32 %N) {
 ; CHECK-NEXT:    [[I_06:%.*]] = phi i32 [ [[DEC:%.*]], [[FOR_BODY]] ], [ [[DEC_PEEL4]], [[FOR_BODY_PREHEADER_PEEL_NEWPH]] ]
 ; CHECK-NEXT:    tail call void @foo(i32 -2)
 ; CHECK-NEXT:    [[DEC]] = add nsw i32 [[I_06]], -1
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[DEC]], [[N]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[DEC]], [[N]]
 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP3:![0-9]+]]
 ; CHECK:       for.cond.cleanup.loopexit.loopexit:
 ; CHECK-NEXT:    br label [[FOR_COND_CLEANUP_LOOPEXIT]]
@@ -215,7 +215,7 @@ define void @test_smin(i32 %N) {
 ; CHECK-NEXT:    [[I_06:%.*]] = phi i32 [ [[DEC:%.*]], [[FOR_BODY]] ], [ [[DEC_PEEL4]], [[FOR_BODY_PREHEADER_PEEL_NEWPH]] ]
 ; CHECK-NEXT:    tail call void @foo(i32 noundef signext [[I_06]])
 ; CHECK-NEXT:    [[DEC]] = add nsw i32 [[I_06]], -1
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[DEC]], [[N]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[DEC]], [[N]]
 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP_LOOPEXIT_LOOPEXIT:%.*]], !llvm.loop [[LOOP4:![0-9]+]]
 ; CHECK:       for.cond.cleanup.loopexit.loopexit:
 ; CHECK-NEXT:    br label [[FOR_COND_CLEANUP_LOOPEXIT]]
diff --git a/llvm/test/Transforms/LoopUnroll/peel-loop-nests.ll b/llvm/test/Transforms/LoopUnroll/peel-loop-nests.ll
index 8ef3ed3c2618b..c760e1eb961ab 100644
--- a/llvm/test/Transforms/LoopUnroll/peel-loop-nests.ll
+++ b/llvm/test/Transforms/LoopUnroll/peel-loop-nests.ll
@@ -32,7 +32,7 @@ define void @test1(i32 %k) {
 ; CHECK:       outer.inc:
 ; CHECK-NEXT:    [[J_INC]] = add nsw i32 [[J]], 1
 ; CHECK-NEXT:    [[OUTER_CMP:%.*]] = icmp slt i32 [[J_INC]], [[K]]
-; CHECK-NEXT:    br i1 [[OUTER_CMP]], label [[OUTER_HEADER]], label [[FOR_END:%.*]], !llvm.loop !{{.*}}
+; CHECK-NEXT:    br i1 [[OUTER_CMP]], label [[OUTER_HEADER]], label [[FOR_END:%.*]], !llvm.loop [[LOOP0:![0-9]+]]
 ; CHECK:       for.end:
 ; CHECK-NEXT:    ret void
 ;
@@ -60,9 +60,7 @@ define void @test1(i32 %k) {
 ; PEELED:       outer.inc.peel:
 ; PEELED-NEXT:    [[J_INC_PEEL:%.*]] = add nsw i32 0, 1
 ; PEELED-NEXT:    [[OUTER_CMP_PEEL:%.*]] = icmp slt i32 [[J_INC_PEEL]], [[K]]
-; PEELED-NEXT:    br i1 [[OUTER_CMP_PEEL]], label [[OUTER_HEADER_PEEL_NEXT:%.*]], label [[FOR_END:%[^,]*]]
-; Verify that MD_loop metadata is dropped.
-; PEELED-NOT:   , !llvm.loop !{{[0-9]*}}
+; PEELED-NEXT:    br i1 [[OUTER_CMP_PEEL]], label [[OUTER_HEADER_PEEL_NEXT:%.*]], label [[FOR_END:%.*]]
 ; PEELED:       outer.header.peel.next:
 ; PEELED-NEXT:    br label [[OUTER_HEADER_PEEL2:%.*]]
 ; PEELED:       outer.header.peel2:
@@ -85,8 +83,6 @@ define void @test1(i32 %k) {
 ; PEELED-NEXT:    [[J_INC_PEEL12:%.*]] = add nsw i32 [[J_INC_PEEL]], 1
 ; PEELED-NEXT:    [[OUTER_CMP_PEEL13:%.*]] = icmp slt i32 [[J_INC_PEEL12]], [[K]]
 ; PEELED-NEXT:    br i1 [[OUTER_CMP_PEEL13]], label [[OUTER_HEADER_PEEL_NEXT1:%.*]], label [[FOR_END]]
-; Verify that MD_loop metadata is dropped.
-; PEELED-NOT:   , !llvm.loop !{{[0-9]*}}
 ; PEELED:       outer.header.peel.next1:
 ; PEELED-NEXT:    br label [[OUTER_HEADER_PEEL_NEXT14:%.*]]
 ; PEELED:       outer.header.peel.next14:
@@ -111,13 +107,15 @@ define void @test1(i32 %k) {
 ; PEELED-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[OUTER_INC]]
 ; PEELED:       outer.inc:
 ; PEELED-NEXT:    [[J_INC]] = add nuw nsw i32 [[J]], 1
-; PEELED-NEXT:    [[OUTER_CMP:%.*]] = icmp slt i32 [[J_INC]], [[K]]
-; PEELED-NEXT:    br i1 [[OUTER_CMP]], label [[OUTER_HEADER]], label [[FOR_END_LOOPEXIT:%.*]], !llvm.loop !{{.*}}
+; PEELED-NEXT:    [[OUTER_CMP:%.*]] = icmp samesign ult i32 [[J_INC]], [[K]]
+; PEELED-NEXT:    br i1 [[OUTER_CMP]], label [[OUTER_HEADER]], label [[FOR_END_LOOPEXIT:%.*]], !llvm.loop [[LOOP0:![0-9]+]]
 ; PEELED:       for.end.loopexit:
 ; PEELED-NEXT:    br label [[FOR_END]]
 ; PEELED:       for.end:
 ; PEELED-NEXT:    ret void
 ;
+; Verify that MD_loop metadata is dropped.
+; Verify that MD_loop metadata is dropped.
 for.body.lr.ph:
   br label %outer.header
 
diff --git a/llvm/test/Transforms/LoopUnroll/peel-loop.ll b/llvm/test/Transforms/LoopUnroll/peel-loop.ll
index 80b9bdd89f542..c790a0ee9fbcd 100644
--- a/llvm/test/Transforms/LoopUnroll/peel-loop.ll
+++ b/llvm/test/Transforms/LoopUnroll/peel-loop.ll
@@ -32,7 +32,7 @@ define void @basic(ptr %p, i32 %k) #0 {
 ; CHECK-NEXT:    [[INCDEC_PTR]] = getelementptr inbounds nuw i8, ptr [[P_ADDR_04]], i64 4
 ; CHECK-NEXT:    store i32 [[I_05]], ptr [[P_ADDR_04]], align 4
 ; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_05]], 1
-; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], [[K]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ult i32 [[INC]], [[K]]
 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END]], !llvm.loop [[LOOP0:![0-9]+]]
 ; CHECK:       for.end:
 ; CHECK-NEXT:    ret void
@@ -92,7 +92,7 @@ define i32 @output(ptr %p, i32 %k) #0 {
 ; CHECK-NEXT:    [[INCDEC_PTR]] = getelementptr inbounds nuw i8, ptr [[P_ADDR_04]], i64 4
 ; CHECK-NEXT:    store i32 [[I_05]], ptr [[P_ADDR_04]], align 4
 ; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_05]], 1
-; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], [[K]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ult i32 [[INC]], [[K]]
 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_END]], !llvm.loop [[LOOP3:![0-9]+]]
 ; CHECK:       for.end:
 ; CHECK-NEXT:    [[RET:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 3, [[FOR_BODY_PEEL7]] ], [ 1, [[FOR_BODY_PEEL]] ], [ 2, [[FOR_BODY_PEEL2]] ], [ [[INC]], [[FOR_BODY]] ]
diff --git a/llvm/test/Transforms/PhaseOrdering/AArch64/interleave_vec.ll b/llvm/test/Transforms/PhaseOrdering/AArch64/interleave_vec.ll
index 2dceb27165c4d..b2fb5a834e005 100644
--- a/llvm/test/Transforms/PhaseOrdering/AArch64/interleave_vec.ll
+++ b/llvm/test/Transforms/PhaseOrdering/AArch64/interleave_vec.ll
@@ -1083,7 +1083,7 @@ define void @saxpy_5(i64 %n, float %a, ptr readonly %x, ptr noalias %y) {
 ; CHECK-NEXT:    [[AXPY5:%.*]] = fadd fast float [[Y5]], [[AX5]]
 ; CHECK-NEXT:    store float [[AXPY5]], ptr [[YGEP5]], align 4
 ; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i64 [[I1]], 5
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i64 [[N]], [[I_NEXT]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i64 [[N]], [[I_NEXT]]
 ; CHECK-NEXT:    br i1 [[CMP]], label %[[LOOP]], label %[[EXIT]], !llvm.loop [[LOOP10:![0-9]+]]
 ; CHECK:       [[EXIT]]:
 ; CHECK-NEXT:    ret void
diff --git a/llvm/test/Transforms/PhaseOrdering/branch-dom-cond.ll b/llvm/test/Transforms/PhaseOrdering/branch-dom-cond.ll
index 904ea6c2d9e73..a2fa7ec87438a 100644
--- a/llvm/test/Transforms/PhaseOrdering/branch-dom-cond.ll
+++ b/llvm/test/Transforms/PhaseOrdering/branch-dom-cond.ll
@@ -12,7 +12,7 @@ define void @growTables(ptr %p) {
 ; CHECK-NEXT:    [[I_02:%.*]] = phi i32 [ [[INC:%.*]], %[[FOR_BODY]] ], [ 0, %[[ENTRY]] ]
 ; CHECK-NEXT:    [[CALL9:%.*]] = load volatile ptr, ptr [[P]], align 8
 ; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_02]], 1
-; CHECK-NEXT:    [[CMP7:%.*]] = icmp slt i32 [[INC]], [[CALL]]
+; CHECK-NEXT:    [[CMP7:%.*]] = icmp samesign ult i32 [[INC]], [[CALL]]
 ; CHECK-NEXT:    br i1 [[CMP7]], label %[[FOR_BODY]], label %[[FOR_BODY12:.*]]
 ; CHECK:       [[FOR_BODY12]]:
 ; CHECK-NEXT:    [[CALL14:%.*]] = load volatile ptr, ptr [[P]], align 8
diff --git a/llvm/test/Transforms/PhaseOrdering/loop-access-checks.ll b/llvm/test/Transforms/PhaseOrdering/loop-access-checks.ll
index 5253c42d9c6d2..d3ad1d82d6147 100644
--- a/llvm/test/Transforms/PhaseOrdering/loop-access-checks.ll
+++ b/llvm/test/Transforms/PhaseOrdering/loop-access-checks.ll
@@ -291,7 +291,7 @@ define void @loop_with_signed_induction(ptr noundef nonnull align 8 dereferencea
 ; CHECK-NEXT:    [[ADD:%.*]] = fadd double [[TMP2]], 1.000000e+00
 ; CHECK-NEXT:    store double [[ADD]], ptr [[ADD_PTR_I]], align 8, !tbaa [[DOUBLE_TBAA6]]
 ; CHECK-NEXT:    [[INC]] = add nuw nsw i64 [[I_010]], 1
-; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i64 [[INC]], [[SUB_PTR_DIV_I_I]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ult i64 [[INC]], [[SUB_PTR_DIV_I_I]]
 ; CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY]], label %[[FOR_COND_CLEANUP]]
 ;
 entry:



More information about the llvm-commits mailing list