[llvm] [InstCombine] Fold icmp eq (and X, 1), 0 --> xor (trunc X to i1) (PR #219320)
Rohan Jha via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 1 13:58:05 PDT 2026
https://github.com/rohan11235813 updated https://github.com/llvm/llvm-project/pull/219320
>From 52b8e52bb2b92622543780826e1f676eaa637a69 Mon Sep 17 00:00:00 2001
From: rohan11235813 <rohanj at quadric.io>
Date: Thu, 27 Aug 2026 15:03:56 -0700
Subject: [PATCH 1/2] [InstCombine] Fold icmp eq (and X, 1), 0 --> xor (trunc X
to i1)
---
.../InstCombine/InstCombineCompares.cpp | 7 ++
.../Transforms/InstCombine/icmp-of-and-x.ll | 66 +++++++++++++++++++
2 files changed, 73 insertions(+)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 72f08b398e45d..bfa0441f5e553 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -1813,6 +1813,13 @@ Instruction *InstCombinerImpl::foldICmpAndConstConst(ICmpInst &Cmp,
const APInt &C1) {
bool isICMP_NE = Cmp.getPredicate() == ICmpInst::ICMP_NE;
+ // icmp eq (and X, 1), 0 --> not (trunc X to i1)
+ if (Cmp.getPredicate() == ICmpInst::ICMP_EQ && C1.isZero() &&
+ And->hasOneUse() && match(And->getOperand(1), m_One())) {
+ Value *NewTrunc = Builder.CreateTrunc(And->getOperand(0), Cmp.getType());
+ return BinaryOperator::CreateNot(NewTrunc);
+ }
+
// icmp ne (and X, 1), 0 --> trunc X to i1
if (isICMP_NE && C1.isZero() && match(And->getOperand(1), m_One()))
return new TruncInst(And->getOperand(0), Cmp.getType());
diff --git a/llvm/test/Transforms/InstCombine/icmp-of-and-x.ll b/llvm/test/Transforms/InstCombine/icmp-of-and-x.ll
index 0bcbc3bcb050b..85e33c3413b15 100644
--- a/llvm/test/Transforms/InstCombine/icmp-of-and-x.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-of-and-x.ll
@@ -300,3 +300,69 @@ define i1 @icmp_eq_x_invertable_y_fail_immconstant(i8 %x, i8 %y) {
%r = icmp eq i8 %and, 7
ret i1 %r
}
+
+define i1 @icmp_eq_and1_zero(i8 %x){
+; CHECK-LABEL: @icmp_eq_and1_zero(
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i8 [[X:%.*]] to i1
+; CHECK-NEXT: [[R:%.*]] = xor i1 [[TMP1]], true
+; CHECK-NEXT: ret i1 [[R]]
+;
+ %and = and i8 %x, 1
+ %r = icmp eq i8 %and, 0
+ ret i1 %r
+}
+
+define <2 x i1> @icmp_eq_and1_zero_vec(<2 x i8> %x){
+; CHECK-LABEL: @icmp_eq_and1_zero_vec(
+; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i8> [[X:%.*]] to <2 x i1>
+; CHECK-NEXT: [[R:%.*]] = xor <2 x i1> [[TMP1]], splat (i1 true)
+; CHECK-NEXT: ret <2 x i1> [[R]]
+;
+ %and = and <2 x i8> %x, splat (i8 1)
+ %r = icmp eq <2 x i8> %and, zeroinitializer
+ ret <2 x i1> %r
+}
+
+define i1 @icmp_ne_and1_zero(i8 %x) {
+; CHECK-LABEL: @icmp_ne_and1_zero(
+; CHECK-NEXT: [[R:%.*]] = trunc i8 [[X:%.*]] to i1
+; CHECK-NEXT: ret i1 [[R]]
+;
+ %and = and i8 %x, 1
+ %r = icmp ne i8 %and, 0
+ ret i1 %r
+}
+
+define i1 @icmp_eq_and1_zero_fail_multiuse(i8 %x) {
+; CHECK-LABEL: @icmp_eq_and1_zero_fail_multiuse(
+; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 1
+; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[AND]], 0
+; CHECK-NEXT: call void @use.i8(i8 [[AND]])
+; CHECK-NEXT: ret i1 [[R]]
+;
+ %and = and i8 %x, 1
+ %r = icmp eq i8 %and, 0
+ call void @use.i8(i8 %and)
+ ret i1 %r
+}
+
+define i1 @icmp_eq_and2_zero(i8 %x) {
+; CHECK-LABEL: @icmp_eq_and2_zero(
+; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 2
+; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[AND]], 0
+; CHECK-NEXT: ret i1 [[R]]
+;
+ %and = and i8 %x, 2
+ %r = icmp eq i8 %and, 0
+ ret i1 %r
+}
+
+define i1 @icmp_eq_and1_one(i8 %x) {
+; CHECK-LABEL: @icmp_eq_and1_one(
+; CHECK-NEXT: [[R:%.*]] = trunc i8 [[X:%.*]] to i1
+; CHECK-NEXT: ret i1 [[R]]
+;
+ %and = and i8 %x, 1
+ %r = icmp eq i8 %and, 1
+ ret i1 %r
+}
>From 0ffc94383a2c967212ad39315e2134847d702298 Mon Sep 17 00:00:00 2001
From: rohan11235813 <rohanj at quadric.io>
Date: Sat, 29 Aug 2026 14:44:38 -0700
Subject: [PATCH 2/2] [InstCombine] Regenerate test checks for icmp eq (and X,
1), 0 fold
---
.../ValueTracking/knownbits-bmi-pattern.ll | 4 +-
.../Analysis/ValueTracking/knownbits-pext.ll | 8 +-
.../Transforms/InstCombine/X86/blend_x86.ll | 3 +-
.../Transforms/InstCombine/and-or-icmps.ll | 50 +++++-----
llvm/test/Transforms/InstCombine/and.ll | 5 +-
llvm/test/Transforms/InstCombine/assume.ll | 21 +++--
.../test/Transforms/InstCombine/binop-cast.ll | 5 +-
.../Transforms/InstCombine/cmp-intrinsic.ll | 8 +-
llvm/test/Transforms/InstCombine/freeze.ll | 4 +-
.../Transforms/InstCombine/icmp-and-shift.ll | 6 +-
.../test/Transforms/InstCombine/icmp-binop.ll | 3 +-
llvm/test/Transforms/InstCombine/icmp-dom.ll | 6 +-
.../Transforms/InstCombine/icmp-logical.ll | 16 ++--
.../Transforms/InstCombine/icmp-mul-and.ll | 16 ++--
.../Transforms/InstCombine/icmp-ne-pow2.ll | 3 +-
llvm/test/Transforms/InstCombine/icmp.ll | 21 ++---
.../test/Transforms/InstCombine/or-bitmask.ll | 45 ++++-----
llvm/test/Transforms/InstCombine/pr25342.ll | 3 +-
.../Transforms/InstCombine/select-icmp-and.ll | 15 ++-
.../InstCombine/select-of-bittest.ll | 56 ++++++------
.../InstCombine/select-with-bitwise-ops.ll | 91 ++++++++-----------
llvm/test/Transforms/InstCombine/select.ll | 15 ++-
llvm/test/Transforms/InstCombine/set.ll | 10 +-
.../shift-direction-in-bit-test.ll | 17 ++--
.../InstCombine/shl-unsigned-cmp-const.ll | 4 +-
.../InstCombine/signed-truncation-check.ll | 12 +--
.../Transforms/InstCombine/zext-or-icmp.ll | 14 +--
27 files changed, 210 insertions(+), 251 deletions(-)
diff --git a/llvm/test/Analysis/ValueTracking/knownbits-bmi-pattern.ll b/llvm/test/Analysis/ValueTracking/knownbits-bmi-pattern.ll
index 868e340c266ad..c71fc80c218bc 100644
--- a/llvm/test/Analysis/ValueTracking/knownbits-bmi-pattern.ll
+++ b/llvm/test/Analysis/ValueTracking/knownbits-bmi-pattern.ll
@@ -660,8 +660,8 @@ define <2 x i32> @blsmsk_xor_no_eval_vec(<2 x i32> %x) {
define i32 @blsmsk_xor_no_eval_assume(i32 %x) {
; CHECK-LABEL: @blsmsk_xor_no_eval_assume(
-; CHECK-NEXT: [[LB:%.*]] = and i32 [[X:%.*]], 1
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[LB]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i1
+; CHECK-NEXT: [[CMP:%.*]] = xor i1 [[TMP1]], true
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
; CHECK-NEXT: [[X2:%.*]] = add i32 [[X]], -1
; CHECK-NEXT: [[X3:%.*]] = xor i32 [[X]], [[X2]]
diff --git a/llvm/test/Analysis/ValueTracking/knownbits-pext.ll b/llvm/test/Analysis/ValueTracking/knownbits-pext.ll
index 8ad80199c18de..3317e3b4a18a5 100644
--- a/llvm/test/Analysis/ValueTracking/knownbits-pext.ll
+++ b/llvm/test/Analysis/ValueTracking/knownbits-pext.ll
@@ -67,8 +67,8 @@ define <2 x i1> @pext_zero_mask_known_zero_vector(<2 x i8> %x) nounwind {
define i1 @pext_low_bits_not_known(i8 %x) nounwind {
; CHECK-LABEL: @pext_low_bits_not_known(
; CHECK-NEXT: [[PEXT:%.*]] = call i8 @llvm.pext.i8(i8 [[X:%.*]], i8 -52)
-; CHECK-NEXT: [[AND:%.*]] = and i8 [[PEXT]], 1
-; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[AND]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i8 [[PEXT]] to i1
+; CHECK-NEXT: [[R:%.*]] = xor i1 [[TMP1]], true
; CHECK-NEXT: ret i1 [[R]]
;
%pext = call i8 @llvm.pext.i8(i8 %x, i8 204)
@@ -80,8 +80,8 @@ define i1 @pext_low_bits_not_known(i8 %x) nounwind {
define <2 x i1> @pext_low_bits_not_known_vector(<2 x i8> %x) nounwind {
; CHECK-LABEL: @pext_low_bits_not_known_vector(
; CHECK-NEXT: [[PEXT:%.*]] = call <2 x i8> @llvm.pext.v2i8(<2 x i8> [[X:%.*]], <2 x i8> splat (i8 -52))
-; CHECK-NEXT: [[AND:%.*]] = and <2 x i8> [[PEXT]], splat (i8 1)
-; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i8> [[AND]], zeroinitializer
+; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i8> [[PEXT]] to <2 x i1>
+; CHECK-NEXT: [[R:%.*]] = xor <2 x i1> [[TMP1]], splat (i1 true)
; CHECK-NEXT: ret <2 x i1> [[R]]
;
%pext = call <2 x i8> @llvm.pext.v2i8(<2 x i8> %x, <2 x i8> splat (i8 -52))
diff --git a/llvm/test/Transforms/InstCombine/X86/blend_x86.ll b/llvm/test/Transforms/InstCombine/X86/blend_x86.ll
index 36479f7b4e709..d25ef658566e6 100644
--- a/llvm/test/Transforms/InstCombine/X86/blend_x86.ll
+++ b/llvm/test/Transforms/InstCombine/X86/blend_x86.ll
@@ -383,8 +383,7 @@ define <32 x i8> @shl_pblendvb_v32i8(<32 x i8> %a0, <32 x i8> %a1, <32 x i8> %a2
define <4 x float> @shl_blendvps_v4f32(<4 x float> %a0, <4 x float> %a1, <4 x i32> %a2) {
; CHECK-LABEL: @shl_blendvps_v4f32(
-; CHECK-NEXT: [[S_MASK:%.*]] = and <4 x i32> [[A2:%.*]], splat (i32 1)
-; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq <4 x i32> [[S_MASK]], zeroinitializer
+; CHECK-NEXT: [[DOTNOT:%.*]] = trunc <4 x i32> [[A2:%.*]] to <4 x i1>
; CHECK-NEXT: [[TMP1:%.*]] = select <4 x i1> [[DOTNOT]], <4 x float> [[A0:%.*]], <4 x float> [[A1:%.*]]
; CHECK-NEXT: ret <4 x float> [[TMP1]]
;
diff --git a/llvm/test/Transforms/InstCombine/and-or-icmps.ll b/llvm/test/Transforms/InstCombine/and-or-icmps.ll
index 420b963110364..63d182cd49315 100644
--- a/llvm/test/Transforms/InstCombine/and-or-icmps.ll
+++ b/llvm/test/Transforms/InstCombine/and-or-icmps.ll
@@ -1761,7 +1761,7 @@ define i1 @bitwise_or_bitwise_or_icmps_comm2(i8 %x, i8 %y, i8 %z) {
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[X:%.*]], [[TMP1]]
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i8 [[TMP2]], [[TMP1]]
-; CHECK-NEXT: [[OR2:%.*]] = or i1 [[TMP3]], [[C1]]
+; CHECK-NEXT: [[OR2:%.*]] = or i1 [[C1]], [[TMP3]]
; CHECK-NEXT: ret i1 [[OR2]]
;
%c1 = icmp eq i8 %y, 42
@@ -1782,7 +1782,7 @@ define i1 @bitwise_or_bitwise_or_icmps_comm3(i8 %x, i8 %y, i8 %z) {
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[X:%.*]], [[TMP1]]
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i8 [[TMP2]], [[TMP1]]
-; CHECK-NEXT: [[OR2:%.*]] = or i1 [[TMP3]], [[C1]]
+; CHECK-NEXT: [[OR2:%.*]] = or i1 [[C1]], [[TMP3]]
; CHECK-NEXT: ret i1 [[OR2]]
;
%c1 = icmp eq i8 %y, 42
@@ -1883,10 +1883,10 @@ define i1 @bitwise_or_logical_or_icmps_comm3(i8 %x, i8 %y, i8 %z) {
define i1 @logical_or_bitwise_or_icmps(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @logical_or_bitwise_or_icmps(
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
-; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1
; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
-; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[X]], [[Z_SHIFT]]
-; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[X_M1]], 0
+; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[X:%.*]], [[Z_SHIFT]]
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i8 [[X]] to i1
+; CHECK-NEXT: [[C2:%.*]] = xor i1 [[TMP1]], true
; CHECK-NEXT: [[C3:%.*]] = icmp eq i8 [[X_M2]], 0
; CHECK-NEXT: [[OR1:%.*]] = or i1 [[C1]], [[C2]]
; CHECK-NEXT: [[OR2:%.*]] = select i1 [[OR1]], i1 true, i1 [[C3]]
@@ -1906,10 +1906,10 @@ define i1 @logical_or_bitwise_or_icmps(i8 %x, i8 %y, i8 %z) {
define i1 @logical_or_bitwise_or_icmps_comm1(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @logical_or_bitwise_or_icmps_comm1(
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
-; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1
; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
-; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[X]], [[Z_SHIFT]]
-; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[X_M1]], 0
+; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[X:%.*]], [[Z_SHIFT]]
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i8 [[X]] to i1
+; CHECK-NEXT: [[C2:%.*]] = xor i1 [[TMP1]], true
; CHECK-NEXT: [[C3:%.*]] = icmp eq i8 [[X_M2]], 0
; CHECK-NEXT: [[OR1:%.*]] = or i1 [[C1]], [[C2]]
; CHECK-NEXT: [[OR2:%.*]] = select i1 [[C3]], i1 true, i1 [[OR1]]
@@ -1929,12 +1929,12 @@ define i1 @logical_or_bitwise_or_icmps_comm1(i8 %x, i8 %y, i8 %z) {
define i1 @logical_or_bitwise_or_icmps_comm2(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @logical_or_bitwise_or_icmps_comm2(
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
-; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1
; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
-; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[X]], [[Z_SHIFT]]
-; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[X_M1]], 0
+; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[X:%.*]], [[Z_SHIFT]]
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i8 [[X]] to i1
+; CHECK-NEXT: [[C2:%.*]] = xor i1 [[TMP1]], true
; CHECK-NEXT: [[C3:%.*]] = icmp eq i8 [[X_M2]], 0
-; CHECK-NEXT: [[OR1:%.*]] = or i1 [[C2]], [[C1]]
+; CHECK-NEXT: [[OR1:%.*]] = or i1 [[C1]], [[C2]]
; CHECK-NEXT: [[OR2:%.*]] = select i1 [[OR1]], i1 true, i1 [[C3]]
; CHECK-NEXT: ret i1 [[OR2]]
;
@@ -1952,12 +1952,12 @@ define i1 @logical_or_bitwise_or_icmps_comm2(i8 %x, i8 %y, i8 %z) {
define i1 @logical_or_bitwise_or_icmps_comm3(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @logical_or_bitwise_or_icmps_comm3(
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
-; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1
; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
-; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[X]], [[Z_SHIFT]]
-; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[X_M1]], 0
+; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[X:%.*]], [[Z_SHIFT]]
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i8 [[X]] to i1
+; CHECK-NEXT: [[C2:%.*]] = xor i1 [[TMP1]], true
; CHECK-NEXT: [[C3:%.*]] = icmp eq i8 [[X_M2]], 0
-; CHECK-NEXT: [[OR1:%.*]] = or i1 [[C2]], [[C1]]
+; CHECK-NEXT: [[OR1:%.*]] = or i1 [[C1]], [[C2]]
; CHECK-NEXT: [[OR2:%.*]] = select i1 [[C3]], i1 true, i1 [[OR1]]
; CHECK-NEXT: ret i1 [[OR2]]
;
@@ -1975,10 +1975,10 @@ define i1 @logical_or_bitwise_or_icmps_comm3(i8 %x, i8 %y, i8 %z) {
define i1 @logical_or_logical_or_icmps(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @logical_or_logical_or_icmps(
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
-; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1
; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
-; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[X]], [[Z_SHIFT]]
-; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[X_M1]], 0
+; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[X:%.*]], [[Z_SHIFT]]
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i8 [[X]] to i1
+; CHECK-NEXT: [[C2:%.*]] = xor i1 [[TMP1]], true
; CHECK-NEXT: [[C3:%.*]] = icmp eq i8 [[X_M2]], 0
; CHECK-NEXT: [[OR1:%.*]] = select i1 [[C1]], i1 true, i1 [[C2]]
; CHECK-NEXT: [[OR2:%.*]] = select i1 [[OR1]], i1 true, i1 [[C3]]
@@ -1998,10 +1998,10 @@ define i1 @logical_or_logical_or_icmps(i8 %x, i8 %y, i8 %z) {
define i1 @logical_or_logical_or_icmps_comm1(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @logical_or_logical_or_icmps_comm1(
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
-; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1
; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
-; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[X]], [[Z_SHIFT]]
-; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[X_M1]], 0
+; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[X:%.*]], [[Z_SHIFT]]
+; CHECK-NEXT: [[TMP2:%.*]] = trunc i8 [[X]] to i1
+; CHECK-NEXT: [[C2:%.*]] = xor i1 [[TMP2]], true
; CHECK-NEXT: [[C3:%.*]] = icmp eq i8 [[X_M2]], 0
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[C3]], i1 true, i1 [[C1]]
; CHECK-NEXT: [[OR2:%.*]] = select i1 [[TMP1]], i1 true, i1 [[C2]]
@@ -2021,10 +2021,10 @@ define i1 @logical_or_logical_or_icmps_comm1(i8 %x, i8 %y, i8 %z) {
define i1 @logical_or_logical_or_icmps_comm2(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @logical_or_logical_or_icmps_comm2(
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
-; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1
; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
-; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[X]], [[Z_SHIFT]]
-; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[X_M1]], 0
+; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[X:%.*]], [[Z_SHIFT]]
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i8 [[X]] to i1
+; CHECK-NEXT: [[C2:%.*]] = xor i1 [[TMP1]], true
; CHECK-NEXT: [[C3:%.*]] = icmp eq i8 [[X_M2]], 0
; CHECK-NEXT: [[OR1:%.*]] = select i1 [[C2]], i1 true, i1 [[C1]]
; CHECK-NEXT: [[OR2:%.*]] = select i1 [[OR1]], i1 true, i1 [[C3]]
diff --git a/llvm/test/Transforms/InstCombine/and.ll b/llvm/test/Transforms/InstCombine/and.ll
index 6a25e53ddaba4..febfea2793a5d 100644
--- a/llvm/test/Transforms/InstCombine/and.ll
+++ b/llvm/test/Transforms/InstCombine/and.ll
@@ -2459,9 +2459,8 @@ define <3 x i16> @lshr_shl_pow2_const_case1_poison3_vec(<3 x i16> %x) {
define i8 @negate_lowbitmask(i8 %x, i8 %y) !prof !0 {
; CHECK-LABEL: @negate_lowbitmask(
-; CHECK-NEXT: [[A:%.*]] = and i8 [[X:%.*]], 1
-; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[A]], 0
-; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP1]], i8 0, i8 [[Y:%.*]], !prof [[PROF1]]
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i8 [[X:%.*]] to i1
+; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP1]], i8 [[Y:%.*]], i8 0, !prof [[PROF1]]
; CHECK-NEXT: ret i8 [[R]]
;
%a = and i8 %x, 1
diff --git a/llvm/test/Transforms/InstCombine/assume.ll b/llvm/test/Transforms/InstCombine/assume.ll
index 78c5c4fbff9d4..087a656cd4d6c 100644
--- a/llvm/test/Transforms/InstCombine/assume.ll
+++ b/llvm/test/Transforms/InstCombine/assume.ll
@@ -1104,10 +1104,11 @@ define void @canonicalize_assume(ptr %0) {
define void @assume_makes_and_known_assume_on_arg(ptr %p, i32 %x) {
; CHECK-LABEL: @assume_makes_and_known_assume_on_arg(
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 1
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i1
+; CHECK-NEXT: [[CMP:%.*]] = xor i1 [[TMP1]], true
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
-; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4
+; CHECK-NEXT: [[AND2:%.*]] = and i32 [[X]], 1
+; CHECK-NEXT: store i32 [[AND2]], ptr [[P:%.*]], align 4
; CHECK-NEXT: ret void
;
%and = and i32 %x, 1
@@ -1121,10 +1122,11 @@ define void @assume_makes_and_known_assume_on_arg(ptr %p, i32 %x) {
define void @assume_makes_and_known_assume_on_mul(ptr %p, i32 %a, i32 %b) {
; CHECK-LABEL: @assume_makes_and_known_assume_on_mul(
; CHECK-NEXT: [[X:%.*]] = mul i32 [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], 1
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X]] to i1
+; CHECK-NEXT: [[CMP:%.*]] = xor i1 [[TMP1]], true
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
-; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4
+; CHECK-NEXT: [[AND2:%.*]] = and i32 [[X]], 1
+; CHECK-NEXT: store i32 [[AND2]], ptr [[P:%.*]], align 4
; CHECK-NEXT: ret void
;
%x = mul i32 %a, %b
@@ -1139,10 +1141,11 @@ define void @assume_makes_and_known_assume_on_mul(ptr %p, i32 %a, i32 %b) {
define void @assume_makes_and_known_assume_on_bitwise(ptr %p, i32 %a, i32 %b) {
; CHECK-LABEL: @assume_makes_and_known_assume_on_bitwise(
; CHECK-NEXT: [[X:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], 1
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X]] to i1
+; CHECK-NEXT: [[CMP:%.*]] = xor i1 [[TMP1]], true
; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
-; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4
+; CHECK-NEXT: [[AND2:%.*]] = and i32 [[X]], 1
+; CHECK-NEXT: store i32 [[AND2]], ptr [[P:%.*]], align 4
; CHECK-NEXT: ret void
;
%x = or i32 %a, %b
diff --git a/llvm/test/Transforms/InstCombine/binop-cast.ll b/llvm/test/Transforms/InstCombine/binop-cast.ll
index ae3036ffc88ae..f4d207f4b1ff4 100644
--- a/llvm/test/Transforms/InstCombine/binop-cast.ll
+++ b/llvm/test/Transforms/InstCombine/binop-cast.ll
@@ -301,9 +301,8 @@ define i32 @and_add_bool_to_select(i1 %x, i32 %y) {
define i32 @and_add_bool_no_fold(i32 %y) !prof !0 {
; CHECK-LABEL: @and_add_bool_no_fold(
-; CHECK-NEXT: [[X:%.*]] = and i32 [[Y:%.*]], 1
-; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[X]], 0
-; CHECK-NEXT: [[RES:%.*]] = select i1 [[TMP1]], i32 [[Y]], i32 0, !prof [[PROF1]]
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[Y:%.*]] to i1
+; CHECK-NEXT: [[RES:%.*]] = select i1 [[TMP1]], i32 0, i32 [[Y]], !prof [[PROF1]]
; CHECK-NEXT: ret i32 [[RES]]
;
%x = and i32 %y, 1
diff --git a/llvm/test/Transforms/InstCombine/cmp-intrinsic.ll b/llvm/test/Transforms/InstCombine/cmp-intrinsic.ll
index 12c18e2ec0302..fe6f35cdf9d65 100644
--- a/llvm/test/Transforms/InstCombine/cmp-intrinsic.ll
+++ b/llvm/test/Transforms/InstCombine/cmp-intrinsic.ll
@@ -284,8 +284,8 @@ define i1 @cttz_eq_zero_i33(i33 %x) {
define <2 x i1> @cttz_ne_zero_v2i32(<2 x i32> %a) {
; CHECK-LABEL: @cttz_ne_zero_v2i32(
-; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[A:%.*]], splat (i32 1)
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> [[TMP1]], zeroinitializer
+; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[A:%.*]] to <2 x i1>
+; CHECK-NEXT: [[CMP:%.*]] = xor <2 x i1> [[TMP1]], splat (i1 true)
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%x = tail call <2 x i32> @llvm.cttz.v2i32(<2 x i32> %a, i1 false)
@@ -350,8 +350,8 @@ define i1 @cttz_eq_other_i33_multiuse(i33 %x, ptr %p) {
define i1 @cttz_ugt_zero_i33(i33 %x) {
; CHECK-LABEL: @cttz_ugt_zero_i33(
-; CHECK-NEXT: [[TMP1:%.*]] = and i33 [[X:%.*]], 1
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i33 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i33 [[X:%.*]] to i1
+; CHECK-NEXT: [[CMP:%.*]] = xor i1 [[TMP1]], true
; CHECK-NEXT: ret i1 [[CMP]]
;
%tz = tail call i33 @llvm.cttz.i33(i33 %x, i1 false)
diff --git a/llvm/test/Transforms/InstCombine/freeze.ll b/llvm/test/Transforms/InstCombine/freeze.ll
index 7a542dc5cb67a..f6c17138f27ab 100644
--- a/llvm/test/Transforms/InstCombine/freeze.ll
+++ b/llvm/test/Transforms/InstCombine/freeze.ll
@@ -126,8 +126,8 @@ define i1 @early_freeze_test2(ptr %ptr) {
; CHECK-SAME: ptr [[PTR:%.*]]) {
; CHECK-NEXT: [[V1:%.*]] = load i32, ptr [[PTR]], align 4
; CHECK-NEXT: [[V1_FR:%.*]] = freeze i32 [[V1]]
-; CHECK-NEXT: [[V2:%.*]] = and i32 [[V1_FR]], 1
-; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[V2]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[V1_FR]] to i1
+; CHECK-NEXT: [[COND:%.*]] = xor i1 [[TMP1]], true
; CHECK-NEXT: ret i1 [[COND]]
;
%v1 = load i32, ptr %ptr
diff --git a/llvm/test/Transforms/InstCombine/icmp-and-shift.ll b/llvm/test/Transforms/InstCombine/icmp-and-shift.ll
index 2973bb979181d..3aae6d65db559 100644
--- a/llvm/test/Transforms/InstCombine/icmp-and-shift.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-and-shift.ll
@@ -644,9 +644,9 @@ define i1 @test_const_shr_and_1_ne_0(i32 %b) {
define i1 @test_not_const_shr_and_1_ne_0(i32 %b) {
; CHECK-LABEL: @test_not_const_shr_and_1_ne_0(
-; CHECK-NEXT: [[TMP1:%.*]] = shl nuw i32 1, [[B:%.*]]
-; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 42
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP2]], 0
+; CHECK-NEXT: [[SHR:%.*]] = lshr i32 42, [[B:%.*]]
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[SHR]] to i1
+; CHECK-NEXT: [[CMP:%.*]] = xor i1 [[TMP1]], true
; CHECK-NEXT: ret i1 [[CMP]]
;
%shr = lshr i32 42, %b
diff --git a/llvm/test/Transforms/InstCombine/icmp-binop.ll b/llvm/test/Transforms/InstCombine/icmp-binop.ll
index 2cf70d30fab59..341aef323fdb3 100644
--- a/llvm/test/Transforms/InstCombine/icmp-binop.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-binop.ll
@@ -123,8 +123,7 @@ define <2 x i1> @mul_setoddV_unkV_ne(<2 x i32> %v1, <2 x i32> %v2) {
define i1 @mul_broddV_unkV_eq(i16 %v, i16 %v2) {
; CHECK-LABEL: @mul_broddV_unkV_eq(
-; CHECK-NEXT: [[LB:%.*]] = and i16 [[V2:%.*]], 1
-; CHECK-NEXT: [[ODD_NOT:%.*]] = icmp eq i16 [[LB]], 0
+; CHECK-NEXT: [[ODD_NOT:%.*]] = trunc i16 [[V2:%.*]] to i1
; CHECK-NEXT: br i1 [[ODD_NOT]], label [[FALSE:%.*]], label [[TRUE:%.*]]
; CHECK: true:
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[V:%.*]], 0
diff --git a/llvm/test/Transforms/InstCombine/icmp-dom.ll b/llvm/test/Transforms/InstCombine/icmp-dom.ll
index a72b5e0bbfa03..56b87cbb84292 100644
--- a/llvm/test/Transforms/InstCombine/icmp-dom.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-dom.ll
@@ -407,8 +407,7 @@ falselabel:
define i1 @and_mask1_eq(i32 %conv) {
; CHECK-LABEL: @and_mask1_eq(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[CONV:%.*]], 1
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
+; CHECK-NEXT: [[CMP:%.*]] = trunc i32 [[CONV:%.*]] to i1
; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
; CHECK: then:
; CHECK-NEXT: ret i1 false
@@ -432,8 +431,7 @@ else:
define i1 @and_mask1_ne(i32 %conv) {
; CHECK-LABEL: @and_mask1_ne(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[CONV:%.*]], 1
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
+; CHECK-NEXT: [[CMP:%.*]] = trunc i32 [[CONV:%.*]] to i1
; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
; CHECK: then:
; CHECK-NEXT: ret i1 false
diff --git a/llvm/test/Transforms/InstCombine/icmp-logical.ll b/llvm/test/Transforms/InstCombine/icmp-logical.ll
index 71706af914933..5de9cbe91bc77 100644
--- a/llvm/test/Transforms/InstCombine/icmp-logical.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-logical.ll
@@ -271,8 +271,8 @@ define i1 @masked_or_allzeroes_notoptimised_logical(i32 %A) {
define i1 @nomask_lhs(i32 %in) {
; CHECK-LABEL: @nomask_lhs(
-; CHECK-NEXT: [[MASKED:%.*]] = and i32 [[IN:%.*]], 1
-; CHECK-NEXT: [[TST2:%.*]] = icmp eq i32 [[MASKED]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[IN:%.*]] to i1
+; CHECK-NEXT: [[TST2:%.*]] = xor i1 [[TMP1]], true
; CHECK-NEXT: ret i1 [[TST2]]
;
%tst1 = icmp eq i32 %in, 0
@@ -284,8 +284,8 @@ define i1 @nomask_lhs(i32 %in) {
define i1 @nomask_lhs_logical(i32 %in) {
; CHECK-LABEL: @nomask_lhs_logical(
-; CHECK-NEXT: [[MASKED:%.*]] = and i32 [[IN:%.*]], 1
-; CHECK-NEXT: [[TST2:%.*]] = icmp eq i32 [[MASKED]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[IN:%.*]] to i1
+; CHECK-NEXT: [[TST2:%.*]] = xor i1 [[TMP1]], true
; CHECK-NEXT: ret i1 [[TST2]]
;
%tst1 = icmp eq i32 %in, 0
@@ -297,8 +297,8 @@ define i1 @nomask_lhs_logical(i32 %in) {
define i1 @nomask_rhs(i32 %in) {
; CHECK-LABEL: @nomask_rhs(
-; CHECK-NEXT: [[MASKED:%.*]] = and i32 [[IN:%.*]], 1
-; CHECK-NEXT: [[TST1:%.*]] = icmp eq i32 [[MASKED]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[IN:%.*]] to i1
+; CHECK-NEXT: [[TST1:%.*]] = xor i1 [[TMP1]], true
; CHECK-NEXT: ret i1 [[TST1]]
;
%masked = and i32 %in, 1
@@ -310,8 +310,8 @@ define i1 @nomask_rhs(i32 %in) {
define i1 @nomask_rhs_logical(i32 %in) {
; CHECK-LABEL: @nomask_rhs_logical(
-; CHECK-NEXT: [[MASKED:%.*]] = and i32 [[IN:%.*]], 1
-; CHECK-NEXT: [[TST1:%.*]] = icmp eq i32 [[MASKED]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[IN:%.*]] to i1
+; CHECK-NEXT: [[TST1:%.*]] = xor i1 [[TMP1]], true
; CHECK-NEXT: ret i1 [[TST1]]
;
%masked = and i32 %in, 1
diff --git a/llvm/test/Transforms/InstCombine/icmp-mul-and.ll b/llvm/test/Transforms/InstCombine/icmp-mul-and.ll
index 62d139c81ea0f..2097e8f1e1828 100644
--- a/llvm/test/Transforms/InstCombine/icmp-mul-and.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-mul-and.ll
@@ -5,8 +5,8 @@ declare void @use(i8)
define i1 @mul_mask_pow2_eq0(i8 %x) {
; CHECK-LABEL: @mul_mask_pow2_eq0(
-; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], 1
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i8 [[X:%.*]] to i1
+; CHECK-NEXT: [[CMP:%.*]] = xor i1 [[TMP1]], true
; CHECK-NEXT: ret i1 [[CMP]]
;
%mul = mul i8 %x, 44
@@ -106,8 +106,8 @@ define i1 @mul_mask_notpow2_ne(i8 %x) {
define i1 @pr40493(i32 %area) {
; CHECK-LABEL: @pr40493(
-; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[AREA:%.*]], 1
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[AREA:%.*]] to i1
+; CHECK-NEXT: [[CMP:%.*]] = xor i1 [[TMP1]], true
; CHECK-NEXT: ret i1 [[CMP]]
;
%mul = mul i32 %area, 12
@@ -155,8 +155,8 @@ define i32 @pr40493_neg3(i32 %area) {
define <4 x i1> @pr40493_vec1(<4 x i32> %area) {
; CHECK-LABEL: @pr40493_vec1(
-; CHECK-NEXT: [[TMP1:%.*]] = and <4 x i32> [[AREA:%.*]], splat (i32 1)
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq <4 x i32> [[TMP1]], zeroinitializer
+; CHECK-NEXT: [[TMP1:%.*]] = trunc <4 x i32> [[AREA:%.*]] to <4 x i1>
+; CHECK-NEXT: [[CMP:%.*]] = xor <4 x i1> [[TMP1]], splat (i1 true)
; CHECK-NEXT: ret <4 x i1> [[CMP]]
;
%mul = mul <4 x i32> %area, <i32 12, i32 12, i32 12, i32 12>
@@ -233,8 +233,8 @@ define i1 @pr51551(i32 %x, i32 %y) {
define i1 @pr51551_2(i32 %x, i32 %y) {
; CHECK-LABEL: @pr51551_2(
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 1
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i1
+; CHECK-NEXT: [[CMP:%.*]] = xor i1 [[TMP1]], true
; CHECK-NEXT: ret i1 [[CMP]]
;
%t0 = and i32 %y, -7
diff --git a/llvm/test/Transforms/InstCombine/icmp-ne-pow2.ll b/llvm/test/Transforms/InstCombine/icmp-ne-pow2.ll
index 4be85be543760..d9f5083d01934 100644
--- a/llvm/test/Transforms/InstCombine/icmp-ne-pow2.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-ne-pow2.ll
@@ -161,8 +161,7 @@ False:
define i64 @pow2_64_br(i64 %x) {
; CHECK-LABEL: @pow2_64_br(
-; CHECK-NEXT: [[AND:%.*]] = and i64 [[X:%.*]], 1
-; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i64 [[AND]], 0
+; CHECK-NEXT: [[CMP_NOT:%.*]] = trunc i64 [[X:%.*]] to i1
; CHECK-NEXT: br i1 [[CMP_NOT]], label [[FALSE:%.*]], label [[TRUE:%.*]]
; CHECK: True:
; CHECK-NEXT: ret i64 1
diff --git a/llvm/test/Transforms/InstCombine/icmp.ll b/llvm/test/Transforms/InstCombine/icmp.ll
index c7bae58a0b197..48cd0e8d61513 100644
--- a/llvm/test/Transforms/InstCombine/icmp.ll
+++ b/llvm/test/Transforms/InstCombine/icmp.ll
@@ -5228,10 +5228,9 @@ define i1 @redundant_sign_bit_count_ugt_31_30(i32 %x) {
define i1 @zext_bool_and_eq0(i1 %x, i8 %y) {
; CHECK-LABEL: define i1 @zext_bool_and_eq0(
; CHECK-SAME: i1 [[X:%.*]], i8 [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[Y]], 1
-; CHECK-NEXT: [[R1:%.*]] = icmp eq i8 [[TMP1]], 0
-; CHECK-NEXT: [[NOT_X:%.*]] = xor i1 [[X]], true
-; CHECK-NEXT: [[R:%.*]] = select i1 [[NOT_X]], i1 true, i1 [[R1]]
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i8 [[Y]] to i1
+; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[X]], i1 [[TMP1]], i1 false
+; CHECK-NEXT: [[R:%.*]] = xor i1 [[TMP2]], true
; CHECK-NEXT: ret i1 [[R]]
;
%zx = zext i1 %x to i8
@@ -5243,10 +5242,9 @@ define i1 @zext_bool_and_eq0(i1 %x, i8 %y) {
define <2 x i1> @zext_bool_and_eq0_commute(<2 x i1> %x, <2 x i8> %p) {
; CHECK-LABEL: define <2 x i1> @zext_bool_and_eq0_commute(
; CHECK-SAME: <2 x i1> [[X:%.*]], <2 x i8> [[P:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[P]], splat (i8 1)
-; CHECK-NEXT: [[R1:%.*]] = icmp eq <2 x i8> [[TMP1]], zeroinitializer
-; CHECK-NEXT: [[NOT_X:%.*]] = xor <2 x i1> [[X]], splat (i1 true)
-; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[NOT_X]], <2 x i1> splat (i1 true), <2 x i1> [[R1]]
+; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i8> [[P]] to <2 x i1>
+; CHECK-NEXT: [[TMP2:%.*]] = select <2 x i1> [[X]], <2 x i1> [[TMP1]], <2 x i1> zeroinitializer
+; CHECK-NEXT: [[R:%.*]] = xor <2 x i1> [[TMP2]], splat (i1 true)
; CHECK-NEXT: ret <2 x i1> [[R]]
;
%y = mul <2 x i8> %p, %p ; thwart complexity-based canonicalization
@@ -5272,10 +5270,9 @@ define i1 @zext_bool_and_ne0(i1 %x, i8 %y) {
define i1 @zext_bool_and_ne1(i1 %x, i8 %y) {
; CHECK-LABEL: define i1 @zext_bool_and_ne1(
; CHECK-SAME: i1 [[X:%.*]], i8 [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[Y]], 1
-; CHECK-NEXT: [[R1:%.*]] = icmp eq i8 [[TMP1]], 0
-; CHECK-NEXT: [[NOT_X:%.*]] = xor i1 [[X]], true
-; CHECK-NEXT: [[R:%.*]] = select i1 [[NOT_X]], i1 true, i1 [[R1]]
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i8 [[Y]] to i1
+; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[X]], i1 [[TMP1]], i1 false
+; CHECK-NEXT: [[R:%.*]] = xor i1 [[TMP2]], true
; CHECK-NEXT: ret i1 [[R]]
;
%zx = zext i1 %x to i8
diff --git a/llvm/test/Transforms/InstCombine/or-bitmask.ll b/llvm/test/Transforms/InstCombine/or-bitmask.ll
index 5fd78827d5f30..27d4addccac44 100644
--- a/llvm/test/Transforms/InstCombine/or-bitmask.ll
+++ b/llvm/test/Transforms/InstCombine/or-bitmask.ll
@@ -159,11 +159,10 @@ define i32 @add_select_cmp_trunc1(i32 %in) {
define i32 @add_select_cmp_and_const_mismatch(i32 %in) {
; CHECK-LABEL: @add_select_cmp_and_const_mismatch(
-; CHECK-NEXT: [[BITOP0:%.*]] = and i32 [[IN:%.*]], 1
-; CHECK-NEXT: [[CMP0:%.*]] = icmp eq i32 [[BITOP0]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[IN:%.*]] to i1
; CHECK-NEXT: [[BITOP1:%.*]] = and i32 [[IN]], 2
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[BITOP1]], 0
-; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[CMP0]], i32 0, i32 72
+; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[TMP1]], i32 72, i32 0
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP1]], i32 0, i32 288
; CHECK-NEXT: [[OUT:%.*]] = or disjoint i32 [[SEL0]], [[SEL1]]
; CHECK-NEXT: ret i32 [[OUT]]
@@ -180,11 +179,10 @@ define i32 @add_select_cmp_and_const_mismatch(i32 %in) {
define i32 @add_select_cmp_and_value_mismatch(i32 %in, i32 %in1) {
; CHECK-LABEL: @add_select_cmp_and_value_mismatch(
-; CHECK-NEXT: [[BITOP0:%.*]] = and i32 [[IN:%.*]], 1
-; CHECK-NEXT: [[CMP0:%.*]] = icmp eq i32 [[BITOP0]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[IN:%.*]] to i1
; CHECK-NEXT: [[BITOP1:%.*]] = and i32 [[IN1:%.*]], 2
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[BITOP1]], 0
-; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[CMP0]], i32 0, i32 72
+; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[TMP1]], i32 72, i32 0
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP1]], i32 0, i32 144
; CHECK-NEXT: [[OUT:%.*]] = or disjoint i32 [[SEL0]], [[SEL1]]
; CHECK-NEXT: ret i32 [[OUT]]
@@ -201,10 +199,9 @@ define i32 @add_select_cmp_and_value_mismatch(i32 %in, i32 %in1) {
define i32 @add_select_cmp_and_negative(i32 %in) {
; CHECK-LABEL: @add_select_cmp_and_negative(
-; CHECK-NEXT: [[BITOP0:%.*]] = and i32 [[IN:%.*]], 1
-; CHECK-NEXT: [[CMP0:%.*]] = icmp eq i32 [[BITOP0]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[IN:%.*]] to i1
; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[IN]], 2
-; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[CMP0]], i32 0, i32 72
+; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[TMP1]], i32 72, i32 0
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP1]], i32 0, i32 -144
; CHECK-NEXT: [[OUT:%.*]] = or disjoint i32 [[SEL0]], [[SEL1]]
; CHECK-NEXT: ret i32 [[OUT]]
@@ -240,11 +237,10 @@ define i32 @add_select_cmp_and_bitsel_overlap(i32 %in) {
define i32 @add_select_cmp_and_multbit_mask(i32 %in) {
; CHECK-LABEL: @add_select_cmp_and_multbit_mask(
-; CHECK-NEXT: [[BITOP0:%.*]] = and i32 [[IN:%.*]], 1
-; CHECK-NEXT: [[CMP0:%.*]] = icmp eq i32 [[BITOP0]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[IN:%.*]] to i1
; CHECK-NEXT: [[BITOP1:%.*]] = and i32 [[IN]], 6
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[BITOP1]], 0
-; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[CMP0]], i32 0, i32 72
+; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[TMP1]], i32 72, i32 0
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP1]], i32 0, i32 432
; CHECK-NEXT: [[OUT:%.*]] = or disjoint i32 [[SEL0]], [[SEL1]]
; CHECK-NEXT: ret i32 [[OUT]]
@@ -278,12 +274,11 @@ define <2 x i32> @add_select_cmp_vec(<2 x i32> %in) {
define <2 x i32> @add_select_cmp_vec_poison(<2 x i32> %in) {
; CHECK-LABEL: @add_select_cmp_vec_poison(
-; CHECK-NEXT: [[BITOP0:%.*]] = and <2 x i32> [[IN:%.*]], splat (i32 1)
-; CHECK-NEXT: [[CMP0:%.*]] = icmp eq <2 x i32> [[BITOP0]], zeroinitializer
+; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[IN:%.*]] to <2 x i1>
; CHECK-NEXT: [[BITOP1:%.*]] = and <2 x i32> [[IN]], splat (i32 2)
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq <2 x i32> [[BITOP1]], zeroinitializer
; CHECK-NEXT: [[SEL1:%.*]] = select <2 x i1> [[CMP1]], <2 x i32> zeroinitializer, <2 x i32> <i32 poison, i32 144>
-; CHECK-NEXT: [[OUT:%.*]] = select <2 x i1> [[CMP0]], <2 x i32> [[SEL1]], <2 x i32> <i32 72, i32 poison>
+; CHECK-NEXT: [[OUT:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> <i32 72, i32 poison>, <2 x i32> [[SEL1]]
; CHECK-NEXT: ret <2 x i32> [[OUT]]
;
%bitop0 = and <2 x i32> %in, <i32 1, i32 1>
@@ -319,11 +314,10 @@ define <2 x i32> @add_select_cmp_vec_nonunique(<2 x i32> %in) {
define i64 @mask_select_types(i32 %in) {
; CHECK-LABEL: @mask_select_types(
-; CHECK-NEXT: [[BITOP0:%.*]] = and i32 [[IN:%.*]], 1
-; CHECK-NEXT: [[CMP0_NOT:%.*]] = icmp eq i32 [[BITOP0]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[IN:%.*]] to i1
; CHECK-NEXT: [[BITOP1:%.*]] = and i32 [[IN]], 2
; CHECK-NEXT: [[CMP1_NOT:%.*]] = icmp eq i32 [[BITOP1]], 0
-; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[CMP0_NOT]], i64 0, i64 72
+; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[TMP1]], i64 72, i64 0
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP1_NOT]], i64 0, i64 144
; CHECK-NEXT: [[OUT:%.*]] = or disjoint i64 [[SEL0]], [[SEL1]]
; CHECK-NEXT: ret i64 [[OUT]]
@@ -400,10 +394,9 @@ define i32 @add_select_cmp_and_mul(i32 %in) {
define i32 @add_select_cmp_mixed2_mismatch(i32 %in) {
; CHECK-LABEL: @add_select_cmp_mixed2_mismatch(
-; CHECK-NEXT: [[BITOP0:%.*]] = and i32 [[IN:%.*]], 1
-; CHECK-NEXT: [[CMP0:%.*]] = icmp eq i32 [[BITOP0]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[IN:%.*]] to i1
; CHECK-NEXT: [[MASK:%.*]] = and i32 [[IN]], 2
-; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[CMP0]], i32 0, i32 73
+; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[TMP1]], i32 73, i32 0
; CHECK-NEXT: [[SEL1:%.*]] = mul nuw nsw i32 [[MASK]], 72
; CHECK-NEXT: [[OUT:%.*]] = or disjoint i32 [[SEL0]], [[SEL1]]
; CHECK-NEXT: ret i32 [[OUT]]
@@ -895,12 +888,11 @@ define i32 @no_chain(i32 %in, i32 %in2, i32 %in3) {
define <2 x i64> @issue199506_1(i64 %idx) {
; CHECK-LABEL: @issue199506_1(
-; CHECK-NEXT: [[B0:%.*]] = and i64 [[IDX:%.*]], 1
-; CHECK-NEXT: [[C0:%.*]] = icmp eq i64 [[B0]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[IDX:%.*]] to i1
; CHECK-NEXT: [[B1:%.*]] = and i64 [[IDX]], 2
; CHECK-NEXT: [[C1:%.*]] = icmp eq i64 [[B1]], 0
; CHECK-NEXT: [[HI:%.*]] = select i1 [[C1]], <2 x i64> zeroinitializer, <2 x i64> splat (i64 -6148914691236517206)
-; CHECK-NEXT: [[LO:%.*]] = select i1 [[C0]], <2 x i64> zeroinitializer, <2 x i64> splat (i64 6148914691236517205)
+; CHECK-NEXT: [[LO:%.*]] = select i1 [[TMP1]], <2 x i64> splat (i64 6148914691236517205), <2 x i64> zeroinitializer
; CHECK-NEXT: [[OR:%.*]] = or disjoint <2 x i64> [[HI]], [[LO]]
; CHECK-NEXT: ret <2 x i64> [[OR]]
;
@@ -916,12 +908,11 @@ define <2 x i64> @issue199506_1(i64 %idx) {
define <2 x i64> @issue199506_2(i64 %idx) {
; CHECK-LABEL: @issue199506_2(
-; CHECK-NEXT: [[B0:%.*]] = and i64 [[IDX:%.*]], 1
-; CHECK-NEXT: [[C0_NOT:%.*]] = icmp eq i64 [[B0]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[IDX:%.*]] to i1
; CHECK-NEXT: [[B1:%.*]] = and i64 [[IDX]], 2
; CHECK-NEXT: [[C1_NOT:%.*]] = icmp eq i64 [[B1]], 0
; CHECK-NEXT: [[HI:%.*]] = select i1 [[C1_NOT]], <2 x i64> zeroinitializer, <2 x i64> splat (i64 -6148914691236517206)
-; CHECK-NEXT: [[LO:%.*]] = select i1 [[C0_NOT]], <2 x i64> zeroinitializer, <2 x i64> splat (i64 6148914691236517205)
+; CHECK-NEXT: [[LO:%.*]] = select i1 [[TMP1]], <2 x i64> splat (i64 6148914691236517205), <2 x i64> zeroinitializer
; CHECK-NEXT: [[OR:%.*]] = or disjoint <2 x i64> [[HI]], [[LO]]
; CHECK-NEXT: ret <2 x i64> [[OR]]
;
diff --git a/llvm/test/Transforms/InstCombine/pr25342.ll b/llvm/test/Transforms/InstCombine/pr25342.ll
index 826070bc4e76b..65debfaac09d9 100644
--- a/llvm/test/Transforms/InstCombine/pr25342.ll
+++ b/llvm/test/Transforms/InstCombine/pr25342.ll
@@ -92,8 +92,7 @@ define void @multi_phi(i32 signext %n) {
; CHECK-NEXT: [[SUB_I:%.*]] = fsub float [[MUL_I]], [[MUL4_I]]
; CHECK-NEXT: [[ADD_I:%.*]] = fadd float [[SUB_I]], [[TMP0]]
; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_0]], 1
-; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[I_0]], 1
-; CHECK-NEXT: [[EVEN_NOT_NOT_NOT:%.*]] = icmp eq i32 [[TMP5]], 0
+; CHECK-NEXT: [[EVEN_NOT_NOT_NOT:%.*]] = trunc i32 [[INC]] to i1
; CHECK-NEXT: br i1 [[EVEN_NOT_NOT_NOT]], label [[ODD_BB]], label [[EVEN_BB:%.*]]
; CHECK: even.bb:
; CHECK-NEXT: [[TMP6:%.*]] = fadd float [[SUB_I]], [[ADD_I]]
diff --git a/llvm/test/Transforms/InstCombine/select-icmp-and.ll b/llvm/test/Transforms/InstCombine/select-icmp-and.ll
index 4309c603bba81..593df93ac5724 100644
--- a/llvm/test/Transforms/InstCombine/select-icmp-and.ll
+++ b/llvm/test/Transforms/InstCombine/select-icmp-and.ll
@@ -734,9 +734,8 @@ entry:
define i32 @select_bittest_to_shl(i32 %x) {
; CHECK-LABEL: @select_bittest_to_shl(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 1
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
-; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 2, i32 4
+; CHECK-NEXT: [[TMP0:%.*]] = trunc i32 [[X:%.*]] to i1
+; CHECK-NEXT: [[RET:%.*]] = select i1 [[TMP0]], i32 4, i32 2
; CHECK-NEXT: ret i32 [[RET]]
;
entry:
@@ -749,9 +748,8 @@ entry:
define i32 @select_bittest_to_lshr(i32 %x) {
; CHECK-LABEL: @select_bittest_to_lshr(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 1
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
-; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 4, i32 2
+; CHECK-NEXT: [[TMP0:%.*]] = trunc i32 [[X:%.*]] to i1
+; CHECK-NEXT: [[RET:%.*]] = select i1 [[TMP0]], i32 2, i32 4
; CHECK-NEXT: ret i32 [[RET]]
;
entry:
@@ -778,9 +776,8 @@ entry:
define i32 @select_bittest_to_shl_negative_test(i32 %x) {
; CHECK-LABEL: @select_bittest_to_shl_negative_test(
-; CHECK-NEXT: [[MASK:%.*]] = and i32 [[X:%.*]], 1
-; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[MASK]], 0
-; CHECK-NEXT: [[RES:%.*]] = select i1 [[COND]], i32 4, i32 6
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i1
+; CHECK-NEXT: [[RES:%.*]] = select i1 [[TMP1]], i32 6, i32 4
; CHECK-NEXT: ret i32 [[RES]]
;
%mask = and i32 %x, 1
diff --git a/llvm/test/Transforms/InstCombine/select-of-bittest.ll b/llvm/test/Transforms/InstCombine/select-of-bittest.ll
index 4495e7f6ed067..dbd22c630bde4 100644
--- a/llvm/test/Transforms/InstCombine/select-of-bittest.ll
+++ b/llvm/test/Transforms/InstCombine/select-of-bittest.ll
@@ -7,9 +7,10 @@
define i32 @and_lshr_and(i32 %arg) {
; CHECK-LABEL: @and_lshr_and(
-; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[ARG:%.*]], 3
-; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
-; CHECK-NEXT: [[T4:%.*]] = zext i1 [[TMP2]] to i32
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[ARG:%.*]] to i1
+; CHECK-NEXT: [[T2:%.*]] = lshr i32 [[ARG]], 1
+; CHECK-NEXT: [[T3:%.*]] = and i32 [[T2]], 1
+; CHECK-NEXT: [[T4:%.*]] = select i1 [[TMP1]], i32 1, i32 [[T3]]
; CHECK-NEXT: ret i32 [[T4]]
;
%t = and i32 %arg, 1
@@ -22,9 +23,10 @@ define i32 @and_lshr_and(i32 %arg) {
define <2 x i32> @and_lshr_and_splatvec(<2 x i32> %arg) {
; CHECK-LABEL: @and_lshr_and_splatvec(
-; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[ARG:%.*]], splat (i32 3)
-; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
-; CHECK-NEXT: [[T4:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32>
+; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[ARG:%.*]] to <2 x i1>
+; CHECK-NEXT: [[T2:%.*]] = lshr <2 x i32> [[ARG]], splat (i32 1)
+; CHECK-NEXT: [[T3:%.*]] = and <2 x i32> [[T2]], splat (i32 1)
+; CHECK-NEXT: [[T4:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> splat (i32 1), <2 x i32> [[T3]]
; CHECK-NEXT: ret <2 x i32> [[T4]]
;
%t = and <2 x i32> %arg, <i32 1, i32 1>
@@ -52,9 +54,10 @@ define <2 x i32> @and_lshr_and_vec_v0(<2 x i32> %arg) {
define <2 x i32> @and_lshr_and_vec_v1(<2 x i32> %arg) {
; CHECK-LABEL: @and_lshr_and_vec_v1(
-; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[ARG:%.*]], <i32 3, i32 5>
-; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
-; CHECK-NEXT: [[T4:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32>
+; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[ARG:%.*]] to <2 x i1>
+; CHECK-NEXT: [[T2:%.*]] = lshr <2 x i32> [[ARG]], <i32 1, i32 2>
+; CHECK-NEXT: [[T3:%.*]] = and <2 x i32> [[T2]], splat (i32 1)
+; CHECK-NEXT: [[T4:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> splat (i32 1), <2 x i32> [[T3]]
; CHECK-NEXT: ret <2 x i32> [[T4]]
;
%t = and <2 x i32> %arg, <i32 1, i32 1>
@@ -304,11 +307,10 @@ define <3 x i32> @f_var1_vec_poison(<3 x i32> %arg, <3 x i32> %arg1) {
define i32 @f_var2(i32 %arg, i32 %arg1) {
; CHECK-LABEL: @f_var2(
-; CHECK-NEXT: [[T:%.*]] = and i32 [[ARG:%.*]], 1
-; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[ARG:%.*]] to i1
; CHECK-NEXT: [[T3:%.*]] = lshr i32 [[ARG]], [[ARG1:%.*]]
; CHECK-NEXT: [[T4:%.*]] = and i32 [[T3]], 1
-; CHECK-NEXT: [[T5:%.*]] = select i1 [[T2]], i32 [[T4]], i32 1
+; CHECK-NEXT: [[T5:%.*]] = select i1 [[TMP1]], i32 1, i32 [[T4]]
; CHECK-NEXT: ret i32 [[T5]]
;
%t = and i32 %arg, 1
@@ -321,11 +323,10 @@ define i32 @f_var2(i32 %arg, i32 %arg1) {
define <2 x i32> @f_var2_splatvec(<2 x i32> %arg, <2 x i32> %arg1) {
; CHECK-LABEL: @f_var2_splatvec(
-; CHECK-NEXT: [[T:%.*]] = and <2 x i32> [[ARG:%.*]], splat (i32 1)
-; CHECK-NEXT: [[T2:%.*]] = icmp eq <2 x i32> [[T]], zeroinitializer
+; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[ARG:%.*]] to <2 x i1>
; CHECK-NEXT: [[T3:%.*]] = lshr <2 x i32> [[ARG]], [[ARG1:%.*]]
; CHECK-NEXT: [[T4:%.*]] = and <2 x i32> [[T3]], splat (i32 1)
-; CHECK-NEXT: [[T5:%.*]] = select <2 x i1> [[T2]], <2 x i32> [[T4]], <2 x i32> splat (i32 1)
+; CHECK-NEXT: [[T5:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> splat (i32 1), <2 x i32> [[T4]]
; CHECK-NEXT: ret <2 x i32> [[T5]]
;
%t = and <2 x i32> %arg, <i32 1, i32 1>
@@ -503,11 +504,10 @@ define i32 @n_var1_oneuse(i32 %arg, i32 %arg1) {
define i32 @n0(i32 %arg, i32 %arg1) {
; CHECK-LABEL: @n0(
-; CHECK-NEXT: [[T:%.*]] = and i32 [[ARG:%.*]], 1
-; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[ARG:%.*]] to i1
; CHECK-NEXT: [[T3:%.*]] = lshr i32 [[ARG1:%.*]], 1
; CHECK-NEXT: [[T4:%.*]] = and i32 [[T3]], 1
-; CHECK-NEXT: [[T5:%.*]] = select i1 [[T2]], i32 [[T4]], i32 1
+; CHECK-NEXT: [[T5:%.*]] = select i1 [[TMP1]], i32 1, i32 [[T4]]
; CHECK-NEXT: ret i32 [[T5]]
;
%t = and i32 %arg, 1
@@ -537,11 +537,10 @@ define i32 @n1(i32 %arg, i32 %arg1) {
define i32 @n2(i32 %arg) {
; CHECK-LABEL: @n2(
-; CHECK-NEXT: [[T:%.*]] = and i32 [[ARG:%.*]], 1
-; CHECK-NEXT: [[T1:%.*]] = icmp eq i32 [[T]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[ARG:%.*]] to i1
; CHECK-NEXT: [[T2:%.*]] = lshr i32 [[ARG]], 2
; CHECK-NEXT: [[T3:%.*]] = and i32 [[T2]], 1
-; CHECK-NEXT: [[T4:%.*]] = select i1 [[T1]], i32 [[T3]], i32 0
+; CHECK-NEXT: [[T4:%.*]] = select i1 [[TMP1]], i32 0, i32 [[T3]]
; CHECK-NEXT: ret i32 [[T4]]
;
%t = and i32 %arg, 1
@@ -571,11 +570,10 @@ define i32 @n3(i32 %arg) {
define i32 @n4(i32 %arg) {
; CHECK-LABEL: @n4(
-; CHECK-NEXT: [[T:%.*]] = and i32 [[ARG:%.*]], 1
-; CHECK-NEXT: [[T1:%.*]] = icmp eq i32 [[T]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[ARG:%.*]] to i1
; CHECK-NEXT: [[T2:%.*]] = lshr i32 [[ARG]], 2
; CHECK-NEXT: [[T3:%.*]] = and i32 [[T2]], 2
-; CHECK-NEXT: [[T4:%.*]] = select i1 [[T1]], i32 [[T3]], i32 1
+; CHECK-NEXT: [[T4:%.*]] = select i1 [[TMP1]], i32 1, i32 [[T3]]
; CHECK-NEXT: ret i32 [[T4]]
;
%t = and i32 %arg, 1
@@ -603,11 +601,10 @@ define i32 @n5(i32 %arg) {
define i32 @n6(i32 %arg) {
; CHECK-LABEL: @n6(
-; CHECK-NEXT: [[T:%.*]] = and i32 [[ARG:%.*]], 1
-; CHECK-NEXT: [[T1_NOT:%.*]] = icmp eq i32 [[T]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[ARG:%.*]] to i1
; CHECK-NEXT: [[T2:%.*]] = lshr i32 [[ARG]], 2
; CHECK-NEXT: [[T3:%.*]] = and i32 [[T2]], 1
-; CHECK-NEXT: [[T4:%.*]] = select i1 [[T1_NOT]], i32 1, i32 [[T3]]
+; CHECK-NEXT: [[T4:%.*]] = select i1 [[TMP1]], i32 [[T3]], i32 1
; CHECK-NEXT: ret i32 [[T4]]
;
%t = and i32 %arg, 1
@@ -637,11 +634,10 @@ define i32 @n7(i32 %arg) {
define i32 @n8(i32 %arg) {
; CHECK-LABEL: @n8(
-; CHECK-NEXT: [[T:%.*]] = and i32 [[ARG:%.*]], 1
-; CHECK-NEXT: [[T1_NOT:%.*]] = icmp eq i32 [[T]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[ARG:%.*]] to i1
; CHECK-NEXT: [[T2:%.*]] = lshr i32 [[ARG]], 2
; CHECK-NEXT: [[T3:%.*]] = and i32 [[T2]], 1
-; CHECK-NEXT: [[T4:%.*]] = select i1 [[T1_NOT]], i32 1, i32 [[T3]]
+; CHECK-NEXT: [[T4:%.*]] = select i1 [[TMP1]], i32 [[T3]], i32 1
; CHECK-NEXT: ret i32 [[T4]]
;
%t = and i32 %arg, 1
diff --git a/llvm/test/Transforms/InstCombine/select-with-bitwise-ops.ll b/llvm/test/Transforms/InstCombine/select-with-bitwise-ops.ll
index 5240a837bf014..9ae7e3ed49479 100644
--- a/llvm/test/Transforms/InstCombine/select-with-bitwise-ops.ll
+++ b/llvm/test/Transforms/InstCombine/select-with-bitwise-ops.ll
@@ -64,8 +64,8 @@ define <2 x i32> @select_icmp_eq_and_1_0_or_2_vec(<2 x i32> %x, <2 x i32> %y) {
define <2 x i32> @select_icmp_eq_and_1_0_or_2_vec_poison1(<2 x i32> %x, <2 x i32> %y) {
; CHECK-LABEL: @select_icmp_eq_and_1_0_or_2_vec_poison1(
-; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X:%.*]], <i32 1, i32 poison>
-; CHECK-NEXT: [[TMP1:%.*]] = shl nuw nsw <2 x i32> [[AND]], splat (i32 1)
+; CHECK-NEXT: [[TMP2:%.*]] = shl <2 x i32> [[X:%.*]], splat (i32 1)
+; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[TMP2]], splat (i32 2)
; CHECK-NEXT: [[SELECT:%.*]] = or <2 x i32> [[Y:%.*]], [[TMP1]]
; CHECK-NEXT: ret <2 x i32> [[SELECT]]
;
@@ -120,10 +120,9 @@ define i32 @select_icmp_eq_and_1_0_xor_2(i32 %x, i32 %y) {
define i32 @select_icmp_eq_and_1_0_and_not_2(i32 %x, i32 %y) {
; CHECK-LABEL: @select_icmp_eq_and_1_0_and_not_2(
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 1
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i1
; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y:%.*]], -3
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[AND2]]
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[TMP1]], i32 [[AND2]], i32 [[Y]]
; CHECK-NEXT: ret i32 [[SELECT]]
;
%and = and i32 %x, 1
@@ -345,10 +344,9 @@ define i32 @select_icmp_eq_0_and_1_xor_1(i64 %x, i32 %y) {
define i32 @select_icmp_eq_0_and_1_and_not_1(i64 %x, i32 %y) {
; CHECK-LABEL: @select_icmp_eq_0_and_1_and_not_1(
-; CHECK-NEXT: [[AND:%.*]] = and i64 [[X:%.*]], 1
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[AND]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[X:%.*]] to i1
; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y:%.*]], -2
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[AND2]]
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[TMP1]], i32 [[AND2]], i32 [[Y]]
; CHECK-NEXT: ret i32 [[SELECT]]
;
%and = and i64 %x, 1
@@ -557,10 +555,9 @@ define i32 @select_icmp_ne_0_and_8_and_not_1073741824(i8 %x, i32 %y) {
; Just make sure we don't assert.
define <2 x i32> @select_icmp_eq_and_1_0_or_vector_of_2s(i32 %x, <2 x i32> %y) {
; CHECK-LABEL: @select_icmp_eq_and_1_0_or_vector_of_2s(
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 1
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i1
; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[Y:%.*]], splat (i32 2)
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], <2 x i32> [[Y]], <2 x i32> [[OR]]
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[TMP1]], <2 x i32> [[OR]], <2 x i32> [[Y]]
; CHECK-NEXT: ret <2 x i32> [[SELECT]]
;
%and = and i32 %x, 1
@@ -851,10 +848,9 @@ define i8 @test70_multiuse(i8 %x, i8 %y) {
define i32 @shift_no_xor_multiuse_or(i32 %x, i32 %y) {
; CHECK-LABEL: @shift_no_xor_multiuse_or(
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i1
; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], 2
-; CHECK-NEXT: [[AND:%.*]] = shl i32 [[X:%.*]], 1
-; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[AND]], 2
-; CHECK-NEXT: [[SELECT:%.*]] = or i32 [[Y]], [[TMP1]]
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[TMP1]], i32 [[OR]], i32 [[Y]]
; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[OR]]
; CHECK-NEXT: ret i32 [[RES]]
;
@@ -868,10 +864,9 @@ define i32 @shift_no_xor_multiuse_or(i32 %x, i32 %y) {
define i32 @shift_no_xor_multiuse_xor(i32 %x, i32 %y) {
; CHECK-LABEL: @shift_no_xor_multiuse_xor(
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i1
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 2
-; CHECK-NEXT: [[AND:%.*]] = shl i32 [[X:%.*]], 1
-; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[AND]], 2
-; CHECK-NEXT: [[SELECT:%.*]] = xor i32 [[Y]], [[TMP1]]
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[TMP1]], i32 [[XOR]], i32 [[Y]]
; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[XOR]]
; CHECK-NEXT: ret i32 [[RES]]
;
@@ -885,10 +880,9 @@ define i32 @shift_no_xor_multiuse_xor(i32 %x, i32 %y) {
define i32 @shift_no_xor_multiuse_and(i32 %x, i32 %y) {
; CHECK-LABEL: @shift_no_xor_multiuse_and(
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 1
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i1
; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y:%.*]], -3
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[AND2]]
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[TMP1]], i32 [[AND2]], i32 [[Y]]
; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[AND2]]
; CHECK-NEXT: ret i32 [[RES]]
;
@@ -1053,12 +1047,11 @@ define i32 @shift_xor_multiuse_and(i32 %x, i32 %y) {
define i32 @shift_no_xor_multiuse_cmp(i32 %x, i32 %y, i32 %z, i32 %w) {
; CHECK-LABEL: @shift_no_xor_multiuse_cmp(
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 1
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
-; CHECK-NEXT: [[TMP1:%.*]] = shl nuw nsw i32 [[AND]], 1
-; CHECK-NEXT: [[SELECT:%.*]] = or i32 [[Y:%.*]], [[TMP1]]
-; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP]], i32 [[Z:%.*]], i32 [[W:%.*]]
-; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[SELECT2]]
+; CHECK-NEXT: [[CMP:%.*]] = trunc i32 [[X:%.*]] to i1
+; CHECK-NEXT: [[Z:%.*]] = or i32 [[W:%.*]], 2
+; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP]], i32 [[Z]], i32 [[W]]
+; CHECK-NEXT: [[SELECT3:%.*]] = select i1 [[CMP]], i32 [[W1:%.*]], i32 [[Z1:%.*]]
+; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT2]], [[SELECT3]]
; CHECK-NEXT: ret i32 [[RES]]
;
%and = and i32 %x, 1
@@ -1072,12 +1065,11 @@ define i32 @shift_no_xor_multiuse_cmp(i32 %x, i32 %y, i32 %z, i32 %w) {
define i32 @shift_no_xor_multiuse_cmp_with_xor(i32 %x, i32 %y, i32 %z, i32 %w) {
; CHECK-LABEL: @shift_no_xor_multiuse_cmp_with_xor(
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 1
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
-; CHECK-NEXT: [[TMP1:%.*]] = shl nuw nsw i32 [[AND]], 1
-; CHECK-NEXT: [[SELECT:%.*]] = xor i32 [[Y:%.*]], [[TMP1]]
-; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP]], i32 [[Z:%.*]], i32 [[W:%.*]]
-; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[SELECT2]]
+; CHECK-NEXT: [[CMP:%.*]] = trunc i32 [[X:%.*]] to i1
+; CHECK-NEXT: [[Z:%.*]] = xor i32 [[W:%.*]], 2
+; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP]], i32 [[Z]], i32 [[W]]
+; CHECK-NEXT: [[SELECT3:%.*]] = select i1 [[CMP]], i32 [[W1:%.*]], i32 [[Z1:%.*]]
+; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT2]], [[SELECT3]]
; CHECK-NEXT: ret i32 [[RES]]
;
%and = and i32 %x, 1
@@ -1091,10 +1083,9 @@ define i32 @shift_no_xor_multiuse_cmp_with_xor(i32 %x, i32 %y, i32 %z, i32 %w) {
define i32 @shift_no_xor_multiuse_cmp_with_and(i32 %x, i32 %y, i32 %z, i32 %w) {
; CHECK-LABEL: @shift_no_xor_multiuse_cmp_with_and(
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 1
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
+; CHECK-NEXT: [[CMP:%.*]] = trunc i32 [[X:%.*]] to i1
; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y:%.*]], -3
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[AND2]]
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[AND2]], i32 [[Y]]
; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP]], i32 [[Z:%.*]], i32 [[W:%.*]]
; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[SELECT2]]
; CHECK-NEXT: ret i32 [[RES]]
@@ -1279,10 +1270,9 @@ define i32 @shift_xor_multiuse_cmp_with_and(i32 %x, i32 %y, i32 %z, i32 %w) {
define i32 @shift_no_xor_multiuse_cmp_or(i32 %x, i32 %y, i32 %z, i32 %w) {
; CHECK-LABEL: @shift_no_xor_multiuse_cmp_or(
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 1
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
+; CHECK-NEXT: [[CMP:%.*]] = trunc i32 [[X:%.*]] to i1
; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], 2
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[OR]]
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[OR]], i32 [[Y]]
; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP]], i32 [[Z:%.*]], i32 [[W:%.*]]
; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[SELECT2]]
; CHECK-NEXT: [[RES2:%.*]] = mul i32 [[RES]], [[OR]]
@@ -1300,10 +1290,9 @@ define i32 @shift_no_xor_multiuse_cmp_or(i32 %x, i32 %y, i32 %z, i32 %w) {
define i32 @shift_no_xor_multiuse_cmp_xor(i32 %x, i32 %y, i32 %z, i32 %w) {
; CHECK-LABEL: @shift_no_xor_multiuse_cmp_xor(
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 1
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
+; CHECK-NEXT: [[CMP:%.*]] = trunc i32 [[X:%.*]] to i1
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 2
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[XOR]]
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[XOR]], i32 [[Y]]
; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP]], i32 [[Z:%.*]], i32 [[W:%.*]]
; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[SELECT2]]
; CHECK-NEXT: [[RES2:%.*]] = mul i32 [[RES]], [[XOR]]
@@ -1321,10 +1310,9 @@ define i32 @shift_no_xor_multiuse_cmp_xor(i32 %x, i32 %y, i32 %z, i32 %w) {
define i32 @shift_no_xor_multiuse_cmp_and(i32 %x, i32 %y, i32 %z, i32 %w) {
; CHECK-LABEL: @shift_no_xor_multiuse_cmp_and(
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 1
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
+; CHECK-NEXT: [[CMP:%.*]] = trunc i32 [[X:%.*]] to i1
; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y:%.*]], -3
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[AND2]]
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[AND2]], i32 [[Y]]
; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP]], i32 [[Z:%.*]], i32 [[W:%.*]]
; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[SELECT2]]
; CHECK-NEXT: [[RES2:%.*]] = mul i32 [[RES]], [[AND2]]
@@ -1652,10 +1640,9 @@ define i8 @clear_bits_extra_use2(i8 %x, i1 %b) {
; Tests factoring in cost of saving the `and`
define i64 @xor_i8_to_i64_shl_save_and_eq(i8 %x, i64 %y) {
; CHECK-LABEL: @xor_i8_to_i64_shl_save_and_eq(
-; CHECK-NEXT: [[XX:%.*]] = and i8 [[X:%.*]], 1
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[XX]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i8 [[X:%.*]] to i1
; CHECK-NEXT: [[Z:%.*]] = xor i64 [[Y:%.*]], -9223372036854775808
-; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP]], i64 [[Z]], i64 [[Y]]
+; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP1]], i64 [[Y]], i64 [[Z]]
; CHECK-NEXT: ret i64 [[R]]
;
%xx = and i8 %x, 1
@@ -1681,10 +1668,9 @@ define i64 @xor_i8_to_i64_shl_save_and_ne(i8 %x, i64 %y) {
define i32 @select_icmp_eq_and_1_0_srem_2_fail_null_identity(i32 %x, i32 %y) {
; CHECK-LABEL: @select_icmp_eq_and_1_0_srem_2_fail_null_identity(
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 1
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i1
; CHECK-NEXT: [[XOR:%.*]] = srem i32 [[Y:%.*]], 2
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[XOR]]
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[TMP1]], i32 [[XOR]], i32 [[Y]]
; CHECK-NEXT: ret i32 [[SELECT]]
;
%and = and i32 %x, 1
@@ -1697,10 +1683,9 @@ define i32 @select_icmp_eq_and_1_0_srem_2_fail_null_identity(i32 %x, i32 %y) {
define i32 @select_icmp_eq_and_1_0_sdiv_2_fail_null_1_identity(i32 %x, i32 %y) {
; CHECK-LABEL: @select_icmp_eq_and_1_0_sdiv_2_fail_null_1_identity(
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 1
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i1
; CHECK-NEXT: [[XOR:%.*]] = sdiv i32 [[Y:%.*]], 2
-; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[XOR]]
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[TMP1]], i32 [[XOR]], i32 [[Y]]
; CHECK-NEXT: ret i32 [[SELECT]]
;
%and = and i32 %x, 1
diff --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll
index a1e84fad9a827..2da75ad917eee 100644
--- a/llvm/test/Transforms/InstCombine/select.ll
+++ b/llvm/test/Transforms/InstCombine/select.ll
@@ -5009,10 +5009,9 @@ define i8 @test_replace_freeze_oneuse(i1 %x, i8 %y) {
define i8 @select_knownbits_simplify(i8 noundef %x) {
; CHECK-LABEL: define i8 @select_knownbits_simplify(
; CHECK-SAME: i8 noundef [[X:%.*]]) {
-; CHECK-NEXT: [[X_LO:%.*]] = and i8 [[X]], 1
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X_LO]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i8 [[X]] to i1
; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], -2
-; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i8 [[AND]], i8 0
+; CHECK-NEXT: [[RES:%.*]] = select i1 [[TMP1]], i8 0, i8 [[AND]]
; CHECK-NEXT: ret i8 [[RES]]
;
%x.lo = and i8 %x, 1
@@ -5025,11 +5024,10 @@ define i8 @select_knownbits_simplify(i8 noundef %x) {
define i8 @select_knownbits_simplify_nested(i8 noundef %x) {
; CHECK-LABEL: define i8 @select_knownbits_simplify_nested(
; CHECK-SAME: i8 noundef [[X:%.*]]) {
-; CHECK-NEXT: [[X_LO:%.*]] = and i8 [[X]], 1
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X_LO]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i8 [[X]] to i1
; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], -2
; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[AND]], [[AND]]
-; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i8 [[MUL]], i8 0
+; CHECK-NEXT: [[RES:%.*]] = select i1 [[TMP1]], i8 0, i8 [[MUL]]
; CHECK-NEXT: ret i8 [[RES]]
;
%x.lo = and i8 %x, 1
@@ -5043,10 +5041,9 @@ define i8 @select_knownbits_simplify_nested(i8 noundef %x) {
define i8 @select_knownbits_simplify_missing_noundef(i8 %x) {
; CHECK-LABEL: define i8 @select_knownbits_simplify_missing_noundef(
; CHECK-SAME: i8 [[X:%.*]]) {
-; CHECK-NEXT: [[X_LO:%.*]] = and i8 [[X]], 1
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X_LO]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i8 [[X]] to i1
; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], -2
-; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i8 [[AND]], i8 0
+; CHECK-NEXT: [[RES:%.*]] = select i1 [[TMP1]], i8 0, i8 [[AND]]
; CHECK-NEXT: ret i8 [[RES]]
;
%x.lo = and i8 %x, 1
diff --git a/llvm/test/Transforms/InstCombine/set.ll b/llvm/test/Transforms/InstCombine/set.ll
index a1d81903ca9ea..81f3c169f7838 100644
--- a/llvm/test/Transforms/InstCombine/set.ll
+++ b/llvm/test/Transforms/InstCombine/set.ll
@@ -478,8 +478,9 @@ define i1 @test22_logical(i32 %A, i32 %X) {
define i32 @test23(i32 %a) {
; CHECK-LABEL: @test23(
-; CHECK-NEXT: [[TMP_1:%.*]] = and i32 [[A:%.*]], 1
-; CHECK-NEXT: [[TMP_3:%.*]] = xor i32 [[TMP_1]], 1
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[A:%.*]] to i1
+; CHECK-NEXT: [[TMP_2:%.*]] = xor i1 [[TMP1]], true
+; CHECK-NEXT: [[TMP_3:%.*]] = zext i1 [[TMP_2]] to i32
; CHECK-NEXT: ret i32 [[TMP_3]]
;
%tmp.1 = and i32 %a, 1
@@ -490,8 +491,9 @@ define i32 @test23(i32 %a) {
define <2 x i32> @test23vec(<2 x i32> %a) {
; CHECK-LABEL: @test23vec(
-; CHECK-NEXT: [[TMP_1:%.*]] = and <2 x i32> [[A:%.*]], splat (i32 1)
-; CHECK-NEXT: [[TMP_3:%.*]] = xor <2 x i32> [[TMP_1]], splat (i32 1)
+; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[A:%.*]] to <2 x i1>
+; CHECK-NEXT: [[TMP_2:%.*]] = xor <2 x i1> [[TMP1]], splat (i1 true)
+; CHECK-NEXT: [[TMP_3:%.*]] = zext <2 x i1> [[TMP_2]] to <2 x i32>
; CHECK-NEXT: ret <2 x i32> [[TMP_3]]
;
%tmp.1 = and <2 x i32> %a, <i32 1, i32 1>
diff --git a/llvm/test/Transforms/InstCombine/shift-direction-in-bit-test.ll b/llvm/test/Transforms/InstCombine/shift-direction-in-bit-test.ll
index 5d63545b08e9a..71c57176b51ec 100644
--- a/llvm/test/Transforms/InstCombine/shift-direction-in-bit-test.ll
+++ b/llvm/test/Transforms/InstCombine/shift-direction-in-bit-test.ll
@@ -226,8 +226,8 @@ define i1 @t12_shift_of_const0(i32 %x, i32 %y, i32 %z) {
define i1 @t13_shift_of_const1(i32 %x, i32 %y, i32 %z) {
; CHECK-LABEL: @t13_shift_of_const1(
; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[Y:%.*]], 0
-; CHECK-NEXT: [[T1:%.*]] = and i32 [[Z:%.*]], 1
-; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
+; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[Z:%.*]] to i1
+; CHECK-NEXT: [[T2:%.*]] = xor i1 [[TMP2]], true
; CHECK-NEXT: [[T3:%.*]] = select i1 [[TMP1]], i1 true, i1 [[T2]]
; CHECK-NEXT: ret i1 [[T3]]
;
@@ -239,10 +239,9 @@ define i1 @t13_shift_of_const1(i32 %x, i32 %y, i32 %z) {
define i1 @t14_and_with_const0(i32 %x, i32 %y, i32 %z) {
; CHECK-LABEL: @t14_and_with_const0(
-; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[Y:%.*]], 0
-; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[X:%.*]], 1
-; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[TMP2]], 0
-; CHECK-NEXT: [[T3:%.*]] = select i1 [[TMP1]], i1 true, i1 [[T2]]
+; CHECK-NEXT: [[T0:%.*]] = shl i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[T0]] to i1
+; CHECK-NEXT: [[T3:%.*]] = xor i1 [[TMP1]], true
; CHECK-NEXT: ret i1 [[T3]]
;
%t0 = shl i32 %x, %y
@@ -252,9 +251,9 @@ define i1 @t14_and_with_const0(i32 %x, i32 %y, i32 %z) {
}
define i1 @t15_and_with_const1(i32 %x, i32 %y, i32 %z) {
; CHECK-LABEL: @t15_and_with_const1(
-; CHECK-NEXT: [[TMP1:%.*]] = shl nuw i32 1, [[Y:%.*]]
-; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[X:%.*]], [[TMP1]]
-; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[TMP2]], 0
+; CHECK-NEXT: [[T0:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[T0]] to i1
+; CHECK-NEXT: [[T2:%.*]] = xor i1 [[TMP1]], true
; CHECK-NEXT: ret i1 [[T2]]
;
%t0 = lshr i32 %x, %y
diff --git a/llvm/test/Transforms/InstCombine/shl-unsigned-cmp-const.ll b/llvm/test/Transforms/InstCombine/shl-unsigned-cmp-const.ll
index 6d6bcb3c46c46..ef731afd6d9c9 100644
--- a/llvm/test/Transforms/InstCombine/shl-unsigned-cmp-const.ll
+++ b/llvm/test/Transforms/InstCombine/shl-unsigned-cmp-const.ll
@@ -33,8 +33,8 @@ define i1 @scalar_i8_shl_ult_const_2(i8 %x) {
; C2 Shift amount greater than C1 trailing zeros.
define i1 @scalar_i8_shl_ult_const_3(i8 %x) {
; CHECK-LABEL: @scalar_i8_shl_ult_const_3(
-; CHECK-NEXT: [[SHL_MASK:%.*]] = and i8 [[X:%.*]], 1
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[SHL_MASK]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i8 [[X:%.*]] to i1
+; CHECK-NEXT: [[CMP:%.*]] = xor i1 [[TMP1]], true
; CHECK-NEXT: ret i1 [[CMP]]
;
%shl = shl i8 %x, 7
diff --git a/llvm/test/Transforms/InstCombine/signed-truncation-check.ll b/llvm/test/Transforms/InstCombine/signed-truncation-check.ll
index 8015af59f4f81..1f90c4351e0d6 100644
--- a/llvm/test/Transforms/InstCombine/signed-truncation-check.ll
+++ b/llvm/test/Transforms/InstCombine/signed-truncation-check.ll
@@ -832,11 +832,11 @@ define i1 @negative_with_uniform_bad_mask_logical(i32 %arg) {
define i1 @negative_with_wrong_mask(i32 %arg) {
; CHECK-LABEL: @negative_with_wrong_mask(
-; CHECK-NEXT: [[T1:%.*]] = and i32 [[ARG:%.*]], 1
-; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[ARG:%.*]] to i1
+; CHECK-NEXT: [[T2:%.*]] = xor i1 [[TMP1]], true
; CHECK-NEXT: [[T3:%.*]] = add i32 [[ARG]], 128
; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[T3]], 256
-; CHECK-NEXT: [[T5:%.*]] = and i1 [[T2]], [[T4]]
+; CHECK-NEXT: [[T5:%.*]] = and i1 [[T4]], [[T2]]
; CHECK-NEXT: ret i1 [[T5]]
;
%t1 = and i32 %arg, 1 ; not even checking the right mask
@@ -849,11 +849,11 @@ define i1 @negative_with_wrong_mask(i32 %arg) {
define i1 @negative_with_wrong_mask_logical(i32 %arg) {
; CHECK-LABEL: @negative_with_wrong_mask_logical(
-; CHECK-NEXT: [[T1:%.*]] = and i32 [[ARG:%.*]], 1
-; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[ARG:%.*]] to i1
+; CHECK-NEXT: [[T2:%.*]] = xor i1 [[TMP1]], true
; CHECK-NEXT: [[T3:%.*]] = add i32 [[ARG]], 128
; CHECK-NEXT: [[T4:%.*]] = icmp ult i32 [[T3]], 256
-; CHECK-NEXT: [[T5:%.*]] = and i1 [[T2]], [[T4]]
+; CHECK-NEXT: [[T5:%.*]] = and i1 [[T4]], [[T2]]
; CHECK-NEXT: ret i1 [[T5]]
;
%t1 = and i32 %arg, 1 ; not even checking the right mask
diff --git a/llvm/test/Transforms/InstCombine/zext-or-icmp.ll b/llvm/test/Transforms/InstCombine/zext-or-icmp.ll
index feb4be9e37050..c2e5b351a19dc 100644
--- a/llvm/test/Transforms/InstCombine/zext-or-icmp.ll
+++ b/llvm/test/Transforms/InstCombine/zext-or-icmp.ll
@@ -3,10 +3,10 @@
define i8 @zext_or_icmp_icmp(i8 %a, i8 %b) {
; CHECK-LABEL: @zext_or_icmp_icmp(
-; CHECK-NEXT: [[MASK:%.*]] = and i8 [[A:%.*]], 1
-; CHECK-NEXT: [[TOBOOL1:%.*]] = icmp eq i8 [[MASK]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i8 [[A:%.*]] to i1
+; CHECK-NEXT: [[TOBOOL1:%.*]] = xor i1 [[TMP1]], true
; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp eq i8 [[B:%.*]], 0
-; CHECK-NEXT: [[BOTHCOND:%.*]] = or i1 [[TOBOOL1]], [[TOBOOL2]]
+; CHECK-NEXT: [[BOTHCOND:%.*]] = or i1 [[TOBOOL2]], [[TOBOOL1]]
; CHECK-NEXT: [[ZEXT:%.*]] = zext i1 [[BOTHCOND]] to i8
; CHECK-NEXT: ret i8 [[ZEXT]]
;
@@ -20,8 +20,8 @@ define i8 @zext_or_icmp_icmp(i8 %a, i8 %b) {
define i8 @zext_or_icmp_icmp_logical(i8 %a, i8 %b) {
; CHECK-LABEL: @zext_or_icmp_icmp_logical(
-; CHECK-NEXT: [[MASK:%.*]] = and i8 [[A:%.*]], 1
-; CHECK-NEXT: [[TOBOOL1:%.*]] = icmp eq i8 [[MASK]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i8 [[A:%.*]] to i1
+; CHECK-NEXT: [[TOBOOL1:%.*]] = xor i1 [[TMP1]], true
; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp eq i8 [[B:%.*]], 0
; CHECK-NEXT: [[BOTHCOND:%.*]] = select i1 [[TOBOOL1]], i1 true, i1 [[TOBOOL2]]
; CHECK-NEXT: [[ZEXT:%.*]] = zext i1 [[BOTHCOND]] to i8
@@ -151,9 +151,9 @@ define i32 @select_zext_or_eq_ult_add(i32 %i) {
define i32 @PR49475(i32 %x, i16 %y) {
; CHECK-LABEL: @PR49475(
-; CHECK-NEXT: [[M:%.*]] = and i16 [[Y:%.*]], 1
; CHECK-NEXT: [[B1:%.*]] = icmp eq i32 [[X:%.*]], 0
-; CHECK-NEXT: [[B2:%.*]] = icmp eq i16 [[M]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i16 [[Y:%.*]] to i1
+; CHECK-NEXT: [[B2:%.*]] = xor i1 [[TMP1]], true
; CHECK-NEXT: [[T1:%.*]] = or i1 [[B1]], [[B2]]
; CHECK-NEXT: [[Z:%.*]] = zext i1 [[T1]] to i32
; CHECK-NEXT: ret i32 [[Z]]
More information about the llvm-commits
mailing list