-
Notifications
You must be signed in to change notification settings - Fork 14.5k
[InstCombine] Fold icmp eq/ne min|max(X, Y), Z
#67087
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-llvm-transforms ChangesThis patch further improves the simplification of pattern Alive2: https://alive2.llvm.org/ce/z/evkmaq Full diff: https://github.com/llvm/llvm-project/pull/67087.diff 6 Files Affected:
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index a219dac7acfbe16..a9fe9efeab55474 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -5022,6 +5022,12 @@ InstCombinerImpl::foldICmpWithMinMaxImpl(Instruction &I,
std::swap(CmpXZ, CmpYZ);
}
+ auto FoldIntoCmpYZ = [&]() -> Instruction * {
+ if (CmpYZ.has_value())
+ return replaceInstUsesWith(I, ConstantInt::getBool(I.getType(), *CmpYZ));
+ return ICmpInst::Create(Instruction::ICmp, Pred, Y, Z);
+ };
+
switch (Pred) {
case ICmpInst::ICMP_EQ:
case ICmpInst::ICMP_NE: {
@@ -5031,6 +5037,7 @@ InstCombinerImpl::foldICmpWithMinMaxImpl(Instruction &I,
// max(X, Y) == Z X >= Y
// min(X, Y) != Z X > Y
// max(X, Y) != Z X < Y
+
if ((Pred == ICmpInst::ICMP_EQ) == *CmpXZ) {
ICmpInst::Predicate NewPred =
ICmpInst::getNonStrictPredicate(MinMax->getPredicate());
@@ -5038,12 +5045,32 @@ InstCombinerImpl::foldICmpWithMinMaxImpl(Instruction &I,
NewPred = ICmpInst::getInversePredicate(NewPred);
return ICmpInst::Create(Instruction::ICmp, NewPred, X, Y);
}
- // Otherwise (X != Z, nofold):
- // Expr Result
- // min(X, Y) == Z X > Y || Y == Z
- // max(X, Y) == Z X < Y || Y == Z
- // min(X, Y) != Z X <= Y && Y != Z
- // max(X, Y) != Z X >= Y && Y != Z
+ // Otherwise (X != Z):
+ ICmpInst::Predicate NewPred = MinMax->getPredicate();
+ auto NewCmpXZ = IsCondKnownTrue(simplifyICmpInst(NewPred, X, Z, Q));
+ if (!NewCmpXZ.has_value()) {
+ std::swap(X, Y);
+ std::swap(CmpXZ, CmpYZ);
+ NewCmpXZ = IsCondKnownTrue(simplifyICmpInst(NewPred, X, Z, Q));
+ }
+ if (!NewCmpXZ.has_value())
+ break;
+ if (*NewCmpXZ) {
+ // Expr Fact Result
+ // min(X, Y) == Z X < Z false
+ // max(X, Y) == Z X > Z false
+ // min(X, Y) != Z X < Z true
+ // max(X, Y) != Z X > Z true
+ return replaceInstUsesWith(
+ I, ConstantInt::getBool(I.getType(), Pred == ICmpInst::ICMP_NE));
+ } else {
+ // Expr Fact Result
+ // min(X, Y) == Z X > Z Y == Z
+ // max(X, Y) == Z X < Z Y == Z
+ // min(X, Y) != Z X > Z Y != Z
+ // max(X, Y) != Z X < Z Y != Z
+ return FoldIntoCmpYZ();
+ }
break;
}
case ICmpInst::ICMP_SLT:
@@ -5054,13 +5081,6 @@ InstCombinerImpl::foldICmpWithMinMaxImpl(Instruction &I,
case ICmpInst::ICMP_UGT:
case ICmpInst::ICMP_SGE:
case ICmpInst::ICMP_UGE: {
- auto FoldIntoCmpYZ = [&]() -> Instruction * {
- if (CmpYZ.has_value())
- return replaceInstUsesWith(I,
- ConstantInt::getBool(I.getType(), *CmpYZ));
- return ICmpInst::Create(Instruction::ICmp, Pred, Y, Z);
- };
-
bool IsSame = MinMax->getPredicate() == ICmpInst::getStrictPredicate(Pred);
if (*CmpXZ) {
if (IsSame) {
diff --git a/llvm/test/Transforms/InstCombine/pr21199.ll b/llvm/test/Transforms/InstCombine/pr21199.ll
index 54389768f1f9b55..7c31638f369fa61 100644
--- a/llvm/test/Transforms/InstCombine/pr21199.ll
+++ b/llvm/test/Transforms/InstCombine/pr21199.ll
@@ -10,7 +10,7 @@ define void @test(i32 %len) {
; CHECK-LABEL: @test(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.umin.i32(i32 [[LEN:%.*]], i32 8)
-; CHECK-NEXT: [[CMP11_NOT:%.*]] = icmp eq i32 [[COND]], 0
+; CHECK-NEXT: [[CMP11_NOT:%.*]] = icmp eq i32 [[LEN]], 0
; CHECK-NEXT: br i1 [[CMP11_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY:%.*]]
; CHECK: for.body:
; CHECK-NEXT: [[I_02:%.*]] = phi i32 [ [[INC:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
diff --git a/llvm/test/Transforms/InstCombine/smax-icmp.ll b/llvm/test/Transforms/InstCombine/smax-icmp.ll
index f8df92d5470e19d..0ccbef34889fda6 100644
--- a/llvm/test/Transforms/InstCombine/smax-icmp.ll
+++ b/llvm/test/Transforms/InstCombine/smax-icmp.ll
@@ -370,9 +370,9 @@ define void @slt_smax_contextual(i32 %x, i32 %y, i32 %z) {
; CHECK-NEXT: call void @use(i1 [[CMP7]])
; CHECK-NEXT: [[CMP8:%.*]] = icmp uge i32 [[COND]], [[Z]]
; CHECK-NEXT: call void @use(i1 [[CMP8]])
-; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[COND]], [[Z]]
+; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[Y]], [[Z]]
; CHECK-NEXT: call void @use(i1 [[CMP9]])
-; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[COND]], [[Z]]
+; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[Y]], [[Z]]
; CHECK-NEXT: call void @use(i1 [[CMP10]])
; CHECK-NEXT: ret void
; CHECK: end:
@@ -429,9 +429,9 @@ define void @slt_smax_contextual_commuted(i32 %x, i32 %y, i32 %z) {
; CHECK-NEXT: call void @use(i1 [[CMP7]])
; CHECK-NEXT: [[CMP8:%.*]] = icmp uge i32 [[COND]], [[Z]]
; CHECK-NEXT: call void @use(i1 [[CMP8]])
-; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[COND]], [[Z]]
+; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[Y]], [[Z]]
; CHECK-NEXT: call void @use(i1 [[CMP9]])
-; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[COND]], [[Z]]
+; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[Y]], [[Z]]
; CHECK-NEXT: call void @use(i1 [[CMP10]])
; CHECK-NEXT: ret void
; CHECK: end:
@@ -602,10 +602,8 @@ define void @sgt_smax_contextual(i32 %x, i32 %y, i32 %z) {
; CHECK-NEXT: call void @use(i1 [[CMP7]])
; CHECK-NEXT: [[CMP8:%.*]] = icmp uge i32 [[COND]], [[Z]]
; CHECK-NEXT: call void @use(i1 [[CMP8]])
-; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[COND]], [[Z]]
-; CHECK-NEXT: call void @use(i1 [[CMP9]])
-; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[COND]], [[Z]]
-; CHECK-NEXT: call void @use(i1 [[CMP10]])
+; CHECK-NEXT: call void @use(i1 false)
+; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: ret void
; CHECK: end:
; CHECK-NEXT: ret void
@@ -657,10 +655,8 @@ define void @sgt_smax_contextual_commuted(i32 %x, i32 %y, i32 %z) {
; CHECK-NEXT: call void @use(i1 [[CMP7]])
; CHECK-NEXT: [[CMP8:%.*]] = icmp uge i32 [[COND]], [[Z]]
; CHECK-NEXT: call void @use(i1 [[CMP8]])
-; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[COND]], [[Z]]
-; CHECK-NEXT: call void @use(i1 [[CMP9]])
-; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[COND]], [[Z]]
-; CHECK-NEXT: call void @use(i1 [[CMP10]])
+; CHECK-NEXT: call void @use(i1 false)
+; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: ret void
; CHECK: end:
; CHECK-NEXT: ret void
diff --git a/llvm/test/Transforms/InstCombine/smin-icmp.ll b/llvm/test/Transforms/InstCombine/smin-icmp.ll
index 244dad451022ea6..00fe5a1efe69309 100644
--- a/llvm/test/Transforms/InstCombine/smin-icmp.ll
+++ b/llvm/test/Transforms/InstCombine/smin-icmp.ll
@@ -465,10 +465,8 @@ define void @slt_smin_contextual(i32 %x, i32 %y, i32 %z) {
; CHECK-NEXT: call void @use(i1 [[CMP7]])
; CHECK-NEXT: [[CMP8:%.*]] = icmp uge i32 [[COND]], [[Z]]
; CHECK-NEXT: call void @use(i1 [[CMP8]])
-; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[COND]], [[Z]]
-; CHECK-NEXT: call void @use(i1 [[CMP9]])
-; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[COND]], [[Z]]
-; CHECK-NEXT: call void @use(i1 [[CMP10]])
+; CHECK-NEXT: call void @use(i1 false)
+; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: ret void
; CHECK: end:
; CHECK-NEXT: ret void
@@ -520,10 +518,8 @@ define void @slt_smin_contextual_commuted(i32 %x, i32 %y, i32 %z) {
; CHECK-NEXT: call void @use(i1 [[CMP7]])
; CHECK-NEXT: [[CMP8:%.*]] = icmp uge i32 [[COND]], [[Z]]
; CHECK-NEXT: call void @use(i1 [[CMP8]])
-; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[COND]], [[Z]]
-; CHECK-NEXT: call void @use(i1 [[CMP9]])
-; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[COND]], [[Z]]
-; CHECK-NEXT: call void @use(i1 [[CMP10]])
+; CHECK-NEXT: call void @use(i1 false)
+; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: ret void
; CHECK: end:
; CHECK-NEXT: ret void
@@ -693,9 +689,9 @@ define void @sgt_smin_contextual(i32 %x, i32 %y, i32 %z) {
; CHECK-NEXT: call void @use(i1 [[CMP7]])
; CHECK-NEXT: [[CMP8:%.*]] = icmp uge i32 [[COND]], [[Z]]
; CHECK-NEXT: call void @use(i1 [[CMP8]])
-; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[COND]], [[Z]]
+; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[Y]], [[Z]]
; CHECK-NEXT: call void @use(i1 [[CMP9]])
-; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[COND]], [[Z]]
+; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[Y]], [[Z]]
; CHECK-NEXT: call void @use(i1 [[CMP10]])
; CHECK-NEXT: ret void
; CHECK: end:
@@ -752,9 +748,9 @@ define void @sgt_smin_contextual_commuted(i32 %x, i32 %y, i32 %z) {
; CHECK-NEXT: call void @use(i1 [[CMP7]])
; CHECK-NEXT: [[CMP8:%.*]] = icmp uge i32 [[COND]], [[Z]]
; CHECK-NEXT: call void @use(i1 [[CMP8]])
-; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[COND]], [[Z]]
+; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[Y]], [[Z]]
; CHECK-NEXT: call void @use(i1 [[CMP9]])
-; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[COND]], [[Z]]
+; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[Y]], [[Z]]
; CHECK-NEXT: call void @use(i1 [[CMP10]])
; CHECK-NEXT: ret void
; CHECK: end:
@@ -1117,9 +1113,9 @@ define void @sgt_smin_v2i32_constant(<2 x i32> %y) {
; CHECK-NEXT: call void @use_v2i1(<2 x i1> [[CMP7]])
; CHECK-NEXT: [[CMP8:%.*]] = icmp ugt <2 x i32> [[COND]], <i32 9, i32 9>
; CHECK-NEXT: call void @use_v2i1(<2 x i1> [[CMP8]])
-; CHECK-NEXT: [[CMP9:%.*]] = icmp eq <2 x i32> [[COND]], <i32 10, i32 10>
+; CHECK-NEXT: [[CMP9:%.*]] = icmp eq <2 x i32> [[Y]], <i32 10, i32 10>
; CHECK-NEXT: call void @use_v2i1(<2 x i1> [[CMP9]])
-; CHECK-NEXT: [[CMP10:%.*]] = icmp ne <2 x i32> [[COND]], <i32 10, i32 10>
+; CHECK-NEXT: [[CMP10:%.*]] = icmp ne <2 x i32> [[Y]], <i32 10, i32 10>
; CHECK-NEXT: call void @use_v2i1(<2 x i1> [[CMP10]])
; CHECK-NEXT: ret void
;
diff --git a/llvm/test/Transforms/InstCombine/umax-icmp.ll b/llvm/test/Transforms/InstCombine/umax-icmp.ll
index d6706374c49897c..9946f3c390f0f38 100644
--- a/llvm/test/Transforms/InstCombine/umax-icmp.ll
+++ b/llvm/test/Transforms/InstCombine/umax-icmp.ll
@@ -370,9 +370,9 @@ define void @ult_umax_contextual(i32 %x, i32 %y, i32 %z) {
; CHECK-NEXT: call void @use(i1 [[CMP7]])
; CHECK-NEXT: [[CMP8:%.*]] = icmp uge i32 [[Y]], [[Z]]
; CHECK-NEXT: call void @use(i1 [[CMP8]])
-; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[COND]], [[Z]]
+; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[Y]], [[Z]]
; CHECK-NEXT: call void @use(i1 [[CMP9]])
-; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[COND]], [[Z]]
+; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[Y]], [[Z]]
; CHECK-NEXT: call void @use(i1 [[CMP10]])
; CHECK-NEXT: ret void
; CHECK: end:
@@ -429,9 +429,9 @@ define void @ult_umax_contextual_commuted(i32 %x, i32 %y, i32 %z) {
; CHECK-NEXT: call void @use(i1 [[CMP7]])
; CHECK-NEXT: [[CMP8:%.*]] = icmp uge i32 [[Y]], [[Z]]
; CHECK-NEXT: call void @use(i1 [[CMP8]])
-; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[COND]], [[Z]]
+; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[Y]], [[Z]]
; CHECK-NEXT: call void @use(i1 [[CMP9]])
-; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[COND]], [[Z]]
+; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[Y]], [[Z]]
; CHECK-NEXT: call void @use(i1 [[CMP10]])
; CHECK-NEXT: ret void
; CHECK: end:
@@ -602,10 +602,8 @@ define void @ugt_umax_contextual(i32 %x, i32 %y, i32 %z) {
; CHECK-NEXT: call void @use(i1 false)
; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: call void @use(i1 true)
-; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[COND]], [[Z]]
-; CHECK-NEXT: call void @use(i1 [[CMP9]])
-; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[COND]], [[Z]]
-; CHECK-NEXT: call void @use(i1 [[CMP10]])
+; CHECK-NEXT: call void @use(i1 false)
+; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: ret void
; CHECK: end:
; CHECK-NEXT: ret void
@@ -657,10 +655,8 @@ define void @ugt_umax_contextual_commuted(i32 %x, i32 %y, i32 %z) {
; CHECK-NEXT: call void @use(i1 false)
; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: call void @use(i1 true)
-; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[COND]], [[Z]]
-; CHECK-NEXT: call void @use(i1 [[CMP9]])
-; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[COND]], [[Z]]
-; CHECK-NEXT: call void @use(i1 [[CMP10]])
+; CHECK-NEXT: call void @use(i1 false)
+; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: ret void
; CHECK: end:
; CHECK-NEXT: ret void
diff --git a/llvm/test/Transforms/InstCombine/umin-icmp.ll b/llvm/test/Transforms/InstCombine/umin-icmp.ll
index 88a391bf18ca13e..da901c6c5e4847f 100644
--- a/llvm/test/Transforms/InstCombine/umin-icmp.ll
+++ b/llvm/test/Transforms/InstCombine/umin-icmp.ll
@@ -366,10 +366,8 @@ define void @ult_umin_contextual(i32 %x, i32 %y, i32 %z) {
; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: call void @use(i1 false)
; CHECK-NEXT: call void @use(i1 false)
-; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[COND]], [[Z]]
-; CHECK-NEXT: call void @use(i1 [[CMP9]])
-; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[COND]], [[Z]]
-; CHECK-NEXT: call void @use(i1 [[CMP10]])
+; CHECK-NEXT: call void @use(i1 false)
+; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: ret void
; CHECK: end:
; CHECK-NEXT: ret void
@@ -421,10 +419,8 @@ define void @ult_umin_contextual_commuted(i32 %x, i32 %y, i32 %z) {
; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: call void @use(i1 false)
; CHECK-NEXT: call void @use(i1 false)
-; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[COND]], [[Z]]
-; CHECK-NEXT: call void @use(i1 [[CMP9]])
-; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[COND]], [[Z]]
-; CHECK-NEXT: call void @use(i1 [[CMP10]])
+; CHECK-NEXT: call void @use(i1 false)
+; CHECK-NEXT: call void @use(i1 true)
; CHECK-NEXT: ret void
; CHECK: end:
; CHECK-NEXT: ret void
@@ -594,9 +590,9 @@ define void @ugt_umin_contextual(i32 %x, i32 %y, i32 %z) {
; CHECK-NEXT: call void @use(i1 [[CMP7]])
; CHECK-NEXT: [[CMP8:%.*]] = icmp uge i32 [[Y]], [[Z]]
; CHECK-NEXT: call void @use(i1 [[CMP8]])
-; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[COND]], [[Z]]
+; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[Y]], [[Z]]
; CHECK-NEXT: call void @use(i1 [[CMP9]])
-; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[COND]], [[Z]]
+; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[Y]], [[Z]]
; CHECK-NEXT: call void @use(i1 [[CMP10]])
; CHECK-NEXT: ret void
; CHECK: end:
@@ -653,9 +649,9 @@ define void @ugt_umin_contextual_commuted(i32 %x, i32 %y, i32 %z) {
; CHECK-NEXT: call void @use(i1 [[CMP7]])
; CHECK-NEXT: [[CMP8:%.*]] = icmp uge i32 [[Y]], [[Z]]
; CHECK-NEXT: call void @use(i1 [[CMP8]])
-; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[COND]], [[Z]]
+; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[Y]], [[Z]]
; CHECK-NEXT: call void @use(i1 [[CMP9]])
-; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[COND]], [[Z]]
+; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[Y]], [[Z]]
; CHECK-NEXT: call void @use(i1 [[CMP10]])
; CHECK-NEXT: ret void
; CHECK: end:
|
f4f558e
to
598b7f0
Compare
Rename `NewCmpXZ` to `MinMaxCmpXZ`
LGTM. |
Seems this broke bootstrapping in some builds. |
Details in https://reviews.llvm.org/D156238 This reverts commit d2abe8d.
@chapuni @vitalybuka Thank you for reverting this! I am investigating the regression. |
This patch further improves the simplification of pattern `icmp eq/ne min|max(X, Y), Z` as discussed in [D156238](https://reviews.llvm.org/D156238). When `X < Z`: `min(X, Y) == Z -> false` `min(X, Y) != Z -> true` `max(X, Y) == Z -> Y == Z` `max(Y, Z) != Z -> Y != Z` When `X > Z`: `max(X, Y) == Z -> false` `max(X, Y) != Z -> true` `min(X, Y) == Z -> Y == Z` `min(Y, Z) != Z -> Y != Z` Alive2: https://alive2.llvm.org/ce/z/evkmaq
Relanded as 416e891 |
Local branch amd-gfx b38cf8a Merged main:2c3cae3f01b1 into amd-gfx:a0afca49984f Remote branch main 4c1c96e Revert "[InstCombine] Fold `icmp eq/ne min|max(X, Y), Z` (llvm#67087)"
This patch further improves the simplification of pattern
icmp eq/ne min|max(X, Y), Z
as discussed in D156238.When
X < Z
:min(X, Y) == Z -> false
min(X, Y) != Z -> true
max(X, Y) == Z -> Y == Z
max(Y, Z) != Z -> Y != Z
When
X > Z
:max(X, Y) == Z -> false
max(X, Y) != Z -> true
min(X, Y) == Z -> Y == Z
min(Y, Z) != Z -> Y != Z
Alive2: https://alive2.llvm.org/ce/z/evkmaq