[llvm] [InstCombine] Implement folds of icmp of UCMP/SCMP call and a constant (PR #96118)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 19 15:04:24 PDT 2024
https://github.com/Poseydon42 created https://github.com/llvm/llvm-project/pull/96118
This patch handles various cases where an operation of the kind `icmp (ucmp/scmp x, y), constant` folds to `icmp x, y`. Another patch with cases where this operation folds to a constant (i.e. dumb cases like `icmp eq (cmp x, y), 4` should be published in a couple of days.
I wasn't sure what negative tests should be added here, if any are necessary at all. I'd love to hear your suggestions.
Proofs (ucmp): https://alive2.llvm.org/ce/z/qQ7ihz
Proofs (scmp): https://alive2.llvm.org/ce/z/cipKEn
>From af26a2001d5a1661690c2b79a7f257ff6a190570 Mon Sep 17 00:00:00 2001
From: Poseydon42 <vvmposeydon at gmail.com>
Date: Wed, 19 Jun 2024 22:57:46 +0100
Subject: [PATCH 1/2] [InstCombine] Added tests for various folds of icmp
(UCMP/SCMP, C)
---
llvm/test/Transforms/InstCombine/scmp.ll | 170 +++++++++++++++++++++++
llvm/test/Transforms/InstCombine/ucmp.ll | 170 +++++++++++++++++++++++
2 files changed, 340 insertions(+)
create mode 100644 llvm/test/Transforms/InstCombine/scmp.ll
create mode 100644 llvm/test/Transforms/InstCombine/ucmp.ll
diff --git a/llvm/test/Transforms/InstCombine/scmp.ll b/llvm/test/Transforms/InstCombine/scmp.ll
new file mode 100644
index 0000000000000..b694eac0f5e06
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/scmp.ll
@@ -0,0 +1,170 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+
+define i1 @scmp_eq_0(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @scmp_eq_0(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
+; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 0
+; CHECK-NEXT: ret i1 [[TMP2]]
+;
+ %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
+ %2 = icmp eq i8 %1, 0
+ ret i1 %2
+}
+
+define i1 @scmp_ne_0(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @scmp_ne_0(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
+; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i8 [[TMP1]], 0
+; CHECK-NEXT: ret i1 [[TMP2]]
+;
+ %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
+ %2 = icmp ne i8 %1, 0
+ ret i1 %2
+}
+
+define i1 @scmp_eq_1(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @scmp_eq_1(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
+; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 1
+; CHECK-NEXT: ret i1 [[TMP2]]
+;
+ %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
+ %2 = icmp eq i8 %1, 1
+ ret i1 %2
+}
+
+define i1 @scmp_ne_1(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @scmp_ne_1(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
+; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i8 [[TMP1]], 1
+; CHECK-NEXT: ret i1 [[TMP2]]
+;
+ %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
+ %2 = icmp ne i8 %1, 1
+ ret i1 %2
+}
+
+define i1 @scmp_eq_negative_1(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @scmp_eq_negative_1(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
+; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], -1
+; CHECK-NEXT: ret i1 [[TMP2]]
+;
+ %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
+ %2 = icmp eq i8 %1, -1
+ ret i1 %2
+}
+
+define i1 @scmp_ne_negative_1(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @scmp_ne_negative_1(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
+; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i8 [[TMP1]], -1
+; CHECK-NEXT: ret i1 [[TMP2]]
+;
+ %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
+ %2 = icmp ne i8 %1, -1
+ ret i1 %2
+}
+
+define i1 @scmp_sgt_0(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @scmp_sgt_0(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
+; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i8 [[TMP1]], 0
+; CHECK-NEXT: ret i1 [[TMP2]]
+;
+ %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
+ %2 = icmp sgt i8 %1, 0
+ ret i1 %2
+}
+
+define i1 @scmp_sgt_neg_1(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @scmp_sgt_neg_1(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
+; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i8 [[TMP1]], -1
+; CHECK-NEXT: ret i1 [[TMP2]]
+;
+ %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
+ %2 = icmp sgt i8 %1, -1
+ ret i1 %2
+}
+
+define i1 @scmp_sge_0(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @scmp_sge_0(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
+; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i8 [[TMP1]], -1
+; CHECK-NEXT: ret i1 [[TMP2]]
+;
+ %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
+ %2 = icmp sge i8 %1, 0
+ ret i1 %2
+}
+
+define i1 @scmp_sge_1(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @scmp_sge_1(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
+; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i8 [[TMP1]], 0
+; CHECK-NEXT: ret i1 [[TMP2]]
+;
+ %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
+ %2 = icmp sge i8 %1, 1
+ ret i1 %2
+}
+
+define i1 @scmp_slt_0(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @scmp_slt_0(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
+; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i8 [[TMP1]], 0
+; CHECK-NEXT: ret i1 [[TMP2]]
+;
+ %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
+ %2 = icmp slt i8 %1, 0
+ ret i1 %2
+}
+
+define i1 @scmp_slt_1(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @scmp_slt_1(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
+; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i8 [[TMP1]], 1
+; CHECK-NEXT: ret i1 [[TMP2]]
+;
+ %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
+ %2 = icmp slt i8 %1, 1
+ ret i1 %2
+}
+
+define i1 @scmp_sle_0(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @scmp_sle_0(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
+; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i8 [[TMP1]], 1
+; CHECK-NEXT: ret i1 [[TMP2]]
+;
+ %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
+ %2 = icmp sle i8 %1, 0
+ ret i1 %2
+}
+
+define i1 @scmp_sle_neg_1(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @scmp_sle_neg_1(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
+; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i8 [[TMP1]], 0
+; CHECK-NEXT: ret i1 [[TMP2]]
+;
+ %1 = call i8 @llvm.scmp(i32 %x, i32 %y)
+ %2 = icmp sle i8 %1, -1
+ ret i1 %2
+}
diff --git a/llvm/test/Transforms/InstCombine/ucmp.ll b/llvm/test/Transforms/InstCombine/ucmp.ll
new file mode 100644
index 0000000000000..88b23fd0972fe
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/ucmp.ll
@@ -0,0 +1,170 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+
+define i1 @ucmp_eq_0(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @ucmp_eq_0(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])
+; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 0
+; CHECK-NEXT: ret i1 [[TMP2]]
+;
+ %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
+ %2 = icmp eq i8 %1, 0
+ ret i1 %2
+}
+
+define i1 @ucmp_ne_0(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @ucmp_ne_0(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])
+; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i8 [[TMP1]], 0
+; CHECK-NEXT: ret i1 [[TMP2]]
+;
+ %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
+ %2 = icmp ne i8 %1, 0
+ ret i1 %2
+}
+
+define i1 @ucmp_eq_1(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @ucmp_eq_1(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])
+; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 1
+; CHECK-NEXT: ret i1 [[TMP2]]
+;
+ %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
+ %2 = icmp eq i8 %1, 1
+ ret i1 %2
+}
+
+define i1 @ucmp_ne_1(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @ucmp_ne_1(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])
+; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i8 [[TMP1]], 1
+; CHECK-NEXT: ret i1 [[TMP2]]
+;
+ %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
+ %2 = icmp ne i8 %1, 1
+ ret i1 %2
+}
+
+define i1 @ucmp_eq_negative_1(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @ucmp_eq_negative_1(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])
+; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], -1
+; CHECK-NEXT: ret i1 [[TMP2]]
+;
+ %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
+ %2 = icmp eq i8 %1, -1
+ ret i1 %2
+}
+
+define i1 @ucmp_ne_negative_1(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @ucmp_ne_negative_1(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])
+; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i8 [[TMP1]], -1
+; CHECK-NEXT: ret i1 [[TMP2]]
+;
+ %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
+ %2 = icmp ne i8 %1, -1
+ ret i1 %2
+}
+
+define i1 @ucmp_sgt_0(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @ucmp_sgt_0(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])
+; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i8 [[TMP1]], 0
+; CHECK-NEXT: ret i1 [[TMP2]]
+;
+ %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
+ %2 = icmp sgt i8 %1, 0
+ ret i1 %2
+}
+
+define i1 @ucmp_sgt_neg_1(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @ucmp_sgt_neg_1(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])
+; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i8 [[TMP1]], -1
+; CHECK-NEXT: ret i1 [[TMP2]]
+;
+ %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
+ %2 = icmp sgt i8 %1, -1
+ ret i1 %2
+}
+
+define i1 @ucmp_sge_0(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @ucmp_sge_0(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])
+; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i8 [[TMP1]], -1
+; CHECK-NEXT: ret i1 [[TMP2]]
+;
+ %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
+ %2 = icmp sge i8 %1, 0
+ ret i1 %2
+}
+
+define i1 @ucmp_sge_1(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @ucmp_sge_1(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])
+; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i8 [[TMP1]], 0
+; CHECK-NEXT: ret i1 [[TMP2]]
+;
+ %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
+ %2 = icmp sge i8 %1, 1
+ ret i1 %2
+}
+
+define i1 @ucmp_slt_0(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @ucmp_slt_0(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])
+; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i8 [[TMP1]], 0
+; CHECK-NEXT: ret i1 [[TMP2]]
+;
+ %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
+ %2 = icmp slt i8 %1, 0
+ ret i1 %2
+}
+
+define i1 @ucmp_slt_1(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @ucmp_slt_1(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])
+; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i8 [[TMP1]], 1
+; CHECK-NEXT: ret i1 [[TMP2]]
+;
+ %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
+ %2 = icmp slt i8 %1, 1
+ ret i1 %2
+}
+
+define i1 @ucmp_sle_0(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @ucmp_sle_0(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])
+; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i8 [[TMP1]], 1
+; CHECK-NEXT: ret i1 [[TMP2]]
+;
+ %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
+ %2 = icmp sle i8 %1, 0
+ ret i1 %2
+}
+
+define i1 @ucmp_sle_neg_1(i32 %x, i32 %y) {
+; CHECK-LABEL: define i1 @ucmp_sle_neg_1(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])
+; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i8 [[TMP1]], 0
+; CHECK-NEXT: ret i1 [[TMP2]]
+;
+ %1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
+ %2 = icmp sle i8 %1, -1
+ ret i1 %2
+}
>From 9d00eb33f9b8346ac27b4b9b0b742860c03a897c Mon Sep 17 00:00:00 2001
From: Poseydon42 <vvmposeydon at gmail.com>
Date: Wed, 19 Jun 2024 22:59:36 +0100
Subject: [PATCH 2/2] [InstCombine] Implement folds of icmp with UCMP/SCMP and
a constant
---
.../InstCombine/InstCombineCompares.cpp | 91 +++++++++++++++++++
llvm/test/Transforms/InstCombine/scmp.ll | 42 +++------
llvm/test/Transforms/InstCombine/ucmp.ll | 42 +++------
3 files changed, 119 insertions(+), 56 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 34b0f8b860497..cb0351259a1f9 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -3926,6 +3926,92 @@ foldICmpUSubSatOrUAddSatWithConstant(ICmpInst::Predicate Pred,
ConstantInt::get(Op1->getType(), EquivInt));
}
+static Instruction *
+foldICmpOfCmpIntrinsicWithConstant(ICmpInst::Predicate Pred, IntrinsicInst *I,
+ const APInt &C,
+ InstCombiner::BuilderTy &Builder) {
+ Intrinsic::ID IID = I->getIntrinsicID();
+ Value *LHS = I->getOperand(0);
+ Value *RHS = I->getOperand(1);
+
+ switch (Pred) {
+ case ICmpInst::ICMP_EQ:
+ if (C.isZero())
+ return new ICmpInst(Pred, LHS, RHS);
+ if (C.isOne())
+ return new ICmpInst(IID == Intrinsic::scmp ? ICmpInst::ICMP_SGT
+ : ICmpInst::ICMP_UGT,
+ LHS, RHS);
+ if (C.isAllOnes())
+ return new ICmpInst(IID == Intrinsic::scmp ? ICmpInst::ICMP_SLT
+ : ICmpInst::ICMP_ULT,
+ LHS, RHS);
+ break;
+
+ case ICmpInst::ICMP_NE:
+ if (C.isZero())
+ return new ICmpInst(Pred, LHS, RHS);
+ if (C.isOne())
+ return new ICmpInst(IID == Intrinsic::scmp ? ICmpInst::ICMP_SLE
+ : ICmpInst::ICMP_ULE,
+ LHS, RHS);
+ if (C.isAllOnes())
+ return new ICmpInst(IID == Intrinsic::scmp ? ICmpInst::ICMP_SGE
+ : ICmpInst::ICMP_UGE,
+ LHS, RHS);
+ break;
+
+ case ICmpInst::ICMP_SGT:
+ if (C.isAllOnes())
+ return new ICmpInst(IID == Intrinsic::scmp ? ICmpInst::ICMP_SGE
+ : ICmpInst::ICMP_UGE,
+ LHS, RHS);
+ if (C.isZero())
+ return new ICmpInst(IID == Intrinsic::scmp ? ICmpInst::ICMP_SGT
+ : ICmpInst::ICMP_UGT,
+ LHS, RHS);
+ break;
+
+ case ICmpInst::ICMP_SGE:
+ if (C.isZero())
+ return new ICmpInst(IID == Intrinsic::scmp ? ICmpInst::ICMP_SGE
+ : ICmpInst::ICMP_UGE,
+ LHS, RHS);
+ if (C.isOne())
+ return new ICmpInst(IID == Intrinsic::scmp ? ICmpInst::ICMP_SGT
+ : ICmpInst::ICMP_UGT,
+ LHS, RHS);
+ break;
+
+ case ICmpInst::ICMP_SLT:
+ if (C.isZero())
+ return new ICmpInst(IID == Intrinsic::scmp ? ICmpInst::ICMP_SLT
+ : ICmpInst::ICMP_ULT,
+ LHS, RHS);
+ if (C.isOne())
+ return new ICmpInst(IID == Intrinsic::scmp ? ICmpInst::ICMP_SLE
+ : ICmpInst::ICMP_ULE,
+ LHS, RHS);
+ break;
+
+ case llvm::ICmpInst::ICMP_SLE:
+ if (C.isZero())
+ return new ICmpInst(IID == Intrinsic::scmp ? ICmpInst::ICMP_SLE
+ : ICmpInst::ICMP_ULE,
+ LHS, RHS);
+ if (C.isAllOnes())
+ return new ICmpInst(IID == Intrinsic::scmp ? ICmpInst::ICMP_SLT
+ : ICmpInst::ICMP_ULT,
+ LHS, RHS);
+ break;
+
+ default:
+ return nullptr;
+ }
+
+ return nullptr;
+}
+
/// Fold an icmp with LLVM intrinsic and constant operand: icmp Pred II, C.
Instruction *InstCombinerImpl::foldICmpIntrinsicWithConstant(ICmpInst &Cmp,
IntrinsicInst *II,
@@ -3947,6 +4033,11 @@ Instruction *InstCombinerImpl::foldICmpIntrinsicWithConstant(ICmpInst &Cmp,
if (Instruction *R = foldCtpopPow2Test(Cmp, II, C, Builder, Q))
return R;
} break;
+ case Intrinsic::scmp:
+ case Intrinsic::ucmp:
+ if (auto *Folded = foldICmpOfCmpIntrinsicWithConstant(Pred, II, C, Builder))
+ return Folded;
+ break;
}
if (Cmp.isEquality())
diff --git a/llvm/test/Transforms/InstCombine/scmp.ll b/llvm/test/Transforms/InstCombine/scmp.ll
index b694eac0f5e06..4f903a79afd5d 100644
--- a/llvm/test/Transforms/InstCombine/scmp.ll
+++ b/llvm/test/Transforms/InstCombine/scmp.ll
@@ -4,8 +4,7 @@
define i1 @scmp_eq_0(i32 %x, i32 %y) {
; CHECK-LABEL: define i1 @scmp_eq_0(
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
-; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 0
+; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[X]], [[Y]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
%1 = call i8 @llvm.scmp(i32 %x, i32 %y)
@@ -16,8 +15,7 @@ define i1 @scmp_eq_0(i32 %x, i32 %y) {
define i1 @scmp_ne_0(i32 %x, i32 %y) {
; CHECK-LABEL: define i1 @scmp_ne_0(
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
-; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i8 [[TMP1]], 0
+; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[X]], [[Y]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
%1 = call i8 @llvm.scmp(i32 %x, i32 %y)
@@ -28,8 +26,7 @@ define i1 @scmp_ne_0(i32 %x, i32 %y) {
define i1 @scmp_eq_1(i32 %x, i32 %y) {
; CHECK-LABEL: define i1 @scmp_eq_1(
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
-; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 1
+; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[X]], [[Y]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
%1 = call i8 @llvm.scmp(i32 %x, i32 %y)
@@ -40,8 +37,7 @@ define i1 @scmp_eq_1(i32 %x, i32 %y) {
define i1 @scmp_ne_1(i32 %x, i32 %y) {
; CHECK-LABEL: define i1 @scmp_ne_1(
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
-; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i8 [[TMP1]], 1
+; CHECK-NEXT: [[TMP2:%.*]] = icmp sle i32 [[X]], [[Y]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
%1 = call i8 @llvm.scmp(i32 %x, i32 %y)
@@ -52,8 +48,7 @@ define i1 @scmp_ne_1(i32 %x, i32 %y) {
define i1 @scmp_eq_negative_1(i32 %x, i32 %y) {
; CHECK-LABEL: define i1 @scmp_eq_negative_1(
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
-; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], -1
+; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[X]], [[Y]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
%1 = call i8 @llvm.scmp(i32 %x, i32 %y)
@@ -64,8 +59,7 @@ define i1 @scmp_eq_negative_1(i32 %x, i32 %y) {
define i1 @scmp_ne_negative_1(i32 %x, i32 %y) {
; CHECK-LABEL: define i1 @scmp_ne_negative_1(
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
-; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i8 [[TMP1]], -1
+; CHECK-NEXT: [[TMP2:%.*]] = icmp sge i32 [[X]], [[Y]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
%1 = call i8 @llvm.scmp(i32 %x, i32 %y)
@@ -76,8 +70,7 @@ define i1 @scmp_ne_negative_1(i32 %x, i32 %y) {
define i1 @scmp_sgt_0(i32 %x, i32 %y) {
; CHECK-LABEL: define i1 @scmp_sgt_0(
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
-; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i8 [[TMP1]], 0
+; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[X]], [[Y]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
%1 = call i8 @llvm.scmp(i32 %x, i32 %y)
@@ -88,8 +81,7 @@ define i1 @scmp_sgt_0(i32 %x, i32 %y) {
define i1 @scmp_sgt_neg_1(i32 %x, i32 %y) {
; CHECK-LABEL: define i1 @scmp_sgt_neg_1(
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
-; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i8 [[TMP1]], -1
+; CHECK-NEXT: [[TMP2:%.*]] = icmp sge i32 [[X]], [[Y]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
%1 = call i8 @llvm.scmp(i32 %x, i32 %y)
@@ -100,8 +92,7 @@ define i1 @scmp_sgt_neg_1(i32 %x, i32 %y) {
define i1 @scmp_sge_0(i32 %x, i32 %y) {
; CHECK-LABEL: define i1 @scmp_sge_0(
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
-; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i8 [[TMP1]], -1
+; CHECK-NEXT: [[TMP2:%.*]] = icmp sge i32 [[X]], [[Y]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
%1 = call i8 @llvm.scmp(i32 %x, i32 %y)
@@ -112,8 +103,7 @@ define i1 @scmp_sge_0(i32 %x, i32 %y) {
define i1 @scmp_sge_1(i32 %x, i32 %y) {
; CHECK-LABEL: define i1 @scmp_sge_1(
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
-; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i8 [[TMP1]], 0
+; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[X]], [[Y]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
%1 = call i8 @llvm.scmp(i32 %x, i32 %y)
@@ -124,8 +114,7 @@ define i1 @scmp_sge_1(i32 %x, i32 %y) {
define i1 @scmp_slt_0(i32 %x, i32 %y) {
; CHECK-LABEL: define i1 @scmp_slt_0(
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
-; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i8 [[TMP1]], 0
+; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[X]], [[Y]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
%1 = call i8 @llvm.scmp(i32 %x, i32 %y)
@@ -136,8 +125,7 @@ define i1 @scmp_slt_0(i32 %x, i32 %y) {
define i1 @scmp_slt_1(i32 %x, i32 %y) {
; CHECK-LABEL: define i1 @scmp_slt_1(
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
-; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i8 [[TMP1]], 1
+; CHECK-NEXT: [[TMP2:%.*]] = icmp sle i32 [[X]], [[Y]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
%1 = call i8 @llvm.scmp(i32 %x, i32 %y)
@@ -148,8 +136,7 @@ define i1 @scmp_slt_1(i32 %x, i32 %y) {
define i1 @scmp_sle_0(i32 %x, i32 %y) {
; CHECK-LABEL: define i1 @scmp_sle_0(
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
-; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i8 [[TMP1]], 1
+; CHECK-NEXT: [[TMP2:%.*]] = icmp sle i32 [[X]], [[Y]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
%1 = call i8 @llvm.scmp(i32 %x, i32 %y)
@@ -160,8 +147,7 @@ define i1 @scmp_sle_0(i32 %x, i32 %y) {
define i1 @scmp_sle_neg_1(i32 %x, i32 %y) {
; CHECK-LABEL: define i1 @scmp_sle_neg_1(
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
-; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i8 [[TMP1]], 0
+; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[X]], [[Y]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
%1 = call i8 @llvm.scmp(i32 %x, i32 %y)
diff --git a/llvm/test/Transforms/InstCombine/ucmp.ll b/llvm/test/Transforms/InstCombine/ucmp.ll
index 88b23fd0972fe..9ab67560c9117 100644
--- a/llvm/test/Transforms/InstCombine/ucmp.ll
+++ b/llvm/test/Transforms/InstCombine/ucmp.ll
@@ -4,8 +4,7 @@
define i1 @ucmp_eq_0(i32 %x, i32 %y) {
; CHECK-LABEL: define i1 @ucmp_eq_0(
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])
-; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 0
+; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[X]], [[Y]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
%1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
@@ -16,8 +15,7 @@ define i1 @ucmp_eq_0(i32 %x, i32 %y) {
define i1 @ucmp_ne_0(i32 %x, i32 %y) {
; CHECK-LABEL: define i1 @ucmp_ne_0(
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])
-; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i8 [[TMP1]], 0
+; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[X]], [[Y]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
%1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
@@ -28,8 +26,7 @@ define i1 @ucmp_ne_0(i32 %x, i32 %y) {
define i1 @ucmp_eq_1(i32 %x, i32 %y) {
; CHECK-LABEL: define i1 @ucmp_eq_1(
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])
-; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 1
+; CHECK-NEXT: [[TMP2:%.*]] = icmp ugt i32 [[X]], [[Y]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
%1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
@@ -40,8 +37,7 @@ define i1 @ucmp_eq_1(i32 %x, i32 %y) {
define i1 @ucmp_ne_1(i32 %x, i32 %y) {
; CHECK-LABEL: define i1 @ucmp_ne_1(
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])
-; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i8 [[TMP1]], 1
+; CHECK-NEXT: [[TMP2:%.*]] = icmp ule i32 [[X]], [[Y]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
%1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
@@ -52,8 +48,7 @@ define i1 @ucmp_ne_1(i32 %x, i32 %y) {
define i1 @ucmp_eq_negative_1(i32 %x, i32 %y) {
; CHECK-LABEL: define i1 @ucmp_eq_negative_1(
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])
-; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], -1
+; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[X]], [[Y]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
%1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
@@ -64,8 +59,7 @@ define i1 @ucmp_eq_negative_1(i32 %x, i32 %y) {
define i1 @ucmp_ne_negative_1(i32 %x, i32 %y) {
; CHECK-LABEL: define i1 @ucmp_ne_negative_1(
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])
-; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i8 [[TMP1]], -1
+; CHECK-NEXT: [[TMP2:%.*]] = icmp uge i32 [[X]], [[Y]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
%1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
@@ -76,8 +70,7 @@ define i1 @ucmp_ne_negative_1(i32 %x, i32 %y) {
define i1 @ucmp_sgt_0(i32 %x, i32 %y) {
; CHECK-LABEL: define i1 @ucmp_sgt_0(
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])
-; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i8 [[TMP1]], 0
+; CHECK-NEXT: [[TMP2:%.*]] = icmp ugt i32 [[X]], [[Y]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
%1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
@@ -88,8 +81,7 @@ define i1 @ucmp_sgt_0(i32 %x, i32 %y) {
define i1 @ucmp_sgt_neg_1(i32 %x, i32 %y) {
; CHECK-LABEL: define i1 @ucmp_sgt_neg_1(
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])
-; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i8 [[TMP1]], -1
+; CHECK-NEXT: [[TMP2:%.*]] = icmp uge i32 [[X]], [[Y]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
%1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
@@ -100,8 +92,7 @@ define i1 @ucmp_sgt_neg_1(i32 %x, i32 %y) {
define i1 @ucmp_sge_0(i32 %x, i32 %y) {
; CHECK-LABEL: define i1 @ucmp_sge_0(
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])
-; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i8 [[TMP1]], -1
+; CHECK-NEXT: [[TMP2:%.*]] = icmp uge i32 [[X]], [[Y]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
%1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
@@ -112,8 +103,7 @@ define i1 @ucmp_sge_0(i32 %x, i32 %y) {
define i1 @ucmp_sge_1(i32 %x, i32 %y) {
; CHECK-LABEL: define i1 @ucmp_sge_1(
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])
-; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i8 [[TMP1]], 0
+; CHECK-NEXT: [[TMP2:%.*]] = icmp ugt i32 [[X]], [[Y]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
%1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
@@ -124,8 +114,7 @@ define i1 @ucmp_sge_1(i32 %x, i32 %y) {
define i1 @ucmp_slt_0(i32 %x, i32 %y) {
; CHECK-LABEL: define i1 @ucmp_slt_0(
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])
-; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i8 [[TMP1]], 0
+; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[X]], [[Y]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
%1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
@@ -136,8 +125,7 @@ define i1 @ucmp_slt_0(i32 %x, i32 %y) {
define i1 @ucmp_slt_1(i32 %x, i32 %y) {
; CHECK-LABEL: define i1 @ucmp_slt_1(
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])
-; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i8 [[TMP1]], 1
+; CHECK-NEXT: [[TMP2:%.*]] = icmp ule i32 [[X]], [[Y]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
%1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
@@ -148,8 +136,7 @@ define i1 @ucmp_slt_1(i32 %x, i32 %y) {
define i1 @ucmp_sle_0(i32 %x, i32 %y) {
; CHECK-LABEL: define i1 @ucmp_sle_0(
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])
-; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i8 [[TMP1]], 1
+; CHECK-NEXT: [[TMP2:%.*]] = icmp ule i32 [[X]], [[Y]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
%1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
@@ -160,8 +147,7 @@ define i1 @ucmp_sle_0(i32 %x, i32 %y) {
define i1 @ucmp_sle_neg_1(i32 %x, i32 %y) {
; CHECK-LABEL: define i1 @ucmp_sle_neg_1(
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])
-; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i8 [[TMP1]], 0
+; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[X]], [[Y]]
; CHECK-NEXT: ret i1 [[TMP2]]
;
%1 = call i8 @llvm.ucmp(i32 %x, i32 %y)
More information about the llvm-commits
mailing list