From 9b205a1fe298fc2523dd1c8a5cbb91fdac84e02d Mon Sep 17 00:00:00 2001 From: AZero13 Date: Fri, 17 Oct 2025 15:00:42 -0400 Subject: [PATCH 1/2] Pre-commit test (NFC) --- .../sext-a-lt-b-plus-zext-a-gt-b-to-uscmp.ll | 190 ++++++++++++++++++ 1 file changed, 190 insertions(+) diff --git a/llvm/test/Transforms/InstCombine/sext-a-lt-b-plus-zext-a-gt-b-to-uscmp.ll b/llvm/test/Transforms/InstCombine/sext-a-lt-b-plus-zext-a-gt-b-to-uscmp.ll index 02ae7ce82f13c..53982601fb7d4 100644 --- a/llvm/test/Transforms/InstCombine/sext-a-lt-b-plus-zext-a-gt-b-to-uscmp.ll +++ b/llvm/test/Transforms/InstCombine/sext-a-lt-b-plus-zext-a-gt-b-to-uscmp.ll @@ -182,3 +182,193 @@ define i8 @signed_add_neg5(i32 %a, i32 %b) { %r = add i8 %lt8, %gt8 ret i8 %r } + +; sext(A s<= B) + zext(A s>= B) => scmp(A, B) +define i8 @signed_add_ge_le(i32 %a, i32 %b) { +; CHECK-LABEL: define i8 @signed_add_ge_le( +; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) { +; CHECK-NEXT: [[LE:%.*]] = icmp sle i32 [[A]], [[B]] +; CHECK-NEXT: [[LE8:%.*]] = sext i1 [[LE]] to i8 +; CHECK-NEXT: [[GE:%.*]] = icmp sge i32 [[A]], [[B]] +; CHECK-NEXT: [[GE8:%.*]] = zext i1 [[GE]] to i8 +; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[LE8]], [[GE8]] +; CHECK-NEXT: ret i8 [[R]] +; + %le = icmp sle i32 %a, %b + %le8 = sext i1 %le to i8 + %ge = icmp sge i32 %a, %b + %ge8 = zext i1 %ge to i8 + %r = add i8 %le8, %ge8 + ret i8 %r +} + +; Unsigned version of >= and <= +define i8 @unsigned_add_ge_le(i32 %a, i32 %b) { +; CHECK-LABEL: define i8 @unsigned_add_ge_le( +; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) { +; CHECK-NEXT: [[LE:%.*]] = icmp ule i32 [[A]], [[B]] +; CHECK-NEXT: [[LE8:%.*]] = sext i1 [[LE]] to i8 +; CHECK-NEXT: [[GE:%.*]] = icmp uge i32 [[A]], [[B]] +; CHECK-NEXT: [[GE8:%.*]] = zext i1 [[GE]] to i8 +; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[LE8]], [[GE8]] +; CHECK-NEXT: ret i8 [[R]] +; + %le = icmp ule i32 %a, %b + %le8 = sext i1 %le to i8 + %ge = icmp uge i32 %a, %b + %ge8 = zext i1 %ge to i8 + %r = add i8 %le8, %ge8 + ret i8 %r +} + +; zext(A s>= B) - zext(A s<= B) => scmp(A, B) +define i8 @signed_sub_ge_le(i32 %a, i32 %b) { +; CHECK-LABEL: define i8 @signed_sub_ge_le( +; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) { +; CHECK-NEXT: [[LE:%.*]] = icmp sle i32 [[A]], [[B]] +; CHECK-NEXT: [[LE8_NEG:%.*]] = sext i1 [[LE]] to i8 +; CHECK-NEXT: [[GE:%.*]] = icmp sge i32 [[A]], [[B]] +; CHECK-NEXT: [[GE8:%.*]] = zext i1 [[GE]] to i8 +; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[LE8_NEG]], [[GE8]] +; CHECK-NEXT: ret i8 [[R]] +; + %le = icmp sle i32 %a, %b + %le8 = zext i1 %le to i8 + %ge = icmp sge i32 %a, %b + %ge8 = zext i1 %ge to i8 + %r = sub i8 %ge8, %le8 + ret i8 %r +} + +; Unsigned version of >= and <= subtraction +define i8 @unsigned_sub_ge_le(i32 %a, i32 %b) { +; CHECK-LABEL: define i8 @unsigned_sub_ge_le( +; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) { +; CHECK-NEXT: [[LE:%.*]] = icmp ule i32 [[A]], [[B]] +; CHECK-NEXT: [[LE8_NEG:%.*]] = sext i1 [[LE]] to i8 +; CHECK-NEXT: [[GE:%.*]] = icmp uge i32 [[A]], [[B]] +; CHECK-NEXT: [[GE8:%.*]] = zext i1 [[GE]] to i8 +; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[LE8_NEG]], [[GE8]] +; CHECK-NEXT: ret i8 [[R]] +; + %le = icmp ule i32 %a, %b + %le8 = zext i1 %le to i8 + %ge = icmp uge i32 %a, %b + %ge8 = zext i1 %ge to i8 + %r = sub i8 %ge8, %le8 + ret i8 %r +} + +; Constant canonicalization: (a > 4) - (a < 6) => scmp(a, 5) +define i8 @signed_sub_const_canonicalization(i32 %a) { +; CHECK-LABEL: define i8 @signed_sub_const_canonicalization( +; CHECK-SAME: i32 [[A:%.*]]) { +; CHECK-NEXT: [[LT:%.*]] = icmp slt i32 [[A]], 6 +; CHECK-NEXT: [[LT8_NEG:%.*]] = sext i1 [[LT]] to i8 +; CHECK-NEXT: [[GT:%.*]] = icmp sgt i32 [[A]], 4 +; CHECK-NEXT: [[GT8:%.*]] = zext i1 [[GT]] to i8 +; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[LT8_NEG]], [[GT8]] +; CHECK-NEXT: ret i8 [[R]] +; + %lt = icmp slt i32 %a, 6 + %lt8 = zext i1 %lt to i8 + %gt = icmp sgt i32 %a, 4 + %gt8 = zext i1 %gt to i8 + %r = sub i8 %gt8, %lt8 + ret i8 %r +} + +; Constant canonicalization: (a >= 5) - (a <= 5) => scmp(a, 5) +define i8 @signed_sub_const_canonicalization2(i32 %a) { +; CHECK-LABEL: define i8 @signed_sub_const_canonicalization2( +; CHECK-SAME: i32 [[A:%.*]]) { +; CHECK-NEXT: [[LE:%.*]] = icmp slt i32 [[A]], 6 +; CHECK-NEXT: [[LE8_NEG:%.*]] = sext i1 [[LE]] to i8 +; CHECK-NEXT: [[GE:%.*]] = icmp sgt i32 [[A]], 4 +; CHECK-NEXT: [[GE8:%.*]] = zext i1 [[GE]] to i8 +; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[LE8_NEG]], [[GE8]] +; CHECK-NEXT: ret i8 [[R]] +; + %le = icmp sle i32 %a, 5 + %le8 = zext i1 %le to i8 + %ge = icmp sge i32 %a, 5 + %ge8 = zext i1 %ge to i8 + %r = sub i8 %ge8, %le8 + ret i8 %r +} + +; Unsigned constant canonicalization: (a > 4) - (a < 6) => ucmp(a, 5) +define i8 @unsigned_sub_const_canonicalization(i32 %a) { +; CHECK-LABEL: define i8 @unsigned_sub_const_canonicalization( +; CHECK-SAME: i32 [[A:%.*]]) { +; CHECK-NEXT: [[LT:%.*]] = icmp ult i32 [[A]], 6 +; CHECK-NEXT: [[LT8_NEG:%.*]] = sext i1 [[LT]] to i8 +; CHECK-NEXT: [[GT:%.*]] = icmp ugt i32 [[A]], 4 +; CHECK-NEXT: [[GT8:%.*]] = zext i1 [[GT]] to i8 +; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[LT8_NEG]], [[GT8]] +; CHECK-NEXT: ret i8 [[R]] +; + %lt = icmp ult i32 %a, 6 + %lt8 = zext i1 %lt to i8 + %gt = icmp ugt i32 %a, 4 + %gt8 = zext i1 %gt to i8 + %r = sub i8 %gt8, %lt8 + ret i8 %r +} + +; Constant canonicalization with >= and <=: (a >= 5) - (a <= 5) => scmp(a, 5) +define i8 @signed_sub_const_canonicalization_ge_le(i32 %a) { +; CHECK-LABEL: define i8 @signed_sub_const_canonicalization_ge_le( +; CHECK-SAME: i32 [[A:%.*]]) { +; CHECK-NEXT: [[LE:%.*]] = icmp slt i32 [[A]], 6 +; CHECK-NEXT: [[LE8_NEG:%.*]] = sext i1 [[LE]] to i8 +; CHECK-NEXT: [[GE:%.*]] = icmp sgt i32 [[A]], 4 +; CHECK-NEXT: [[GE8:%.*]] = zext i1 [[GE]] to i8 +; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[LE8_NEG]], [[GE8]] +; CHECK-NEXT: ret i8 [[R]] +; + %le = icmp sle i32 %a, 5 + %le8 = zext i1 %le to i8 + %ge = icmp sge i32 %a, 5 + %ge8 = zext i1 %ge to i8 + %r = sub i8 %ge8, %le8 + ret i8 %r +} + +; More constant canonicalization: (a > 2) - (a < 4) => scmp(a, 3) +define i8 @signed_sub_const_canonicalization3(i32 %a) { +; CHECK-LABEL: define i8 @signed_sub_const_canonicalization3( +; CHECK-SAME: i32 [[A:%.*]]) { +; CHECK-NEXT: [[LT:%.*]] = icmp slt i32 [[A]], 4 +; CHECK-NEXT: [[LT8_NEG:%.*]] = sext i1 [[LT]] to i8 +; CHECK-NEXT: [[GT:%.*]] = icmp sgt i32 [[A]], 2 +; CHECK-NEXT: [[GT8:%.*]] = zext i1 [[GT]] to i8 +; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[LT8_NEG]], [[GT8]] +; CHECK-NEXT: ret i8 [[R]] +; + %lt = icmp slt i32 %a, 4 + %lt8 = zext i1 %lt to i8 + %gt = icmp sgt i32 %a, 2 + %gt8 = zext i1 %gt to i8 + %r = sub i8 %gt8, %lt8 + ret i8 %r +} + +; Negative test: constants that are more than one apart - should NOT canonicalize +define i8 @signed_sub_const_no_canonicalization(i32 %a) { +; CHECK-LABEL: define i8 @signed_sub_const_no_canonicalization( +; CHECK-SAME: i32 [[A:%.*]]) { +; CHECK-NEXT: [[LT:%.*]] = icmp slt i32 [[A]], 10 +; CHECK-NEXT: [[LT8_NEG:%.*]] = sext i1 [[LT]] to i8 +; CHECK-NEXT: [[GT:%.*]] = icmp sgt i32 [[A]], 4 +; CHECK-NEXT: [[GT8:%.*]] = zext i1 [[GT]] to i8 +; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[LT8_NEG]], [[GT8]] +; CHECK-NEXT: ret i8 [[R]] +; + %lt = icmp slt i32 %a, 10 + %lt8 = zext i1 %lt to i8 + %gt = icmp sgt i32 %a, 4 + %gt8 = zext i1 %gt to i8 + %r = sub i8 %gt8, %lt8 + ret i8 %r +} From 38c3aa879eea773e426819b7994af67e8751450b Mon Sep 17 00:00:00 2001 From: AZero13 Date: Fri, 17 Oct 2025 16:06:06 -0400 Subject: [PATCH 2/2] [InstCombine] Add a >= b - a<=b to scmp and ucmp folds https://alive2.llvm.org/ce/z/QiMA_i --- .../InstCombine/InstCombineAddSub.cpp | 56 +++++++++++++++++-- .../sext-a-lt-b-plus-zext-a-gt-b-to-uscmp.ll | 54 +++--------------- 2 files changed, 59 insertions(+), 51 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp index 9bee523c7b7e5..fe327cbe93dcc 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -1660,6 +1660,7 @@ Instruction *InstCombinerImpl::visitAdd(BinaryOperator &I) { return replaceInstUsesWith(I, Constant::getNullValue(I.getType())); // sext(A < B) + zext(A > B) => ucmp/scmp(A, B) + // sext(A <= B) + zext(A >= B) => ucmp/scmp(A, B) CmpPredicate LTPred, GTPred; if (match(&I, m_c_Add(m_SExt(m_c_ICmp(LTPred, m_Value(A), m_Value(B))), @@ -1670,13 +1671,56 @@ Instruction *InstCombinerImpl::visitAdd(BinaryOperator &I) { std::swap(A, B); } - if (ICmpInst::isLT(LTPred) && ICmpInst::isGT(GTPred) && - ICmpInst::isSigned(LTPred) == ICmpInst::isSigned(GTPred)) + if (ICmpInst::isSigned(LTPred) == ICmpInst::isSigned(GTPred)) { + Intrinsic::ID IID = + ICmpInst::isSigned(LTPred) ? Intrinsic::scmp : Intrinsic::ucmp; + + // Handle strict inequalities: sext(A < B) + zext(A > B) => scmp/ucmp(A, + // B) + if (ICmpInst::isLT(LTPred) && ICmpInst::isGT(GTPred)) { + return replaceInstUsesWith(I, Builder.CreateIntrinsic(Ty, IID, {A, B})); + } + + // Handle non-strict inequalities: sext(A <= B) + zext(A >= B) => + // scmp/ucmp(A, B) + if (ICmpInst::isLE(LTPred) && ICmpInst::isGE(GTPred)) { + return replaceInstUsesWith(I, Builder.CreateIntrinsic(Ty, IID, {A, B})); + } + } + } + + // Handle constant case: sext/zext(x > C1) + zext/sext(x < C2) where C2 = C1 + + // 2 This represents (x >= C1+1) - (x <= C1+1) => scmp/ucmp(x, C1+1) + Value *X; + ConstantInt *Const1, *Const2; + CmpPredicate Pred1, Pred2; + if (match(&I, + m_c_Add( + m_SExt(m_ICmp(Pred1, m_Value(X), m_ConstantInt(Const1))), + m_ZExt(m_ICmp(Pred2, m_Deferred(X), m_ConstantInt(Const2))))) && + X->getType()->isIntOrIntVectorTy()) { + + // Case 1: sext(x > C1) + zext(x < C2) where C2 = C1 + 2 + if (ICmpInst::isGT(Pred1) && ICmpInst::isLT(Pred2) && + Const2->getValue() == Const1->getValue() + 2) { + Intrinsic::ID IID = + ICmpInst::isSigned(Pred1) ? Intrinsic::scmp : Intrinsic::ucmp; + Constant *C1Plus1 = + ConstantInt::get(Const1->getType(), Const1->getValue() + 1); return replaceInstUsesWith( - I, Builder.CreateIntrinsic( - Ty, - ICmpInst::isSigned(LTPred) ? Intrinsic::scmp : Intrinsic::ucmp, - {A, B})); + I, Builder.CreateIntrinsic(Ty, IID, {X, C1Plus1})); + } + + // Case 2: sext(x < C1) + zext(x > C2) where C1 = C2 + 2 + if (ICmpInst::isLT(Pred1) && ICmpInst::isGT(Pred2) && + Const1->getValue() == Const2->getValue() + 2) { + Intrinsic::ID IID = + ICmpInst::isSigned(Pred1) ? Intrinsic::scmp : Intrinsic::ucmp; + Constant *C2Plus1 = + ConstantInt::get(Const2->getType(), Const2->getValue() + 1); + return replaceInstUsesWith( + I, Builder.CreateIntrinsic(Ty, IID, {X, C2Plus1})); + } } // A+B --> A|B iff A and B have no bits set in common. diff --git a/llvm/test/Transforms/InstCombine/sext-a-lt-b-plus-zext-a-gt-b-to-uscmp.ll b/llvm/test/Transforms/InstCombine/sext-a-lt-b-plus-zext-a-gt-b-to-uscmp.ll index 53982601fb7d4..023ad5ef4b35a 100644 --- a/llvm/test/Transforms/InstCombine/sext-a-lt-b-plus-zext-a-gt-b-to-uscmp.ll +++ b/llvm/test/Transforms/InstCombine/sext-a-lt-b-plus-zext-a-gt-b-to-uscmp.ll @@ -187,11 +187,7 @@ define i8 @signed_add_neg5(i32 %a, i32 %b) { define i8 @signed_add_ge_le(i32 %a, i32 %b) { ; CHECK-LABEL: define i8 @signed_add_ge_le( ; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) { -; CHECK-NEXT: [[LE:%.*]] = icmp sle i32 [[A]], [[B]] -; CHECK-NEXT: [[LE8:%.*]] = sext i1 [[LE]] to i8 -; CHECK-NEXT: [[GE:%.*]] = icmp sge i32 [[A]], [[B]] -; CHECK-NEXT: [[GE8:%.*]] = zext i1 [[GE]] to i8 -; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[LE8]], [[GE8]] +; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[A]], i32 [[B]]) ; CHECK-NEXT: ret i8 [[R]] ; %le = icmp sle i32 %a, %b @@ -206,11 +202,7 @@ define i8 @signed_add_ge_le(i32 %a, i32 %b) { define i8 @unsigned_add_ge_le(i32 %a, i32 %b) { ; CHECK-LABEL: define i8 @unsigned_add_ge_le( ; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) { -; CHECK-NEXT: [[LE:%.*]] = icmp ule i32 [[A]], [[B]] -; CHECK-NEXT: [[LE8:%.*]] = sext i1 [[LE]] to i8 -; CHECK-NEXT: [[GE:%.*]] = icmp uge i32 [[A]], [[B]] -; CHECK-NEXT: [[GE8:%.*]] = zext i1 [[GE]] to i8 -; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[LE8]], [[GE8]] +; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A]], i32 [[B]]) ; CHECK-NEXT: ret i8 [[R]] ; %le = icmp ule i32 %a, %b @@ -225,11 +217,7 @@ define i8 @unsigned_add_ge_le(i32 %a, i32 %b) { define i8 @signed_sub_ge_le(i32 %a, i32 %b) { ; CHECK-LABEL: define i8 @signed_sub_ge_le( ; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) { -; CHECK-NEXT: [[LE:%.*]] = icmp sle i32 [[A]], [[B]] -; CHECK-NEXT: [[LE8_NEG:%.*]] = sext i1 [[LE]] to i8 -; CHECK-NEXT: [[GE:%.*]] = icmp sge i32 [[A]], [[B]] -; CHECK-NEXT: [[GE8:%.*]] = zext i1 [[GE]] to i8 -; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[LE8_NEG]], [[GE8]] +; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[A]], i32 [[B]]) ; CHECK-NEXT: ret i8 [[R]] ; %le = icmp sle i32 %a, %b @@ -244,11 +232,7 @@ define i8 @signed_sub_ge_le(i32 %a, i32 %b) { define i8 @unsigned_sub_ge_le(i32 %a, i32 %b) { ; CHECK-LABEL: define i8 @unsigned_sub_ge_le( ; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) { -; CHECK-NEXT: [[LE:%.*]] = icmp ule i32 [[A]], [[B]] -; CHECK-NEXT: [[LE8_NEG:%.*]] = sext i1 [[LE]] to i8 -; CHECK-NEXT: [[GE:%.*]] = icmp uge i32 [[A]], [[B]] -; CHECK-NEXT: [[GE8:%.*]] = zext i1 [[GE]] to i8 -; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[LE8_NEG]], [[GE8]] +; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A]], i32 [[B]]) ; CHECK-NEXT: ret i8 [[R]] ; %le = icmp ule i32 %a, %b @@ -263,11 +247,7 @@ define i8 @unsigned_sub_ge_le(i32 %a, i32 %b) { define i8 @signed_sub_const_canonicalization(i32 %a) { ; CHECK-LABEL: define i8 @signed_sub_const_canonicalization( ; CHECK-SAME: i32 [[A:%.*]]) { -; CHECK-NEXT: [[LT:%.*]] = icmp slt i32 [[A]], 6 -; CHECK-NEXT: [[LT8_NEG:%.*]] = sext i1 [[LT]] to i8 -; CHECK-NEXT: [[GT:%.*]] = icmp sgt i32 [[A]], 4 -; CHECK-NEXT: [[GT8:%.*]] = zext i1 [[GT]] to i8 -; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[LT8_NEG]], [[GT8]] +; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[A]], i32 5) ; CHECK-NEXT: ret i8 [[R]] ; %lt = icmp slt i32 %a, 6 @@ -282,11 +262,7 @@ define i8 @signed_sub_const_canonicalization(i32 %a) { define i8 @signed_sub_const_canonicalization2(i32 %a) { ; CHECK-LABEL: define i8 @signed_sub_const_canonicalization2( ; CHECK-SAME: i32 [[A:%.*]]) { -; CHECK-NEXT: [[LE:%.*]] = icmp slt i32 [[A]], 6 -; CHECK-NEXT: [[LE8_NEG:%.*]] = sext i1 [[LE]] to i8 -; CHECK-NEXT: [[GE:%.*]] = icmp sgt i32 [[A]], 4 -; CHECK-NEXT: [[GE8:%.*]] = zext i1 [[GE]] to i8 -; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[LE8_NEG]], [[GE8]] +; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[A]], i32 5) ; CHECK-NEXT: ret i8 [[R]] ; %le = icmp sle i32 %a, 5 @@ -301,11 +277,7 @@ define i8 @signed_sub_const_canonicalization2(i32 %a) { define i8 @unsigned_sub_const_canonicalization(i32 %a) { ; CHECK-LABEL: define i8 @unsigned_sub_const_canonicalization( ; CHECK-SAME: i32 [[A:%.*]]) { -; CHECK-NEXT: [[LT:%.*]] = icmp ult i32 [[A]], 6 -; CHECK-NEXT: [[LT8_NEG:%.*]] = sext i1 [[LT]] to i8 -; CHECK-NEXT: [[GT:%.*]] = icmp ugt i32 [[A]], 4 -; CHECK-NEXT: [[GT8:%.*]] = zext i1 [[GT]] to i8 -; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[LT8_NEG]], [[GT8]] +; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A]], i32 5) ; CHECK-NEXT: ret i8 [[R]] ; %lt = icmp ult i32 %a, 6 @@ -320,11 +292,7 @@ define i8 @unsigned_sub_const_canonicalization(i32 %a) { define i8 @signed_sub_const_canonicalization_ge_le(i32 %a) { ; CHECK-LABEL: define i8 @signed_sub_const_canonicalization_ge_le( ; CHECK-SAME: i32 [[A:%.*]]) { -; CHECK-NEXT: [[LE:%.*]] = icmp slt i32 [[A]], 6 -; CHECK-NEXT: [[LE8_NEG:%.*]] = sext i1 [[LE]] to i8 -; CHECK-NEXT: [[GE:%.*]] = icmp sgt i32 [[A]], 4 -; CHECK-NEXT: [[GE8:%.*]] = zext i1 [[GE]] to i8 -; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[LE8_NEG]], [[GE8]] +; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[A]], i32 5) ; CHECK-NEXT: ret i8 [[R]] ; %le = icmp sle i32 %a, 5 @@ -339,11 +307,7 @@ define i8 @signed_sub_const_canonicalization_ge_le(i32 %a) { define i8 @signed_sub_const_canonicalization3(i32 %a) { ; CHECK-LABEL: define i8 @signed_sub_const_canonicalization3( ; CHECK-SAME: i32 [[A:%.*]]) { -; CHECK-NEXT: [[LT:%.*]] = icmp slt i32 [[A]], 4 -; CHECK-NEXT: [[LT8_NEG:%.*]] = sext i1 [[LT]] to i8 -; CHECK-NEXT: [[GT:%.*]] = icmp sgt i32 [[A]], 2 -; CHECK-NEXT: [[GT8:%.*]] = zext i1 [[GT]] to i8 -; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[LT8_NEG]], [[GT8]] +; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[A]], i32 3) ; CHECK-NEXT: ret i8 [[R]] ; %lt = icmp slt i32 %a, 4