[llvm] [InstCombine] Fold comparisons of llvm.usub.sat result with its LHS (PR #214108)

Haram Jeong via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 10 01:44:45 PDT 2026


https://github.com/haramj updated https://github.com/llvm/llvm-project/pull/214108

>From 4f129d5bf7af0bca1be84885d40e83e46dbb0f9b Mon Sep 17 00:00:00 2001
From: haramjeong <04harams77 at gmail.com>
Date: Thu, 6 Aug 2026 13:54:12 +0900
Subject: [PATCH 1/3] [InstCombine] Add tests for usub.sat comparisons with its
 LHS

---
 .../Transforms/InstCombine/icmp-usub-sat.ll   | 87 +++++++++++++++++++
 1 file changed, 87 insertions(+)

diff --git a/llvm/test/Transforms/InstCombine/icmp-usub-sat.ll b/llvm/test/Transforms/InstCombine/icmp-usub-sat.ll
index 2cd07b17af580..1c0233aba2229 100644
--- a/llvm/test/Transforms/InstCombine/icmp-usub-sat.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-usub-sat.ll
@@ -425,6 +425,92 @@ define <2 x i1> @icmp_eq_vector_multiuse_negative_equal(<2 x i8> %arg) {
   ret <2 x i1> %cmp
 }
 
+define i1 @icmp_eq_lhs_nonzero_constant(i64 %x) {
+; CHECK-LABEL: define i1 @icmp_eq_lhs_nonzero_constant
+; CHECK-SAME: (i64 [[X:%.*]]) {
+; CHECK-NEXT:    [[SAT:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[X]], i64 10)
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[SAT]], [[X]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %sat = call i64 @llvm.usub.sat.i64(i64 %x, i64 10)
+  %cmp = icmp eq i64 %sat, %x
+  ret i1 %cmp
+}
+
+define i1 @icmp_eq_lhs_nonzero_constant_commuted(i64 %x) {
+; CHECK-LABEL: define i1 @icmp_eq_lhs_nonzero_constant_commuted
+; CHECK-SAME: (i64 [[X:%.*]]) {
+; CHECK-NEXT:    [[SAT:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[X]], i64 10)
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[X]], [[SAT]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %sat = call i64 @llvm.usub.sat.i64(i64 %x, i64 10)
+  %cmp = icmp eq i64 %x, %sat
+  ret i1 %cmp
+}
+
+define i1 @icmp_ult_lhs_nonzero_constant(i64 %x) {
+; CHECK-LABEL: define i1 @icmp_ult_lhs_nonzero_constant
+; CHECK-SAME: (i64 [[X:%.*]]) {
+; CHECK-NEXT:    [[SAT:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[X]], i64 10)
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[SAT]], [[X]]
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %sat = call i64 @llvm.usub.sat.i64(i64 %x, i64 10)
+  %cmp = icmp ult i64 %sat, %x
+  ret i1 %cmp
+}
+
+define i1 @icmp_eq_lhs_nonzero_constant_multiuse(i64 %x) {
+; CHECK-LABEL: define i1 @icmp_eq_lhs_nonzero_constant_multiuse
+; CHECK-SAME: (i64 [[X:%.*]]) {
+; CHECK-NEXT:    [[SAT:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[X]], i64 10)
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[SAT]], [[X]]
+; CHECK-NEXT:    call void @use.i64(i64 [[SAT]])
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %sat = call i64 @llvm.usub.sat.i64(i64 %x, i64 10)
+  %cmp = icmp eq i64 %sat, %x
+  call void @use.i64(i64 %sat)
+  ret i1 %cmp
+}
+
+define i1 @icmp_ult_lhs_nonzero_constant_multiuse(i64 %x) {
+; CHECK-LABEL: define i1 @icmp_ult_lhs_nonzero_constant_multiuse
+; CHECK-SAME: (i64 [[X:%.*]]) {
+; CHECK-NEXT:    [[SAT:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[X]], i64 10)
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[SAT]], [[X]]
+; CHECK-NEXT:    call void @use.i64(i64 [[SAT]])
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %sat = call i64 @llvm.usub.sat.i64(i64 %x, i64 10)
+  %cmp = icmp ult i64 %sat, %x
+  call void @use.i64(i64 %sat)
+  ret i1 %cmp
+}
+
+define i1 @icmp_eq_lhs_zero_constant(i64 %x) {
+; CHECK-LABEL: define i1 @icmp_eq_lhs_zero_constant
+; CHECK-SAME: (i64 [[X:%.*]]) {
+; CHECK-NEXT:    ret i1 true
+;
+  %sat = call i64 @llvm.usub.sat.i64(i64 %x, i64 0)
+  %cmp = icmp eq i64 %sat, %x
+  ret i1 %cmp
+}
+
+define <2 x i1> @icmp_ult_lhs_nonzero_constant_vector(<2 x i8> %x) {
+; CHECK-LABEL: define <2 x i1> @icmp_ult_lhs_nonzero_constant_vector
+; CHECK-SAME: (<2 x i8> [[X:%.*]]) {
+; CHECK-NEXT:    [[SAT:%.*]] = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> [[X]], <2 x i8> splat (i8 10))
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i8> [[SAT]], [[X]]
+; CHECK-NEXT:    ret <2 x i1> [[CMP]]
+;
+  %sat = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %x, <2 x i8> <i8 10, i8 10>)
+  %cmp = icmp ult <2 x i8> %sat, %x
+  ret <2 x i1> %cmp
+}
+
 declare i8 @llvm.usub.sat.i8(i8, i8)
 declare i16 @llvm.usub.sat.i16(i16, i16)
 declare i32 @llvm.usub.sat.i32(i32, i32)
@@ -437,3 +523,4 @@ declare <2 x i8> @llvm.usub.sat.v2i8(<2 x i8>, <2 x i8>)
 
 declare void @use.i8(i8)
 declare void @use.v2i8(<2 x i8>)
+declare void @use.i64(i64)

>From 9f67a96fa23fe31c6b41072bf03e93ad30775715 Mon Sep 17 00:00:00 2001
From: haramjeong <04harams77 at gmail.com>
Date: Thu, 6 Aug 2026 14:16:51 +0900
Subject: [PATCH 2/3] [InstCombine] Fold usub.sat comparisons with its LHS

---
 .../InstCombine/InstCombineCompares.cpp       | 19 ++++-
 .../Transforms/InstCombine/icmp-usub-sat.ll   | 83 +++++++++++++------
 2 files changed, 77 insertions(+), 25 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 70d584740f5b9..a62603ffc4b11 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -3952,7 +3952,6 @@ Instruction *InstCombinerImpl::foldICmpEqIntrinsicWithConstant(
   return nullptr;
 }
 
-/// Fold an icmp with LLVM intrinsics
 static Instruction *
 foldICmpIntrinsicWithIntrinsic(ICmpInst &Cmp,
                                InstCombiner::BuilderTy &Builder) {
@@ -7741,6 +7740,24 @@ Instruction *InstCombinerImpl::foldICmpCommutative(CmpPredicate Pred,
   }
 
   const SimplifyQuery Q = SQ.getWithInstruction(&CxtI);
+
+  {
+    Value *Y;
+    // For Y != 0:
+    // usub.sat(X, Y) == X  --> X == 0
+    // usub.sat(X, Y) != X  --> X != 0
+    // usub.sat(X, Y) <  X  --> X != 0
+    if (match(Op0, m_Intrinsic<Intrinsic::usub_sat>(m_Specific(Op1),
+                                                    m_Value(Y))) &&
+        (CmpInst::isEquality(Pred) || Pred == ICmpInst::ICMP_ULT) &&
+        isKnownNonZero(Y, Q)) {
+      ICmpInst::Predicate NewPred =
+          CmpInst::isEquality(Pred) ? Pred.dropSameSign() : ICmpInst::ICMP_NE;
+      return new ICmpInst(NewPred, Op1,
+                          Constant::getNullValue(Op1->getType()));
+    }
+  }
+
   if (Value *V = foldICmpWithLowBitMaskedVal(Pred, Op0, Op1, Q, *this))
     return replaceInstUsesWith(CxtI, V);
 
diff --git a/llvm/test/Transforms/InstCombine/icmp-usub-sat.ll b/llvm/test/Transforms/InstCombine/icmp-usub-sat.ll
index 1c0233aba2229..f612b192b43cb 100644
--- a/llvm/test/Transforms/InstCombine/icmp-usub-sat.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-usub-sat.ll
@@ -425,11 +425,10 @@ define <2 x i1> @icmp_eq_vector_multiuse_negative_equal(<2 x i8> %arg) {
   ret <2 x i1> %cmp
 }
 
-define i1 @icmp_eq_lhs_nonzero_constant(i64 %x) {
-; CHECK-LABEL: define i1 @icmp_eq_lhs_nonzero_constant
+define i1 @icmp_eq_usub_sat_lhs_nonzero_constant(i64 %x) {
+; CHECK-LABEL: define i1 @icmp_eq_usub_sat_lhs_nonzero_constant
 ; CHECK-SAME: (i64 [[X:%.*]]) {
-; CHECK-NEXT:    [[SAT:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[X]], i64 10)
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[SAT]], [[X]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[X]], 0
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %sat = call i64 @llvm.usub.sat.i64(i64 %x, i64 10)
@@ -437,11 +436,10 @@ define i1 @icmp_eq_lhs_nonzero_constant(i64 %x) {
   ret i1 %cmp
 }
 
-define i1 @icmp_eq_lhs_nonzero_constant_commuted(i64 %x) {
-; CHECK-LABEL: define i1 @icmp_eq_lhs_nonzero_constant_commuted
+define i1 @icmp_eq_usub_sat_lhs_nonzero_constant_commuted(i64 %x) {
+; CHECK-LABEL: define i1 @icmp_eq_usub_sat_lhs_nonzero_constant_commuted
 ; CHECK-SAME: (i64 [[X:%.*]]) {
-; CHECK-NEXT:    [[SAT:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[X]], i64 10)
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[X]], [[SAT]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[X]], 0
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %sat = call i64 @llvm.usub.sat.i64(i64 %x, i64 10)
@@ -449,11 +447,10 @@ define i1 @icmp_eq_lhs_nonzero_constant_commuted(i64 %x) {
   ret i1 %cmp
 }
 
-define i1 @icmp_ult_lhs_nonzero_constant(i64 %x) {
-; CHECK-LABEL: define i1 @icmp_ult_lhs_nonzero_constant
+define i1 @icmp_ult_usub_sat_lhs_nonzero_constant(i64 %x) {
+; CHECK-LABEL: define i1 @icmp_ult_usub_sat_lhs_nonzero_constant
 ; CHECK-SAME: (i64 [[X:%.*]]) {
-; CHECK-NEXT:    [[SAT:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[X]], i64 10)
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[SAT]], [[X]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i64 [[X]], 0
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %sat = call i64 @llvm.usub.sat.i64(i64 %x, i64 10)
@@ -461,11 +458,33 @@ define i1 @icmp_ult_lhs_nonzero_constant(i64 %x) {
   ret i1 %cmp
 }
 
-define i1 @icmp_eq_lhs_nonzero_constant_multiuse(i64 %x) {
-; CHECK-LABEL: define i1 @icmp_eq_lhs_nonzero_constant_multiuse
+define i1 @icmp_ne_usub_sat_lhs_nonzero_constant(i64 %x) {
+; CHECK-LABEL: define i1 @icmp_ne_usub_sat_lhs_nonzero_constant
+; CHECK-SAME: (i64 [[X:%.*]]) {
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i64 [[X]], 0
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %sat = call i64 @llvm.usub.sat.i64(i64 %x, i64 10)
+  %cmp = icmp ne i64 %sat, %x
+  ret i1 %cmp
+}
+
+define i1 @icmp_ugt_usub_sat_lhs_nonzero_constant(i64 %x) {
+; CHECK-LABEL: define i1 @icmp_ugt_usub_sat_lhs_nonzero_constant
+; CHECK-SAME: (i64 [[X:%.*]]) {
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i64 [[X]], 0
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %sat = call i64 @llvm.usub.sat.i64(i64 %x, i64 10)
+  %cmp = icmp ugt i64 %x, %sat
+  ret i1 %cmp
+}
+
+define i1 @icmp_eq_usub_sat_lhs_nonzero_constant_multiuse(i64 %x) {
+; CHECK-LABEL: define i1 @icmp_eq_usub_sat_lhs_nonzero_constant_multiuse
 ; CHECK-SAME: (i64 [[X:%.*]]) {
 ; CHECK-NEXT:    [[SAT:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[X]], i64 10)
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[SAT]], [[X]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[X]], 0
 ; CHECK-NEXT:    call void @use.i64(i64 [[SAT]])
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
@@ -475,11 +494,11 @@ define i1 @icmp_eq_lhs_nonzero_constant_multiuse(i64 %x) {
   ret i1 %cmp
 }
 
-define i1 @icmp_ult_lhs_nonzero_constant_multiuse(i64 %x) {
-; CHECK-LABEL: define i1 @icmp_ult_lhs_nonzero_constant_multiuse
+define i1 @icmp_ult_usub_sat_lhs_nonzero_constant_multiuse(i64 %x) {
+; CHECK-LABEL: define i1 @icmp_ult_usub_sat_lhs_nonzero_constant_multiuse
 ; CHECK-SAME: (i64 [[X:%.*]]) {
 ; CHECK-NEXT:    [[SAT:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[X]], i64 10)
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i64 [[SAT]], [[X]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i64 [[X]], 0
 ; CHECK-NEXT:    call void @use.i64(i64 [[SAT]])
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
@@ -489,8 +508,8 @@ define i1 @icmp_ult_lhs_nonzero_constant_multiuse(i64 %x) {
   ret i1 %cmp
 }
 
-define i1 @icmp_eq_lhs_zero_constant(i64 %x) {
-; CHECK-LABEL: define i1 @icmp_eq_lhs_zero_constant
+define i1 @icmp_eq_usub_sat_lhs_zero_constant(i64 %x) {
+; CHECK-LABEL: define i1 @icmp_eq_usub_sat_lhs_zero_constant
 ; CHECK-SAME: (i64 [[X:%.*]]) {
 ; CHECK-NEXT:    ret i1 true
 ;
@@ -499,11 +518,10 @@ define i1 @icmp_eq_lhs_zero_constant(i64 %x) {
   ret i1 %cmp
 }
 
-define <2 x i1> @icmp_ult_lhs_nonzero_constant_vector(<2 x i8> %x) {
-; CHECK-LABEL: define <2 x i1> @icmp_ult_lhs_nonzero_constant_vector
+define <2 x i1> @icmp_ult_usub_sat_lhs_nonzero_constant_vector(<2 x i8> %x) {
+; CHECK-LABEL: define <2 x i1> @icmp_ult_usub_sat_lhs_nonzero_constant_vector
 ; CHECK-SAME: (<2 x i8> [[X:%.*]]) {
-; CHECK-NEXT:    [[SAT:%.*]] = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> [[X]], <2 x i8> splat (i8 10))
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i8> [[SAT]], [[X]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i8> [[X]], zeroinitializer
 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
 ;
   %sat = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> %x, <2 x i8> <i8 10, i8 10>)
@@ -511,6 +529,21 @@ define <2 x i1> @icmp_ult_lhs_nonzero_constant_vector(<2 x i8> %x) {
   ret <2 x i1> %cmp
 }
 
+define i1 @icmp_eq_usub_sat_lhs_known_nonzero_rhs(i64 %x, i64 %y) {
+; CHECK-LABEL: define i1 @icmp_eq_usub_sat_lhs_known_nonzero_rhs
+; CHECK-SAME: (i64 [[X:%.*]], i64 [[Y:%.*]]) {
+; CHECK-NEXT:    [[COND:%.*]] = icmp ne i64 [[Y]], 0
+; CHECK-NEXT:    call void @llvm.assume(i1 [[COND]])
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[X]], 0
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %cond = icmp ne i64 %y, 0
+  call void @llvm.assume(i1 %cond)
+  %sat = call i64 @llvm.usub.sat.i64(i64 %x, i64 %y)
+  %cmp = icmp eq i64 %sat, %x
+  ret i1 %cmp
+}
+
 declare i8 @llvm.usub.sat.i8(i8, i8)
 declare i16 @llvm.usub.sat.i16(i16, i16)
 declare i32 @llvm.usub.sat.i32(i32, i32)
@@ -521,6 +554,8 @@ declare <2 x i32> @llvm.usub.sat.v2i32(<2 x i32>, <2 x i32>)
 declare <2 x i16> @llvm.usub.sat.v2i16(<2 x i16>, <2 x i16>)
 declare <2 x i8> @llvm.usub.sat.v2i8(<2 x i8>, <2 x i8>)
 
+declare void @llvm.assume(i1)
+
 declare void @use.i8(i8)
 declare void @use.v2i8(<2 x i8>)
 declare void @use.i64(i64)

>From 33d50aa8f7dce1f1843017aec653db6d8b707d2d Mon Sep 17 00:00:00 2001
From: haramjeong <04harams77 at gmail.com>
Date: Mon, 10 Aug 2026 17:44:23 +0900
Subject: [PATCH 3/3] [InstCombine] Limit usub.sat LHS comparison fold to
 constants

---
 .../Transforms/InstCombine/InstCombineCompares.cpp |  7 +++----
 llvm/test/Transforms/InstCombine/icmp-usub-sat.ll  | 14 +++++++++++++-
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index a62603ffc4b11..11aa1d936ec7a 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -3952,6 +3952,7 @@ Instruction *InstCombinerImpl::foldICmpEqIntrinsicWithConstant(
   return nullptr;
 }
 
+/// Fold an icmp with LLVM intrinsics
 static Instruction *
 foldICmpIntrinsicWithIntrinsic(ICmpInst &Cmp,
                                InstCombiner::BuilderTy &Builder) {
@@ -7742,15 +7743,13 @@ Instruction *InstCombinerImpl::foldICmpCommutative(CmpPredicate Pred,
   const SimplifyQuery Q = SQ.getWithInstruction(&CxtI);
 
   {
-    Value *Y;
     // For Y != 0:
     // usub.sat(X, Y) == X  --> X == 0
     // usub.sat(X, Y) != X  --> X != 0
     // usub.sat(X, Y) <  X  --> X != 0
     if (match(Op0, m_Intrinsic<Intrinsic::usub_sat>(m_Specific(Op1),
-                                                    m_Value(Y))) &&
-        (CmpInst::isEquality(Pred) || Pred == ICmpInst::ICMP_ULT) &&
-        isKnownNonZero(Y, Q)) {
+                                                    m_NonZeroInt())) &&
+        (CmpInst::isEquality(Pred) || Pred == ICmpInst::ICMP_ULT)) {
       ICmpInst::Predicate NewPred =
           CmpInst::isEquality(Pred) ? Pred.dropSameSign() : ICmpInst::ICMP_NE;
       return new ICmpInst(NewPred, Op1,
diff --git a/llvm/test/Transforms/InstCombine/icmp-usub-sat.ll b/llvm/test/Transforms/InstCombine/icmp-usub-sat.ll
index f612b192b43cb..b3d1971ad40e6 100644
--- a/llvm/test/Transforms/InstCombine/icmp-usub-sat.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-usub-sat.ll
@@ -447,6 +447,17 @@ define i1 @icmp_eq_usub_sat_lhs_nonzero_constant_commuted(i64 %x) {
   ret i1 %cmp
 }
 
+define i1 @icmp_samesign_eq_usub_sat_lhs_nonzero_constant(i64 %x) {
+; CHECK-LABEL: define i1 @icmp_samesign_eq_usub_sat_lhs_nonzero_constant
+; CHECK-SAME: (i64 [[X:%.*]]) {
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[X]], 0
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %sat = call i64 @llvm.usub.sat.i64(i64 %x, i64 10)
+  %cmp = icmp samesign eq i64 %sat, %x
+  ret i1 %cmp
+}
+
 define i1 @icmp_ult_usub_sat_lhs_nonzero_constant(i64 %x) {
 ; CHECK-LABEL: define i1 @icmp_ult_usub_sat_lhs_nonzero_constant
 ; CHECK-SAME: (i64 [[X:%.*]]) {
@@ -534,7 +545,8 @@ define i1 @icmp_eq_usub_sat_lhs_known_nonzero_rhs(i64 %x, i64 %y) {
 ; CHECK-SAME: (i64 [[X:%.*]], i64 [[Y:%.*]]) {
 ; CHECK-NEXT:    [[COND:%.*]] = icmp ne i64 [[Y]], 0
 ; CHECK-NEXT:    call void @llvm.assume(i1 [[COND]])
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[X]], 0
+; CHECK-NEXT:    [[SAT:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[X]], i64 [[Y]])
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[SAT]], [[X]]
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %cond = icmp ne i64 %y, 0



More information about the llvm-commits mailing list