[llvm] [InstCombine] Generalizing icmp ne X, 0 to trunc X to i1 IIF X in range (0,2] (PR #184182)

Andreas Jonson via llvm-commits llvm-commits at lists.llvm.org
Sat Jun 27 03:21:01 PDT 2026


https://github.com/andjo403 updated https://github.com/llvm/llvm-project/pull/184182

>From 120e10faf8e9c81b36e899e5bed10df5d8014fe6 Mon Sep 17 00:00:00 2001
From: Andreas Jonson <andjo403 at hotmail.com>
Date: Mon, 2 Mar 2026 18:06:29 +0100
Subject: [PATCH] [InstCombine] Generalizing icmp ne X, 0 to trunc X to i1 IIF
 X in range (0,2]

removes the icmp ne (and X, 1), 0 to trunc X to i1 fold that will no longer trigger
---
 .../InstCombine/InstCombineCompares.cpp       | 10 +++---
 .../Transforms/InstCombine/and-or-icmps.ll    | 12 +++----
 .../test/Transforms/InstCombine/icmp-range.ll |  4 +--
 .../Transforms/InstCombine/icmp-shr-lt-gt.ll  |  2 +-
 .../Transforms/InstCombine/icmp-usub-sat.ll   |  2 +-
 llvm/test/Transforms/InstCombine/icmp.ll      |  2 +-
 .../InstCombine/known-phi-recurse.ll          |  4 +--
 llvm/test/Transforms/InstCombine/narrow.ll    |  2 +-
 llvm/test/Transforms/InstCombine/pr12251.ll   | 15 ++++++---
 ...ciation-in-bittest-with-truncation-lshr.ll | 32 ++++++++++++++-----
 ...ociation-in-bittest-with-truncation-shl.ll |  8 ++---
 .../shift-amount-reassociation-in-bittest.ll  |  4 +--
 .../InstCombine/vector-casts-inseltpoison.ll  |  5 +--
 .../Transforms/InstCombine/vector-casts.ll    |  5 +--
 14 files changed, 61 insertions(+), 46 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index e6deb548819e8..be67277d048e7 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -1787,10 +1787,6 @@ Instruction *InstCombinerImpl::foldICmpAndConstConst(ICmpInst &Cmp,
                                                      const APInt &C1) {
   bool isICMP_NE = Cmp.getPredicate() == ICmpInst::ICMP_NE;
 
-  // 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());
-
   const APInt *C2;
   Value *X;
   if (!match(And, m_And(m_Value(X), m_APInt(C2))))
@@ -7115,6 +7111,12 @@ Instruction *InstCombinerImpl::foldICmpUsingKnownBits(ICmpInst &I) {
           *LHSC != Op0KnownZeroInverted)
         LHS = Op0;
 
+      if (Pred == CmpInst::ICMP_NE && Ty->isIntOrIntVectorTy() &&
+          Op0Known.getMaxValue() == 1)
+        return replaceInstUsesWith(I,
+                                   Builder.CreateTrunc(LHS, I.getType(), "",
+                                                       /*IsNUW=*/LHS == Op0));
+
       Value *X;
       const APInt *C1;
       if (match(LHS, m_Shl(m_Power2(C1), m_Value(X)))) {
diff --git a/llvm/test/Transforms/InstCombine/and-or-icmps.ll b/llvm/test/Transforms/InstCombine/and-or-icmps.ll
index 91b9f702f4575..e3cc0e8437025 100644
--- a/llvm/test/Transforms/InstCombine/and-or-icmps.ll
+++ b/llvm/test/Transforms/InstCombine/and-or-icmps.ll
@@ -3457,12 +3457,10 @@ define i1 @and_ugt_to_mask_off_by_one(i8 %x) {
   ret i1 %and2
 }
 
-; TODO: shall fold to trunc nuw i8 (and %x, %y) to i1.
 define i1 @and_icmp_ne_with_binary_range_operands(i8 range(i8 0, 2) %x, i8 range(i8 0, 2) %y) {
 ; CHECK-LABEL: @and_icmp_ne_with_binary_range_operands(
-; CHECK-NEXT:    [[ICMP1:%.*]] = icmp ne i8 [[X:%.*]], 0
-; CHECK-NEXT:    [[ICMP2:%.*]] = icmp ne i8 [[Y:%.*]], 0
-; CHECK-NEXT:    [[RET:%.*]] = and i1 [[ICMP1]], [[ICMP2]]
+; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = trunc nuw i8 [[TMP1]] to i1
 ; CHECK-NEXT:    ret i1 [[RET]]
 ;
   %icmp1 = icmp ne i8 %x, 0
@@ -3471,12 +3469,10 @@ define i1 @and_icmp_ne_with_binary_range_operands(i8 range(i8 0, 2) %x, i8 range
   ret i1 %ret
 }
 
-; TODO: shall fold to trunc nuw i8 (and %x, %y) to i1.
 define i1 @and_icmp_eq_with_binary_range_operands(i8 range(i8 0, 2) %x, i8 range(i8 0, 2) %y) {
 ; CHECK-LABEL: @and_icmp_eq_with_binary_range_operands(
-; CHECK-NEXT:    [[ICMP1:%.*]] = icmp ne i8 [[X:%.*]], 0
-; CHECK-NEXT:    [[ICMP2:%.*]] = icmp ne i8 [[Y:%.*]], 0
-; CHECK-NEXT:    [[RET:%.*]] = and i1 [[ICMP1]], [[ICMP2]]
+; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = trunc nuw i8 [[TMP1]] to i1
 ; CHECK-NEXT:    ret i1 [[RET]]
 ;
   %icmp1 = icmp eq i8 %x, 1
diff --git a/llvm/test/Transforms/InstCombine/icmp-range.ll b/llvm/test/Transforms/InstCombine/icmp-range.ll
index 1970694cf9c42..ea8fb1ff1b23e 100644
--- a/llvm/test/Transforms/InstCombine/icmp-range.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-range.ll
@@ -1174,7 +1174,7 @@ define i1 @icmp_eq_bool_0(ptr %ptr) {
 define i1 @icmp_eq_bool_1(ptr %ptr) {
 ; CHECK-LABEL: @icmp_eq_bool_1(
 ; CHECK-NEXT:    [[VAL:%.*]] = load i64, ptr [[PTR:%.*]], align 8, !range [[RNG6]]
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i64 [[VAL]], 0
+; CHECK-NEXT:    [[CMP:%.*]] = trunc nuw i64 [[VAL]] to i1
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %val = load i64, ptr %ptr, align 8, !range !{i64 0, i64 2}
@@ -1185,7 +1185,7 @@ define i1 @icmp_eq_bool_1(ptr %ptr) {
 define i1 @icmp_ne_bool_0(ptr %ptr) {
 ; CHECK-LABEL: @icmp_ne_bool_0(
 ; CHECK-NEXT:    [[VAL:%.*]] = load i64, ptr [[PTR:%.*]], align 8, !range [[RNG6]]
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i64 [[VAL]], 0
+; CHECK-NEXT:    [[CMP:%.*]] = trunc nuw i64 [[VAL]] to i1
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %val = load i64, ptr %ptr, align 8, !range !{i64 0, i64 2}
diff --git a/llvm/test/Transforms/InstCombine/icmp-shr-lt-gt.ll b/llvm/test/Transforms/InstCombine/icmp-shr-lt-gt.ll
index 70f2539184761..fa137deb75c6f 100644
--- a/llvm/test/Transforms/InstCombine/icmp-shr-lt-gt.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-shr-lt-gt.ll
@@ -2086,7 +2086,7 @@ define i1 @lshrugt_02_15_exact(i4 %x) {
 
 define i1 @lshrugt_03_00_exact(i4 %x) {
 ; CHECK-LABEL: @lshrugt_03_00_exact(
-; CHECK-NEXT:    [[C:%.*]] = icmp ne i4 [[X:%.*]], 0
+; CHECK-NEXT:    [[C:%.*]] = icmp slt i4 [[X:%.*]], 0
 ; CHECK-NEXT:    ret i1 [[C]]
 ;
   %s = lshr exact i4 %x, 3
diff --git a/llvm/test/Transforms/InstCombine/icmp-usub-sat.ll b/llvm/test/Transforms/InstCombine/icmp-usub-sat.ll
index 2cd07b17af580..5662056dbee83 100644
--- a/llvm/test/Transforms/InstCombine/icmp-usub-sat.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-usub-sat.ll
@@ -259,7 +259,7 @@ define i1 @icmp_eq_multiuse_negative(i8 %arg) {
 ; CHECK-LABEL: define i1 @icmp_eq_multiuse_negative
 ; CHECK-SAME: (i8 [[ARG:%.*]]) {
 ; CHECK-NEXT:    [[SUB:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[ARG]], i8 -2)
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[ARG]], -1
+; CHECK-NEXT:    [[CMP:%.*]] = trunc nuw i8 [[SUB]] to i1
 ; CHECK-NEXT:    call void @use.i8(i8 [[SUB]])
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
diff --git a/llvm/test/Transforms/InstCombine/icmp.ll b/llvm/test/Transforms/InstCombine/icmp.ll
index 61ae46ba08d2d..c6336817fd557 100644
--- a/llvm/test/Transforms/InstCombine/icmp.ll
+++ b/llvm/test/Transforms/InstCombine/icmp.ll
@@ -5295,7 +5295,7 @@ define i1 @zext_bool_and_ne0_use(i1 %x, i64 %y) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = and i64 [[Y]], 1
 ; CHECK-NEXT:    [[A:%.*]] = select i1 [[X]], i64 [[TMP1]], i64 0
 ; CHECK-NEXT:    call void @use_i64(i64 [[A]])
-; CHECK-NEXT:    [[R:%.*]] = icmp ne i64 [[A]], 0
+; CHECK-NEXT:    [[R:%.*]] = trunc nuw i64 [[A]] to i1
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
   %zx = zext i1 %x to i64
diff --git a/llvm/test/Transforms/InstCombine/known-phi-recurse.ll b/llvm/test/Transforms/InstCombine/known-phi-recurse.ll
index 657ef26e6ffb9..9d61a229161ee 100644
--- a/llvm/test/Transforms/InstCombine/known-phi-recurse.ll
+++ b/llvm/test/Transforms/InstCombine/known-phi-recurse.ll
@@ -164,8 +164,8 @@ define i32 @knownbits_phi_select_test1(ptr %p1, ptr %p2, i8 %x) {
 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i16 [[MASK]], 0
 ; CHECK-NEXT:    br i1 [[CMP1]], label [[BB2]], label [[BB1]]
 ; CHECK:       bb1:
-; CHECK-NEXT:    [[CMP2:%.*]] = icmp ne i32 [[INDVAR4]], 0
-; CHECK-NEXT:    [[CMP3:%.*]] = icmp ne i32 [[INDVAR5]], 0
+; CHECK-NEXT:    [[CMP2:%.*]] = trunc nuw i32 [[INDVAR4]] to i1
+; CHECK-NEXT:    [[CMP3:%.*]] = trunc nuw i32 [[INDVAR5]] to i1
 ; CHECK-NEXT:    [[OR_COND:%.*]] = select i1 [[CMP2]], i1 true, i1 [[CMP3]]
 ; CHECK-NEXT:    br i1 [[OR_COND]], label [[BB2]], label [[EXIT]]
 ; CHECK:       bb2:
diff --git a/llvm/test/Transforms/InstCombine/narrow.ll b/llvm/test/Transforms/InstCombine/narrow.ll
index 3161d284b637f..c3055513505f7 100644
--- a/llvm/test/Transforms/InstCombine/narrow.ll
+++ b/llvm/test/Transforms/InstCombine/narrow.ll
@@ -160,7 +160,7 @@ define i1 @searchArray2(i32 %hay, ptr %haystack) {
 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i64 [[INDVAR_NEXT]], 1000
 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[EXIT:%.*]], label [[LOOP]]
 ; CHECK:       exit:
-; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i8 [[AND]], 0
+; CHECK-NEXT:    [[TOBOOL:%.*]] = trunc nuw i8 [[AND]] to i1
 ; CHECK-NEXT:    ret i1 [[TOBOOL]]
 ;
 entry:
diff --git a/llvm/test/Transforms/InstCombine/pr12251.ll b/llvm/test/Transforms/InstCombine/pr12251.ll
index 1041bdc67b63a..679ad864b45e3 100644
--- a/llvm/test/Transforms/InstCombine/pr12251.ll
+++ b/llvm/test/Transforms/InstCombine/pr12251.ll
@@ -1,6 +1,14 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
 
 define zeroext i1 @_Z3fooPb(ptr nocapture %x) {
+; CHECK-LABEL: define zeroext i1 @_Z3fooPb(
+; CHECK-SAME: ptr captures(none) [[X:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[A:%.*]] = load i8, ptr [[X]], align 1, !range [[RNG0:![0-9]+]]
+; CHECK-NEXT:    [[TOBOOL:%.*]] = trunc nuw i8 [[A]] to i1
+; CHECK-NEXT:    ret i1 [[TOBOOL]]
+;
 entry:
   %a = load i8, ptr %x, align 1, !range !0
   %b = and i8 %a, 1
@@ -8,8 +16,7 @@ entry:
   ret i1 %tobool
 }
 
-; CHECK: %a = load i8, ptr %x, align 1, !range !0
-; CHECK-NEXT: %tobool = icmp ne i8 %a, 0
-; CHECK-NEXT: ret i1 %tobool
-
 !0 = !{i8 0, i8 2}
+;.
+; CHECK: [[RNG0]] = !{i8 0, i8 2}
+;.
diff --git a/llvm/test/Transforms/InstCombine/shift-amount-reassociation-in-bittest-with-truncation-lshr.ll b/llvm/test/Transforms/InstCombine/shift-amount-reassociation-in-bittest-with-truncation-lshr.ll
index 006b06cfc7669..d700bc1ba2505 100644
--- a/llvm/test/Transforms/InstCombine/shift-amount-reassociation-in-bittest-with-truncation-lshr.ll
+++ b/llvm/test/Transforms/InstCombine/shift-amount-reassociation-in-bittest-with-truncation-lshr.ll
@@ -205,8 +205,8 @@ define <2 x i1> @n6_vec(<2 x i64> %y, <2 x i32> %len) {
 ; New shift amount would be 16, minimal count of leading zeros in %x is 47. Ok.
 define <2 x i1> @t7_vec(<2 x i32> %x, <2 x i32> %len) {
 ; CHECK-LABEL: @t7_vec(
-; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 1, i32 0>
-; CHECK-NEXT:    [[T5:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
+; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[X:%.*]] to <2 x i1>
+; CHECK-NEXT:    [[T5:%.*]] = and <2 x i1> [[TMP1]], <i1 true, i1 false>
 ; CHECK-NEXT:    ret <2 x i1> [[T5]]
 ;
   %t0 = sub <2 x i32> <i32 32, i32 32>, %len
@@ -251,7 +251,7 @@ define i1 @t9_highest_bit(i32 %x, i64 %y, i32 %len) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = zext i32 [[X:%.*]] to i64
 ; CHECK-NEXT:    [[TMP2:%.*]] = lshr i64 [[Y:%.*]], 63
 ; CHECK-NEXT:    [[TMP3:%.*]] = and i64 [[TMP2]], [[TMP1]]
-; CHECK-NEXT:    [[T5:%.*]] = icmp ne i64 [[TMP3]], 0
+; CHECK-NEXT:    [[T5:%.*]] = trunc nuw i64 [[TMP3]] to i1
 ; CHECK-NEXT:    ret i1 [[T5]]
 ;
   %t0 = sub i32 64, %len
@@ -397,7 +397,15 @@ define i1 @t13_x_is_one(i64 %y, i32 %len) {
 }
 define i1 @t14_x_is_one(i32 %x, i32 %len) {
 ; CHECK-LABEL: @t14_x_is_one(
-; CHECK-NEXT:    ret i1 false
+; CHECK-NEXT:    [[T0:%.*]] = sub i32 32, [[LEN:%.*]]
+; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[X:%.*]], [[T0]]
+; CHECK-NEXT:    [[T2:%.*]] = add i32 [[LEN]], -16
+; CHECK-NEXT:    [[T2_WIDE:%.*]] = zext nneg i32 [[T2]] to i64
+; CHECK-NEXT:    [[T3:%.*]] = lshr i64 1, [[T2_WIDE]]
+; CHECK-NEXT:    [[T3_TRUNC:%.*]] = trunc nuw nsw i64 [[T3]] to i32
+; CHECK-NEXT:    [[T4:%.*]] = and i32 [[T1]], [[T3_TRUNC]]
+; CHECK-NEXT:    [[T5:%.*]] = trunc nuw i32 [[T4]] to i1
+; CHECK-NEXT:    ret i1 [[T5]]
 ;
   %t0 = sub i32 32, %len
   %t1 = shl i32 %x, %t0
@@ -412,10 +420,10 @@ define i1 @t14_x_is_one(i32 %x, i32 %len) {
 
 define <2 x i1> @t15_vec_x_is_one_or_zero(<2 x i64> %y, <2 x i32> %len) {
 ; CHECK-LABEL: @t15_vec_x_is_one_or_zero(
-; CHECK-NEXT:    [[TMP1:%.*]] = lshr <2 x i64> [[Y:%.*]], splat (i64 48)
-; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i64> [[TMP1]], <i64 1, i64 0>
+; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i64> [[Y:%.*]], splat (i64 281474976710656)
 ; CHECK-NEXT:    [[T5:%.*]] = icmp ne <2 x i64> [[TMP2]], zeroinitializer
-; CHECK-NEXT:    ret <2 x i1> [[T5]]
+; CHECK-NEXT:    [[T6:%.*]] = and <2 x i1> [[T5]], <i1 true, i1 false>
+; CHECK-NEXT:    ret <2 x i1> [[T6]]
 ;
   %t0 = sub <2 x i32> <i32 64, i32 64>, %len
   %t1 = shl <2 x i32> <i32 1, i32 0>, %t0
@@ -429,7 +437,15 @@ define <2 x i1> @t15_vec_x_is_one_or_zero(<2 x i64> %y, <2 x i32> %len) {
 }
 define <2 x i1> @t16_vec_y_is_one_or_zero(<2 x i32> %x, <2 x i32> %len) {
 ; CHECK-LABEL: @t16_vec_y_is_one_or_zero(
-; CHECK-NEXT:    ret <2 x i1> zeroinitializer
+; CHECK-NEXT:    [[T0:%.*]] = sub <2 x i32> splat (i32 64), [[LEN:%.*]]
+; CHECK-NEXT:    [[T1:%.*]] = shl <2 x i32> [[X:%.*]], [[T0]]
+; CHECK-NEXT:    [[T2:%.*]] = add <2 x i32> [[LEN]], splat (i32 -16)
+; CHECK-NEXT:    [[T2_WIDE:%.*]] = zext nneg <2 x i32> [[T2]] to <2 x i64>
+; CHECK-NEXT:    [[T3:%.*]] = lshr <2 x i64> <i64 1, i64 0>, [[T2_WIDE]]
+; CHECK-NEXT:    [[T3_TRUNC:%.*]] = trunc nuw nsw <2 x i64> [[T3]] to <2 x i32>
+; CHECK-NEXT:    [[T4:%.*]] = and <2 x i32> [[T1]], [[T3_TRUNC]]
+; CHECK-NEXT:    [[T5:%.*]] = trunc nuw <2 x i32> [[T4]] to <2 x i1>
+; CHECK-NEXT:    ret <2 x i1> [[T5]]
 ;
   %t0 = sub <2 x i32> <i32 64, i32 64>, %len
   %t1 = shl <2 x i32> %x, %t0
diff --git a/llvm/test/Transforms/InstCombine/shift-amount-reassociation-in-bittest-with-truncation-shl.ll b/llvm/test/Transforms/InstCombine/shift-amount-reassociation-in-bittest-with-truncation-shl.ll
index 2c508c0c47472..21ea443185dc3 100644
--- a/llvm/test/Transforms/InstCombine/shift-amount-reassociation-in-bittest-with-truncation-shl.ll
+++ b/llvm/test/Transforms/InstCombine/shift-amount-reassociation-in-bittest-with-truncation-shl.ll
@@ -18,7 +18,7 @@ define i1 @t0_const_after_fold_lshr_shl_ne(i32 %x, i64 %y, i32 %len) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 31
 ; CHECK-NEXT:    [[TMP2:%.*]] = zext nneg i32 [[TMP1]] to i64
 ; CHECK-NEXT:    [[TMP3:%.*]] = and i64 [[Y:%.*]], [[TMP2]]
-; CHECK-NEXT:    [[T5:%.*]] = icmp ne i64 [[TMP3]], 0
+; CHECK-NEXT:    [[T5:%.*]] = trunc nuw i64 [[TMP3]] to i1
 ; CHECK-NEXT:    ret i1 [[T5]]
 ;
   %t0 = sub i32 32, %len
@@ -41,7 +41,7 @@ define <2 x i1> @t1_vec_splat(<2 x i32> %x, <2 x i64> %y, <2 x i32> %len) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr <2 x i32> [[X:%.*]], splat (i32 31)
 ; CHECK-NEXT:    [[TMP2:%.*]] = zext nneg <2 x i32> [[TMP1]] to <2 x i64>
 ; CHECK-NEXT:    [[TMP3:%.*]] = and <2 x i64> [[Y:%.*]], [[TMP2]]
-; CHECK-NEXT:    [[T5:%.*]] = icmp ne <2 x i64> [[TMP3]], zeroinitializer
+; CHECK-NEXT:    [[T5:%.*]] = trunc nuw <2 x i64> [[TMP3]] to <2 x i1>
 ; CHECK-NEXT:    ret <2 x i1> [[T5]]
 ;
   %t0 = sub <2 x i32> <i32 32, i32 32>, %len
@@ -213,7 +213,7 @@ define i1 @t6_oneuse3(i32 %x, i64 %y, i32 %len) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 31
 ; CHECK-NEXT:    [[TMP2:%.*]] = zext nneg i32 [[TMP1]] to i64
 ; CHECK-NEXT:    [[TMP3:%.*]] = and i64 [[Y]], [[TMP2]]
-; CHECK-NEXT:    [[T5:%.*]] = icmp ne i64 [[TMP3]], 0
+; CHECK-NEXT:    [[T5:%.*]] = trunc nuw i64 [[TMP3]] to i1
 ; CHECK-NEXT:    ret i1 [[T5]]
 ;
   %t0 = sub i32 32, %len
@@ -245,7 +245,7 @@ define i1 @t7_oneuse4(i32 %x, i64 %y, i32 %len) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 31
 ; CHECK-NEXT:    [[TMP2:%.*]] = zext nneg i32 [[TMP1]] to i64
 ; CHECK-NEXT:    [[TMP3:%.*]] = and i64 [[Y]], [[TMP2]]
-; CHECK-NEXT:    [[T5:%.*]] = icmp ne i64 [[TMP3]], 0
+; CHECK-NEXT:    [[T5:%.*]] = trunc nuw i64 [[TMP3]] to i1
 ; CHECK-NEXT:    ret i1 [[T5]]
 ;
   %t0 = sub i32 32, %len ; no extra uses
diff --git a/llvm/test/Transforms/InstCombine/shift-amount-reassociation-in-bittest.ll b/llvm/test/Transforms/InstCombine/shift-amount-reassociation-in-bittest.ll
index 64ef1936fc2c1..4096d41d8d81f 100644
--- a/llvm/test/Transforms/InstCombine/shift-amount-reassociation-in-bittest.ll
+++ b/llvm/test/Transforms/InstCombine/shift-amount-reassociation-in-bittest.ll
@@ -57,7 +57,7 @@ define i1 @t3_const_after_fold_lshr_shl_ne(i32 %x, i32 %y, i32 %len) {
 ; CHECK-LABEL: @t3_const_after_fold_lshr_shl_ne(
 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 31
 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[Y:%.*]]
-; CHECK-NEXT:    [[T5:%.*]] = icmp ne i32 [[TMP2]], 0
+; CHECK-NEXT:    [[T5:%.*]] = trunc nuw i32 [[TMP2]] to i1
 ; CHECK-NEXT:    ret i1 [[T5]]
 ;
   %t0 = sub i32 32, %len
@@ -72,7 +72,7 @@ define i1 @t4_const_after_fold_lshr_shl_ne(i32 %x, i32 %y, i32 %len) {
 ; CHECK-LABEL: @t4_const_after_fold_lshr_shl_ne(
 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[Y:%.*]], 31
 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[X:%.*]]
-; CHECK-NEXT:    [[T5:%.*]] = icmp ne i32 [[TMP2]], 0
+; CHECK-NEXT:    [[T5:%.*]] = trunc nuw i32 [[TMP2]] to i1
 ; CHECK-NEXT:    ret i1 [[T5]]
 ;
   %t0 = sub i32 32, %len
diff --git a/llvm/test/Transforms/InstCombine/vector-casts-inseltpoison.ll b/llvm/test/Transforms/InstCombine/vector-casts-inseltpoison.ll
index 3d47f99a9bc5e..3ec0e509476d4 100644
--- a/llvm/test/Transforms/InstCombine/vector-casts-inseltpoison.ll
+++ b/llvm/test/Transforms/InstCombine/vector-casts-inseltpoison.ll
@@ -36,12 +36,9 @@ define <2 x i1> @and_cmp_is_trunc_even_with_poison_elt(<2 x i64> %a) {
   ret <2 x i1> %r
 }
 
-; TODO: This could be just 1 instruction (trunc), but our poison matching is incomplete.
-
 define <2 x i1> @and_cmp_is_trunc_even_with_poison_elts(<2 x i64> %a) {
 ; CHECK-LABEL: @and_cmp_is_trunc_even_with_poison_elts(
-; CHECK-NEXT:    [[T:%.*]] = and <2 x i64> [[A:%.*]], <i64 poison, i64 1>
-; CHECK-NEXT:    [[R:%.*]] = icmp ne <2 x i64> [[T]], <i64 poison, i64 0>
+; CHECK-NEXT:    [[R:%.*]] = trunc <2 x i64> [[A:%.*]] to <2 x i1>
 ; CHECK-NEXT:    ret <2 x i1> [[R]]
 ;
   %t = and <2 x i64> %a, <i64 poison, i64 1>
diff --git a/llvm/test/Transforms/InstCombine/vector-casts.ll b/llvm/test/Transforms/InstCombine/vector-casts.ll
index 2a2448a9e6ad9..1227c8ea54f4c 100644
--- a/llvm/test/Transforms/InstCombine/vector-casts.ll
+++ b/llvm/test/Transforms/InstCombine/vector-casts.ll
@@ -36,12 +36,9 @@ define <2 x i1> @and_cmp_is_trunc_even_with_poison_elt(<2 x i64> %a) {
   ret <2 x i1> %r
 }
 
-; TODO: This could be just 1 instruction (trunc), but our poison matching is incomplete.
-
 define <2 x i1> @and_cmp_is_trunc_even_with_poison_elts(<2 x i64> %a) {
 ; CHECK-LABEL: @and_cmp_is_trunc_even_with_poison_elts(
-; CHECK-NEXT:    [[T:%.*]] = and <2 x i64> [[A:%.*]], <i64 poison, i64 1>
-; CHECK-NEXT:    [[R:%.*]] = icmp ne <2 x i64> [[T]], <i64 poison, i64 0>
+; CHECK-NEXT:    [[R:%.*]] = trunc <2 x i64> [[A:%.*]] to <2 x i1>
 ; CHECK-NEXT:    ret <2 x i1> [[R]]
 ;
   %t = and <2 x i64> %a, <i64 poison, i64 1>



More information about the llvm-commits mailing list