[llvm] [InstCombine] Fold `(x < y) ? -1 : zext(x != y)` into `u/scmp(x,y)` (PR #101049)
Volodymyr Vasylkun via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 29 11:22:38 PDT 2024
https://github.com/Poseydon42 updated https://github.com/llvm/llvm-project/pull/101049
>From 8dca7281d5177269a8f6e4b12b5181658510990e Mon Sep 17 00:00:00 2001
From: Poseydon42 <vvmposeydon at gmail.com>
Date: Mon, 29 Jul 2024 18:43:33 +0100
Subject: [PATCH 1/6] Precommit tests
---
llvm/test/Transforms/InstCombine/scmp.ll | 99 ++++++++++++++++++++++++
llvm/test/Transforms/InstCombine/ucmp.ll | 99 ++++++++++++++++++++++++
2 files changed, 198 insertions(+)
diff --git a/llvm/test/Transforms/InstCombine/scmp.ll b/llvm/test/Transforms/InstCombine/scmp.ll
index 2523872562cad..53ab819a7d340 100644
--- a/llvm/test/Transforms/InstCombine/scmp.ll
+++ b/llvm/test/Transforms/InstCombine/scmp.ll
@@ -183,3 +183,102 @@ define i8 @scmp_negated_multiuse(i32 %x, i32 %y) {
%2 = sub i8 0, %1
ret i8 %2
}
+
+; Fold ((x s< y) ? -1 : (x != y)) into scmp(x, y)
+define i8 @scmp_from_select(i32 %x, i32 %y) {
+; CHECK-LABEL: define i8 @scmp_from_select(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[NE_BOOL:%.*]] = icmp ne i32 [[X]], [[Y]]
+; CHECK-NEXT: [[NE:%.*]] = zext i1 [[NE_BOOL]] to i8
+; CHECK-NEXT: [[LT:%.*]] = icmp slt i32 [[X]], [[Y]]
+; CHECK-NEXT: [[R:%.*]] = select i1 [[LT]], i8 -1, i8 [[NE]]
+; CHECK-NEXT: ret i8 [[R]]
+;
+ %ne_bool = icmp ne i32 %x, %y
+ %ne = zext i1 %ne_bool to i8
+ %lt = icmp slt i32 %x, %y
+ %r = select i1 %lt, i8 -1, i8 %ne
+ ret i8 %r
+}
+
+; Negative test: false value of the select is not `icmp ne x, y`
+define i8 @scmp_from_select_neg1(i32 %x, i32 %y) {
+; CHECK-LABEL: define i8 @scmp_from_select_neg1(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[NE_BOOL:%.*]] = icmp eq i32 [[X]], [[Y]]
+; CHECK-NEXT: [[NE:%.*]] = zext i1 [[NE_BOOL]] to i8
+; CHECK-NEXT: [[LT:%.*]] = icmp slt i32 [[X]], [[Y]]
+; CHECK-NEXT: [[R:%.*]] = select i1 [[LT]], i8 -1, i8 [[NE]]
+; CHECK-NEXT: ret i8 [[R]]
+;
+ %ne_bool = icmp eq i32 %x, %y
+ %ne = zext i1 %ne_bool to i8
+ %lt = icmp slt i32 %x, %y
+ %r = select i1 %lt, i8 -1, i8 %ne
+ ret i8 %r
+}
+
+define i8 @scmp_from_select_neg2(i32 %x, i32 %y) {
+; CHECK-LABEL: define i8 @scmp_from_select_neg2(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[NE_BOOL:%.*]] = icmp ne i32 [[Y]], [[X]]
+; CHECK-NEXT: [[NE:%.*]] = zext i1 [[NE_BOOL]] to i8
+; CHECK-NEXT: [[LT:%.*]] = icmp slt i32 [[X]], [[Y]]
+; CHECK-NEXT: [[R:%.*]] = select i1 [[LT]], i8 -1, i8 [[NE]]
+; CHECK-NEXT: ret i8 [[R]]
+;
+ %ne_bool = icmp ne i32 %y, %x
+ %ne = zext i1 %ne_bool to i8
+ %lt = icmp slt i32 %x, %y
+ %r = select i1 %lt, i8 -1, i8 %ne
+ ret i8 %r
+}
+
+; Negative test: true value of select is not -1
+define i8 @scmp_from_select_neg3(i32 %x, i32 %y) {
+; CHECK-LABEL: define i8 @scmp_from_select_neg3(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[NE_BOOL:%.*]] = icmp ne i32 [[X]], [[Y]]
+; CHECK-NEXT: [[NE:%.*]] = zext i1 [[NE_BOOL]] to i8
+; CHECK-NEXT: [[LT:%.*]] = icmp slt i32 [[X]], [[Y]]
+; CHECK-NEXT: [[R:%.*]] = select i1 [[LT]], i8 2, i8 [[NE]]
+; CHECK-NEXT: ret i8 [[R]]
+;
+ %ne_bool = icmp ne i32 %x, %y
+ %ne = zext i1 %ne_bool to i8
+ %lt = icmp slt i32 %x, %y
+ %r = select i1 %lt, i8 2, i8 %ne
+ ret i8 %r
+}
+
+; Negative test: false value of select is sign-extended instead of zero-extended
+define i8 @scmp_from_select_neg4(i32 %x, i32 %y) {
+; CHECK-LABEL: define i8 @scmp_from_select_neg4(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[NE_BOOL:%.*]] = icmp ne i32 [[X]], [[Y]]
+; CHECK-NEXT: [[R:%.*]] = sext i1 [[NE_BOOL]] to i8
+; CHECK-NEXT: ret i8 [[R]]
+;
+ %ne_bool = icmp ne i32 %x, %y
+ %ne = sext i1 %ne_bool to i8
+ %lt = icmp slt i32 %x, %y
+ %r = select i1 %lt, i8 -1, i8 %ne
+ ret i8 %r
+}
+
+; Negative test: condition of select is not (x s< y)
+define i8 @scmp_from_select_neg5(i32 %x, i32 %y) {
+; CHECK-LABEL: define i8 @scmp_from_select_neg5(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[NE_BOOL:%.*]] = icmp ne i32 [[X]], [[Y]]
+; CHECK-NEXT: [[NE:%.*]] = zext i1 [[NE_BOOL]] to i8
+; CHECK-NEXT: [[LT:%.*]] = icmp sgt i32 [[X]], [[Y]]
+; CHECK-NEXT: [[R:%.*]] = select i1 [[LT]], i8 -1, i8 [[NE]]
+; CHECK-NEXT: ret i8 [[R]]
+;
+ %ne_bool = icmp ne i32 %x, %y
+ %ne = zext i1 %ne_bool to i8
+ %lt = icmp sgt i32 %x, %y
+ %r = select i1 %lt, i8 -1, i8 %ne
+ ret i8 %r
+}
diff --git a/llvm/test/Transforms/InstCombine/ucmp.ll b/llvm/test/Transforms/InstCombine/ucmp.ll
index 7210455094baa..08eab78d2eacb 100644
--- a/llvm/test/Transforms/InstCombine/ucmp.ll
+++ b/llvm/test/Transforms/InstCombine/ucmp.ll
@@ -183,3 +183,102 @@ define i8 @ucmp_negated_multiuse(i32 %x, i32 %y) {
%2 = sub i8 0, %1
ret i8 %2
}
+
+; Fold ((x u< y) ? -1 : (x != y)) into ucmp(x, y)
+define i8 @ucmp_from_select(i32 %x, i32 %y) {
+; CHECK-LABEL: define i8 @ucmp_from_select(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[NE_BOOL:%.*]] = icmp ne i32 [[X]], [[Y]]
+; CHECK-NEXT: [[NE:%.*]] = zext i1 [[NE_BOOL]] to i8
+; CHECK-NEXT: [[LT:%.*]] = icmp ult i32 [[X]], [[Y]]
+; CHECK-NEXT: [[R:%.*]] = select i1 [[LT]], i8 -1, i8 [[NE]]
+; CHECK-NEXT: ret i8 [[R]]
+;
+ %ne_bool = icmp ne i32 %x, %y
+ %ne = zext i1 %ne_bool to i8
+ %lt = icmp ult i32 %x, %y
+ %r = select i1 %lt, i8 -1, i8 %ne
+ ret i8 %r
+}
+
+; Negative test: false value of the select is not `icmp ne x, y`
+define i8 @ucmp_from_select_neg1(i32 %x, i32 %y) {
+; CHECK-LABEL: define i8 @ucmp_from_select_neg1(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[NE_BOOL:%.*]] = icmp eq i32 [[X]], [[Y]]
+; CHECK-NEXT: [[NE:%.*]] = zext i1 [[NE_BOOL]] to i8
+; CHECK-NEXT: [[LT:%.*]] = icmp ult i32 [[X]], [[Y]]
+; CHECK-NEXT: [[R:%.*]] = select i1 [[LT]], i8 -1, i8 [[NE]]
+; CHECK-NEXT: ret i8 [[R]]
+;
+ %ne_bool = icmp eq i32 %x, %y
+ %ne = zext i1 %ne_bool to i8
+ %lt = icmp ult i32 %x, %y
+ %r = select i1 %lt, i8 -1, i8 %ne
+ ret i8 %r
+}
+
+define i8 @ucmp_from_select_neg2(i32 %x, i32 %y) {
+; CHECK-LABEL: define i8 @ucmp_from_select_neg2(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[NE_BOOL:%.*]] = icmp ne i32 [[Y]], [[X]]
+; CHECK-NEXT: [[NE:%.*]] = zext i1 [[NE_BOOL]] to i8
+; CHECK-NEXT: [[LT:%.*]] = icmp ult i32 [[X]], [[Y]]
+; CHECK-NEXT: [[R:%.*]] = select i1 [[LT]], i8 -1, i8 [[NE]]
+; CHECK-NEXT: ret i8 [[R]]
+;
+ %ne_bool = icmp ne i32 %y, %x
+ %ne = zext i1 %ne_bool to i8
+ %lt = icmp ult i32 %x, %y
+ %r = select i1 %lt, i8 -1, i8 %ne
+ ret i8 %r
+}
+
+; Negative test: true value of select is not -1
+define i8 @ucmp_from_select_neg3(i32 %x, i32 %y) {
+; CHECK-LABEL: define i8 @ucmp_from_select_neg3(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[NE_BOOL:%.*]] = icmp ne i32 [[X]], [[Y]]
+; CHECK-NEXT: [[NE:%.*]] = zext i1 [[NE_BOOL]] to i8
+; CHECK-NEXT: [[LT:%.*]] = icmp ult i32 [[X]], [[Y]]
+; CHECK-NEXT: [[R:%.*]] = select i1 [[LT]], i8 2, i8 [[NE]]
+; CHECK-NEXT: ret i8 [[R]]
+;
+ %ne_bool = icmp ne i32 %x, %y
+ %ne = zext i1 %ne_bool to i8
+ %lt = icmp ult i32 %x, %y
+ %r = select i1 %lt, i8 2, i8 %ne
+ ret i8 %r
+}
+
+; Negative test: false value of select is sign-extended instead of zero-extended
+define i8 @ucmp_from_select_neg4(i32 %x, i32 %y) {
+; CHECK-LABEL: define i8 @ucmp_from_select_neg4(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[NE_BOOL:%.*]] = icmp ne i32 [[X]], [[Y]]
+; CHECK-NEXT: [[R:%.*]] = sext i1 [[NE_BOOL]] to i8
+; CHECK-NEXT: ret i8 [[R]]
+;
+ %ne_bool = icmp ne i32 %x, %y
+ %ne = sext i1 %ne_bool to i8
+ %lt = icmp ult i32 %x, %y
+ %r = select i1 %lt, i8 -1, i8 %ne
+ ret i8 %r
+}
+
+; Negative test: condition of select is not (x s< y)
+define i8 @ucmp_from_select_neg5(i32 %x, i32 %y) {
+; CHECK-LABEL: define i8 @ucmp_from_select_neg5(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[NE_BOOL:%.*]] = icmp ne i32 [[X]], [[Y]]
+; CHECK-NEXT: [[NE:%.*]] = zext i1 [[NE_BOOL]] to i8
+; CHECK-NEXT: [[LT_NOT:%.*]] = icmp ugt i32 [[X]], [[Y]]
+; CHECK-NEXT: [[R:%.*]] = select i1 [[LT_NOT]], i8 [[NE]], i8 -1
+; CHECK-NEXT: ret i8 [[R]]
+;
+ %ne_bool = icmp ne i32 %x, %y
+ %ne = zext i1 %ne_bool to i8
+ %lt = icmp ule i32 %x, %y
+ %r = select i1 %lt, i8 -1, i8 %ne
+ ret i8 %r
+}
>From 8bb9202ee81033dac49b84b10a5363704d2dfec2 Mon Sep 17 00:00:00 2001
From: Poseydon42 <vvmposeydon at gmail.com>
Date: Mon, 29 Jul 2024 18:44:32 +0100
Subject: [PATCH 2/6] [InstCombine] Fold (x [us]< y) ? -1 : (x != y) into
[us]cmp(x, y)
---
.../InstCombine/InstCombineInternal.h | 1 +
.../InstCombine/InstCombineSelect.cpp | 35 +++++++++++++++++++
2 files changed, 36 insertions(+)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
index 64fbcc80e0edf..19d27e277bfda 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
+++ b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h
@@ -731,6 +731,7 @@ class LLVM_LIBRARY_VISIBILITY InstCombinerImpl final
// Helpers of visitSelectInst().
Instruction *foldSelectOfBools(SelectInst &SI);
+ Instruction *foldSelectToCmp(SelectInst &SI);
Instruction *foldSelectExtConst(SelectInst &Sel);
Instruction *foldSelectOpOp(SelectInst &SI, Instruction *TI, Instruction *FI);
Instruction *foldSelectIntoOp(SelectInst &SI, Value *, Value *);
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index aaf4ece3249a2..a6815f92955b0 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -3529,6 +3529,38 @@ static Instruction *foldBitCeil(SelectInst &SI, IRBuilderBase &Builder) {
Masked);
}
+// This function tries to fold the following sequence
+// %lt = icmp ult/slt i32 %x, %y
+// %ne0 = icmp ne i32 %x, %y
+// %ne = zext i1 %ne0 to iN
+// %r = select i1 %lt, iN -1, iN %ne
+// into
+// %r = call iN @llvm.ucmp/scmp(%x, %y)
+Instruction *InstCombinerImpl::foldSelectToCmp(SelectInst &SI) {
+ if (!isa<ConstantInt>(SI.getTrueValue()) ||
+ !dyn_cast<ConstantInt>(SI.getTrueValue())->isAllOnesValue())
+ return nullptr;
+
+ Value *LHS, *RHS;
+ ICmpInst::Predicate NEPred;
+ if (!match(SI.getFalseValue(),
+ m_ZExt(m_ICmp(NEPred, m_Value(LHS), m_Value(RHS)))) ||
+ NEPred != ICmpInst::ICMP_NE)
+ return nullptr;
+
+ ICmpInst::Predicate LTPred;
+ if (!match(SI.getCondition(),
+ m_ICmp(LTPred, m_Specific(LHS), m_Specific(RHS))) ||
+ !ICmpInst::isLT(LTPred))
+ return nullptr;
+
+ bool IsSigned = ICmpInst::isSigned(LTPred);
+ Instruction *Result = Builder.CreateIntrinsic(
+ SI.getFalseValue()->getType(),
+ IsSigned ? Intrinsic::scmp : Intrinsic::ucmp, {LHS, RHS});
+ return replaceInstUsesWith(SI, Result);
+}
+
bool InstCombinerImpl::fmulByZeroIsZero(Value *MulVal, FastMathFlags FMF,
const Instruction *CtxI) const {
KnownFPClass Known = computeKnownFPClass(MulVal, FMF, fcNegative, CtxI);
@@ -4111,5 +4143,8 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
}
}
+ if (auto *Instruction = foldSelectToCmp(SI))
+ return Instruction;
+
return nullptr;
}
>From e7ceb669dd7e8c94314448c0c8bc01a70dfa02a2 Mon Sep 17 00:00:00 2001
From: Poseydon42 <vvmposeydon at gmail.com>
Date: Mon, 29 Jul 2024 18:47:11 +0100
Subject: [PATCH 3/6] Update tests
---
llvm/test/Transforms/InstCombine/scmp.ll | 5 +----
llvm/test/Transforms/InstCombine/ucmp.ll | 5 +----
2 files changed, 2 insertions(+), 8 deletions(-)
diff --git a/llvm/test/Transforms/InstCombine/scmp.ll b/llvm/test/Transforms/InstCombine/scmp.ll
index 53ab819a7d340..5ae7970499fa7 100644
--- a/llvm/test/Transforms/InstCombine/scmp.ll
+++ b/llvm/test/Transforms/InstCombine/scmp.ll
@@ -188,10 +188,7 @@ define i8 @scmp_negated_multiuse(i32 %x, i32 %y) {
define i8 @scmp_from_select(i32 %x, i32 %y) {
; CHECK-LABEL: define i8 @scmp_from_select(
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
-; CHECK-NEXT: [[NE_BOOL:%.*]] = icmp ne i32 [[X]], [[Y]]
-; CHECK-NEXT: [[NE:%.*]] = zext i1 [[NE_BOOL]] to i8
-; CHECK-NEXT: [[LT:%.*]] = icmp slt i32 [[X]], [[Y]]
-; CHECK-NEXT: [[R:%.*]] = select i1 [[LT]], i8 -1, i8 [[NE]]
+; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[X]], i32 [[Y]])
; CHECK-NEXT: ret i8 [[R]]
;
%ne_bool = icmp ne i32 %x, %y
diff --git a/llvm/test/Transforms/InstCombine/ucmp.ll b/llvm/test/Transforms/InstCombine/ucmp.ll
index 08eab78d2eacb..f7ce432885616 100644
--- a/llvm/test/Transforms/InstCombine/ucmp.ll
+++ b/llvm/test/Transforms/InstCombine/ucmp.ll
@@ -188,10 +188,7 @@ define i8 @ucmp_negated_multiuse(i32 %x, i32 %y) {
define i8 @ucmp_from_select(i32 %x, i32 %y) {
; CHECK-LABEL: define i8 @ucmp_from_select(
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
-; CHECK-NEXT: [[NE_BOOL:%.*]] = icmp ne i32 [[X]], [[Y]]
-; CHECK-NEXT: [[NE:%.*]] = zext i1 [[NE_BOOL]] to i8
-; CHECK-NEXT: [[LT:%.*]] = icmp ult i32 [[X]], [[Y]]
-; CHECK-NEXT: [[R:%.*]] = select i1 [[LT]], i8 -1, i8 [[NE]]
+; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[X]], i32 [[Y]])
; CHECK-NEXT: ret i8 [[R]]
;
%ne_bool = icmp ne i32 %x, %y
>From c597f49a33efcd926f03976a6a51fe94ee6d9cc2 Mon Sep 17 00:00:00 2001
From: Poseydon42 <vvmposeydon at gmail.com>
Date: Mon, 29 Jul 2024 19:19:21 +0100
Subject: [PATCH 4/6] Add support for vector types
---
llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp | 4 ++--
llvm/test/Transforms/InstCombine/scmp.ll | 9 +++++++++
llvm/test/Transforms/InstCombine/ucmp.ll | 9 +++++++++
3 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index a6815f92955b0..be65342c2c058 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -3537,8 +3537,8 @@ static Instruction *foldBitCeil(SelectInst &SI, IRBuilderBase &Builder) {
// into
// %r = call iN @llvm.ucmp/scmp(%x, %y)
Instruction *InstCombinerImpl::foldSelectToCmp(SelectInst &SI) {
- if (!isa<ConstantInt>(SI.getTrueValue()) ||
- !dyn_cast<ConstantInt>(SI.getTrueValue())->isAllOnesValue())
+ if (!isa<Constant>(SI.getTrueValue()) ||
+ !dyn_cast<Constant>(SI.getTrueValue())->isAllOnesValue())
return nullptr;
Value *LHS, *RHS;
diff --git a/llvm/test/Transforms/InstCombine/scmp.ll b/llvm/test/Transforms/InstCombine/scmp.ll
index 5ae7970499fa7..df5e6691ef407 100644
--- a/llvm/test/Transforms/InstCombine/scmp.ll
+++ b/llvm/test/Transforms/InstCombine/scmp.ll
@@ -198,6 +198,15 @@ define i8 @scmp_from_select(i32 %x, i32 %y) {
ret i8 %r
}
+; Vector version
+define <4 x i8> @scmp_from_select_vec(<4 x i32> %x, <4 x i32> %y) {
+ %ne_bool = icmp ne <4 x i32> %x, %y
+ %ne = zext <4 x i1> %ne_bool to <4 x i8>
+ %lt = icmp slt <4 x i32> %x, %y
+ %r = select <4 x i1> %lt, <4 x i8> splat(i8 -1), <4 x i8> %ne
+ ret <4 x i8> %r
+}
+
; Negative test: false value of the select is not `icmp ne x, y`
define i8 @scmp_from_select_neg1(i32 %x, i32 %y) {
; CHECK-LABEL: define i8 @scmp_from_select_neg1(
diff --git a/llvm/test/Transforms/InstCombine/ucmp.ll b/llvm/test/Transforms/InstCombine/ucmp.ll
index f7ce432885616..38ece55f37f63 100644
--- a/llvm/test/Transforms/InstCombine/ucmp.ll
+++ b/llvm/test/Transforms/InstCombine/ucmp.ll
@@ -198,6 +198,15 @@ define i8 @ucmp_from_select(i32 %x, i32 %y) {
ret i8 %r
}
+; Vector version
+define <4 x i8> @ucmp_from_select_vec(<4 x i32> %x, <4 x i32> %y) {
+ %ne_bool = icmp ne <4 x i32> %x, %y
+ %ne = zext <4 x i1> %ne_bool to <4 x i8>
+ %lt = icmp ult <4 x i32> %x, %y
+ %r = select <4 x i1> %lt, <4 x i8> splat(i8 -1), <4 x i8> %ne
+ ret <4 x i8> %r
+}
+
; Negative test: false value of the select is not `icmp ne x, y`
define i8 @ucmp_from_select_neg1(i32 %x, i32 %y) {
; CHECK-LABEL: define i8 @ucmp_from_select_neg1(
>From 7de0031aa0efc9e9f65fd3e7aa31e89a76488f99 Mon Sep 17 00:00:00 2001
From: Poseydon42 <vvmposeydon at gmail.com>
Date: Mon, 29 Jul 2024 19:19:40 +0100
Subject: [PATCH 5/6] Update existing tests
---
llvm/test/Transforms/InstCombine/select-select.ll | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/llvm/test/Transforms/InstCombine/select-select.ll b/llvm/test/Transforms/InstCombine/select-select.ll
index 84fe973093e32..36b1e50ab1160 100644
--- a/llvm/test/Transforms/InstCombine/select-select.ll
+++ b/llvm/test/Transforms/InstCombine/select-select.ll
@@ -282,10 +282,7 @@ define i8 @strong_order_cmp_ugt_eq(i32 %a, i32 %b) {
define i8 @strong_order_cmp_eq_slt(i32 %a, i32 %b) {
; CHECK-LABEL: @strong_order_cmp_eq_slt(
-; CHECK-NEXT: [[CMP_EQ:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT: [[SEL_EQ:%.*]] = zext i1 [[CMP_EQ]] to i8
-; CHECK-NEXT: [[CMP_LT:%.*]] = icmp slt i32 [[A]], [[B]]
-; CHECK-NEXT: [[SEL_LT:%.*]] = select i1 [[CMP_LT]], i8 -1, i8 [[SEL_EQ]]
+; CHECK-NEXT: [[SEL_LT:%.*]] = call i8 @llvm.scmp.i8.i32(i32 [[A:%.*]], i32 [[B:%.*]])
; CHECK-NEXT: ret i8 [[SEL_LT]]
;
%cmp.eq = icmp eq i32 %a, %b
@@ -312,10 +309,7 @@ define i8 @strong_order_cmp_eq_sgt(i32 %a, i32 %b) {
define i8 @strong_order_cmp_eq_ult(i32 %a, i32 %b) {
; CHECK-LABEL: @strong_order_cmp_eq_ult(
-; CHECK-NEXT: [[CMP_EQ:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT: [[SEL_EQ:%.*]] = zext i1 [[CMP_EQ]] to i8
-; CHECK-NEXT: [[CMP_LT:%.*]] = icmp ult i32 [[A]], [[B]]
-; CHECK-NEXT: [[SEL_LT:%.*]] = select i1 [[CMP_LT]], i8 -1, i8 [[SEL_EQ]]
+; CHECK-NEXT: [[SEL_LT:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A:%.*]], i32 [[B:%.*]])
; CHECK-NEXT: ret i8 [[SEL_LT]]
;
%cmp.eq = icmp eq i32 %a, %b
>From 176f3b04a45eac11ca9899e243f6f8eecda079fb Mon Sep 17 00:00:00 2001
From: Poseydon42 <vvmposeydon at gmail.com>
Date: Mon, 29 Jul 2024 19:22:12 +0100
Subject: [PATCH 6/6] Move the fold up
---
llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index be65342c2c058..9c77d624d62af 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -4064,6 +4064,9 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
if (Instruction *I = foldBitCeil(SI, Builder))
return I;
+ if (Instruction *I = foldSelectToCmp(SI))
+ return I;
+
// Fold:
// (select A && B, T, F) -> (select A, (select B, T, F), F)
// (select A || B, T, F) -> (select A, T, (select B, T, F))
@@ -4143,8 +4146,5 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
}
}
- if (auto *Instruction = foldSelectToCmp(SI))
- return Instruction;
-
return nullptr;
}
More information about the llvm-commits
mailing list