[llvm] 8a0b2ca - [InstCombine] Transform bitwise (A >> C - 1, zext(icmp)) -> zext (bitwise(A < 0, icmp))

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 24 04:07:47 PDT 2023


Author: XChy
Date: 2023-07-24T13:04:32+02:00
New Revision: 8a0b2ca8217f3c4380c43ffd8d6b679db3805822

URL: https://github.com/llvm/llvm-project/commit/8a0b2ca8217f3c4380c43ffd8d6b679db3805822
DIFF: https://github.com/llvm/llvm-project/commit/8a0b2ca8217f3c4380c43ffd8d6b679db3805822.diff

LOG: [InstCombine] Transform bitwise (A >> C - 1, zext(icmp)) -> zext (bitwise(A < 0, icmp))

This extends foldCastedBitwiseLogic to handle the similar cases.
I have recently submitted a patch to implement a single fold like:

(A > 0) | (A < 0) -> zext (A != 0)

But it is not general enough, and some problems like
a < b & a >= b - 1 happen again.

So I generalize this fold by matching the pattern
bitwise(A >> C - 1, zext(icmp)), and replace A >> C - 1 with
zext(A < 0) here. (C is the scalar size bits of the type of A.)

Then we get bitwise(zext(A < 0), zext(icmp)), this will be folded
by original code in foldCastedBitwiseLogic, into
zext(bitwise(A < 0, icmp)). And finally, any related icmp fold will
be automatically implemented because bitwise(icmp,icmp) had been
implemented.

The proof of the correctness is obvious, because the folds below
were previously proved and implemented.
  A >> C - 1 -> zext(A < 0)
  bitwise(zext(A), zext(B)) -> zext(bitwise(A, B))
And the fold of this patch is the combination of folds above.

Fixes https://github.com/llvm/llvm-project/issues/63751.

Differential Revision: https://reviews.llvm.org/D154791

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
    llvm/test/Transforms/InstCombine/and-or-icmps.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index e335bcc083b092..8a1fb6b7f17e7b 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -1713,24 +1713,37 @@ Instruction *InstCombinerImpl::foldCastedBitwiseLogic(BinaryOperator &I) {
 
   Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
 
-  // ( A << (X - 1) ) | ((A > 0) zext to iX)
-  // <=> A < 0 | A > 0
-  // <=> (A != 0) zext to iX
-  Value *A;
-  ICmpInst::Predicate Pred;
+  // fold bitwise(A >> BW - 1, zext(icmp))     (BW is the scalar bits of the
+  // type of A)
+  //   -> bitwise(zext(A < 0), zext(icmp))
+  //   -> zext(bitwise(A < 0, icmp))
+  auto FoldBitwiseICmpZeroWithICmp = [&](Value *Op0,
+                                         Value *Op1) -> Instruction * {
+    ICmpInst::Predicate Pred;
+    Value *A;
+    bool IsMatched =
+        match(Op0,
+              m_OneUse(m_LShr(
+                  m_Value(A),
+                  m_SpecificInt(Op0->getType()->getScalarSizeInBits() - 1)))) &&
+        match(Op1, m_OneUse(m_ZExt(m_ICmp(Pred, m_Value(), m_Value()))));
+
+    if (!IsMatched)
+      return nullptr;
 
-  auto MatchOrZExtICmp = [&](Value *Op0, Value *Op1) -> bool {
-    return match(Op0, m_LShr(m_Value(A), m_SpecificInt(Op0->getType()->getScalarSizeInBits() - 1))) &&
-           match(Op1, m_ZExt(m_ICmp(Pred, m_Specific(A), m_Zero())));
+    auto *ICmpL =
+        Builder.CreateICmpSLT(A, Constant::getNullValue(A->getType()));
+    auto *ICmpR = cast<ZExtInst>(Op1)->getOperand(0);
+    auto *BitwiseOp = Builder.CreateBinOp(LogicOpc, ICmpL, ICmpR);
+
+    return new ZExtInst(BitwiseOp, Op0->getType());
   };
 
-  if (LogicOpc == Instruction::Or &&
-      (MatchOrZExtICmp(Op0, Op1) || MatchOrZExtICmp(Op1, Op0)) &&
-      Pred == ICmpInst::ICMP_SGT) {
-      Value *Cmp =
-          Builder.CreateICmpNE(A, Constant::getNullValue(A->getType()));
-      return new ZExtInst(Cmp, A->getType());
-  }
+  if (auto *Ret = FoldBitwiseICmpZeroWithICmp(Op0, Op1))
+    return Ret;
+
+  if (auto *Ret = FoldBitwiseICmpZeroWithICmp(Op1, Op0))
+    return Ret;
 
   CastInst *Cast0 = dyn_cast<CastInst>(Op0);
   if (!Cast0)

diff  --git a/llvm/test/Transforms/InstCombine/and-or-icmps.ll b/llvm/test/Transforms/InstCombine/and-or-icmps.ll
index 6515d7cb6fbbdf..065dbf261e131b 100644
--- a/llvm/test/Transforms/InstCombine/and-or-icmps.ll
+++ b/llvm/test/Transforms/InstCombine/and-or-icmps.ll
@@ -2669,10 +2669,8 @@ define <2 x i64> @icmp_slt_0_or_icmp_sgt_0_i64x2(<2 x i64> %x) {
 
 define <2 x i64> @icmp_slt_0_or_icmp_sgt_0_i64x2_fail(<2 x i64> %x) {
 ; CHECK-LABEL: @icmp_slt_0_or_icmp_sgt_0_i64x2_fail(
-; CHECK-NEXT:    [[B:%.*]] = icmp sgt <2 x i64> [[X:%.*]], <i64 1, i64 1>
-; CHECK-NEXT:    [[C:%.*]] = lshr <2 x i64> [[X]], <i64 63, i64 63>
-; CHECK-NEXT:    [[D:%.*]] = zext <2 x i1> [[B]] to <2 x i64>
-; CHECK-NEXT:    [[E:%.*]] = or <2 x i64> [[C]], [[D]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt <2 x i64> [[X:%.*]], <i64 1, i64 1>
+; CHECK-NEXT:    [[E:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i64>
 ; CHECK-NEXT:    ret <2 x i64> [[E]]
 ;
   %B = icmp sgt <2 x i64> %x, <i64 1, i64 1>
@@ -2685,11 +2683,7 @@ define <2 x i64> @icmp_slt_0_or_icmp_sgt_0_i64x2_fail(<2 x i64> %x) {
 
 define i32 @icmp_slt_0_and_icmp_sge_neg1_i32(i32 %x) {
 ; CHECK-LABEL: @icmp_slt_0_and_icmp_sge_neg1_i32(
-; CHECK-NEXT:    [[A:%.*]] = icmp sgt i32 [[X:%.*]], -1
-; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i32
-; CHECK-NEXT:    [[C:%.*]] = lshr i32 [[X]], 31
-; CHECK-NEXT:    [[D:%.*]] = and i32 [[C]], [[B]]
-; CHECK-NEXT:    ret i32 [[D]]
+; CHECK-NEXT:    ret i32 0
 ;
   %A = icmp sgt i32 %x, -1
   %B = zext i1 %A to i32
@@ -2700,11 +2694,7 @@ define i32 @icmp_slt_0_and_icmp_sge_neg1_i32(i32 %x) {
 
 define i32 @icmp_slt_0_or_icmp_sge_neg1_i32(i32 %x) {
 ; CHECK-LABEL: @icmp_slt_0_or_icmp_sge_neg1_i32(
-; CHECK-NEXT:    [[A:%.*]] = icmp sgt i32 [[X:%.*]], -2
-; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i32
-; CHECK-NEXT:    [[C:%.*]] = lshr i32 [[X]], 31
-; CHECK-NEXT:    [[D:%.*]] = or i32 [[C]], [[B]]
-; CHECK-NEXT:    ret i32 [[D]]
+; CHECK-NEXT:    ret i32 1
 ;
   %A = icmp sge i32 %x, -1
   %B = zext i1 %A to i32
@@ -2715,10 +2705,8 @@ define i32 @icmp_slt_0_or_icmp_sge_neg1_i32(i32 %x) {
 
 define i32 @icmp_slt_0_or_icmp_sge_100_i32(i32 %x) {
 ; CHECK-LABEL: @icmp_slt_0_or_icmp_sge_100_i32(
-; CHECK-NEXT:    [[A:%.*]] = icmp sgt i32 [[X:%.*]], 99
-; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i32
-; CHECK-NEXT:    [[C:%.*]] = lshr i32 [[X]], 31
-; CHECK-NEXT:    [[D:%.*]] = or i32 [[C]], [[B]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[X:%.*]], 99
+; CHECK-NEXT:    [[D:%.*]] = zext i1 [[TMP1]] to i32
 ; CHECK-NEXT:    ret i32 [[D]]
 ;
   %A = icmp sge i32 %x, 100
@@ -2730,10 +2718,8 @@ define i32 @icmp_slt_0_or_icmp_sge_100_i32(i32 %x) {
 
 define i64 @icmp_slt_0_and_icmp_sge_neg1_i64(i64 %x) {
 ; CHECK-LABEL: @icmp_slt_0_and_icmp_sge_neg1_i64(
-; CHECK-NEXT:    [[A:%.*]] = icmp sgt i64 [[X:%.*]], -2
-; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i64
-; CHECK-NEXT:    [[C:%.*]] = lshr i64 [[X]], 63
-; CHECK-NEXT:    [[D:%.*]] = and i64 [[C]], [[B]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[X:%.*]], -1
+; CHECK-NEXT:    [[D:%.*]] = zext i1 [[TMP1]] to i64
 ; CHECK-NEXT:    ret i64 [[D]]
 ;
   %A = icmp sge i64 %x, -1
@@ -2745,10 +2731,8 @@ define i64 @icmp_slt_0_and_icmp_sge_neg1_i64(i64 %x) {
 
 define i64 @icmp_slt_0_and_icmp_sge_neg2_i64(i64 %x) {
 ; CHECK-LABEL: @icmp_slt_0_and_icmp_sge_neg2_i64(
-; CHECK-NEXT:    [[A:%.*]] = icmp sgt i64 [[X:%.*]], -3
-; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i64
-; CHECK-NEXT:    [[C:%.*]] = lshr i64 [[X]], 63
-; CHECK-NEXT:    [[D:%.*]] = and i64 [[C]], [[B]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i64 [[X:%.*]], -3
+; CHECK-NEXT:    [[D:%.*]] = zext i1 [[TMP1]] to i64
 ; CHECK-NEXT:    ret i64 [[D]]
 ;
   %A = icmp sge i64 %x, -2
@@ -2760,10 +2744,8 @@ define i64 @icmp_slt_0_and_icmp_sge_neg2_i64(i64 %x) {
 
 define i64 @ashr_and_icmp_sge_neg1_i64(i64 %x) {
 ; CHECK-LABEL: @ashr_and_icmp_sge_neg1_i64(
-; CHECK-NEXT:    [[A:%.*]] = icmp sgt i64 [[X:%.*]], -2
-; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i64
-; CHECK-NEXT:    [[C1:%.*]] = lshr i64 [[X]], 63
-; CHECK-NEXT:    [[D:%.*]] = and i64 [[C1]], [[B]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[X:%.*]], -1
+; CHECK-NEXT:    [[D:%.*]] = zext i1 [[TMP1]] to i64
 ; CHECK-NEXT:    ret i64 [[D]]
 ;
   %A = icmp sge i64 %x, -1
@@ -2775,11 +2757,7 @@ define i64 @ashr_and_icmp_sge_neg1_i64(i64 %x) {
 
 define i64 @icmp_slt_0_and_icmp_sgt_neg1_i64(i64 %x) {
 ; CHECK-LABEL: @icmp_slt_0_and_icmp_sgt_neg1_i64(
-; CHECK-NEXT:    [[A:%.*]] = icmp sgt i64 [[X:%.*]], -1
-; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i64
-; CHECK-NEXT:    [[C:%.*]] = lshr i64 [[X]], 63
-; CHECK-NEXT:    [[D:%.*]] = and i64 [[C]], [[B]]
-; CHECK-NEXT:    ret i64 [[D]]
+; CHECK-NEXT:    ret i64 0
 ;
   %A = icmp sgt i64 %x, -1
   %B = zext i1 %A to i64
@@ -2805,10 +2783,8 @@ define i64 @icmp_slt_0_and_icmp_sge_neg1_i64_fail(i64 %x) {
 
 define <2 x i32> @icmp_slt_0_and_icmp_sge_neg1_i32x2(<2 x i32> %x) {
 ; CHECK-LABEL: @icmp_slt_0_and_icmp_sge_neg1_i32x2(
-; CHECK-NEXT:    [[A:%.*]] = icmp sgt <2 x i32> [[X:%.*]], <i32 -2, i32 -2>
-; CHECK-NEXT:    [[B:%.*]] = zext <2 x i1> [[A]] to <2 x i32>
-; CHECK-NEXT:    [[C:%.*]] = lshr <2 x i32> [[X]], <i32 31, i32 31>
-; CHECK-NEXT:    [[D:%.*]] = and <2 x i32> [[C]], [[B]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 -1, i32 -1>
+; CHECK-NEXT:    [[D:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i32>
 ; CHECK-NEXT:    ret <2 x i32> [[D]]
 ;
   %A = icmp sge <2 x i32> %x, <i32 -1, i32 -1>
@@ -2820,10 +2796,8 @@ define <2 x i32> @icmp_slt_0_and_icmp_sge_neg1_i32x2(<2 x i32> %x) {
 
 define <2 x i32> @icmp_slt_0_and_icmp_sge_neg2_i32x2(<2 x i32> %x) {
 ; CHECK-LABEL: @icmp_slt_0_and_icmp_sge_neg2_i32x2(
-; CHECK-NEXT:    [[A:%.*]] = icmp sgt <2 x i32> [[X:%.*]], <i32 -3, i32 -3>
-; CHECK-NEXT:    [[B:%.*]] = zext <2 x i1> [[A]] to <2 x i32>
-; CHECK-NEXT:    [[C:%.*]] = lshr <2 x i32> [[X]], <i32 31, i32 31>
-; CHECK-NEXT:    [[D:%.*]] = and <2 x i32> [[C]], [[B]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 -3, i32 -3>
+; CHECK-NEXT:    [[D:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i32>
 ; CHECK-NEXT:    ret <2 x i32> [[D]]
 ;
   %A = icmp sge <2 x i32> %x, <i32 -2, i32 -2>
@@ -2836,10 +2810,9 @@ define <2 x i32> @icmp_slt_0_and_icmp_sge_neg2_i32x2(<2 x i32> %x) {
 
 define i32 @icmp_x_slt_0_xor_icmp_y_sgt_neg1_i32(i32 %x, i32 %y) {
 ; CHECK-LABEL: @icmp_x_slt_0_xor_icmp_y_sgt_neg1_i32(
-; CHECK-NEXT:    [[A:%.*]] = icmp sgt i32 [[X:%.*]], -1
-; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i32
-; CHECK-NEXT:    [[C:%.*]] = lshr i32 [[Y:%.*]], 31
-; CHECK-NEXT:    [[D:%.*]] = xor i32 [[C]], [[B]]
+; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i32 [[TMP1]], -1
+; CHECK-NEXT:    [[D:%.*]] = zext i1 [[TMP2]] to i32
 ; CHECK-NEXT:    ret i32 [[D]]
 ;
   %A = icmp sgt i32 %x, -1
@@ -2851,10 +2824,8 @@ define i32 @icmp_x_slt_0_xor_icmp_y_sgt_neg1_i32(i32 %x, i32 %y) {
 
 define i32 @icmp_slt_0_xor_icmp_sgt_neg2_i32(i32 %x) {
 ; CHECK-LABEL: @icmp_slt_0_xor_icmp_sgt_neg2_i32(
-; CHECK-NEXT:    [[A:%.*]] = icmp sgt i32 [[X:%.*]], -2
-; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i32
-; CHECK-NEXT:    [[C:%.*]] = lshr i32 [[X]], 31
-; CHECK-NEXT:    [[D:%.*]] = xor i32 [[C]], [[B]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i32 [[X:%.*]], -1
+; CHECK-NEXT:    [[D:%.*]] = zext i1 [[TMP1]] to i32
 ; CHECK-NEXT:    ret i32 [[D]]
 ;
   %A = icmp sgt i32 %x, -2
@@ -2867,9 +2838,8 @@ define i32 @icmp_slt_0_xor_icmp_sgt_neg2_i32(i32 %x) {
 define i32 @icmp_slt_0_and_icmp_sge_neg1_i32_multiuse0(i32 %x) {
 ; CHECK-LABEL: @icmp_slt_0_and_icmp_sge_neg1_i32_multiuse0(
 ; CHECK-NEXT:    [[A:%.*]] = icmp sgt i32 [[X:%.*]], -3
-; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i32
-; CHECK-NEXT:    [[C:%.*]] = lshr i32 [[X]], 31
-; CHECK-NEXT:    [[D:%.*]] = and i32 [[C]], [[B]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[X]], -3
+; CHECK-NEXT:    [[D:%.*]] = zext i1 [[TMP1]] to i32
 ; CHECK-NEXT:    call void @use(i1 [[A]])
 ; CHECK-NEXT:    ret i32 [[D]]
 ;
@@ -2988,9 +2958,9 @@ define i32 @icmp_slt_0_or_icmp_eq_100_i32_multiuse_fail3(i32 %x) {
 define i32 @icmp_slt_0_or_icmp_eq_100_i32_fail(i32 %x) {
 ; CHECK-LABEL: @icmp_slt_0_or_icmp_eq_100_i32_fail(
 ; CHECK-NEXT:    [[A:%.*]] = icmp eq i32 [[X:%.*]], 100
-; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i32
-; CHECK-NEXT:    [[C:%.*]] = lshr i32 [[X]], 31
-; CHECK-NEXT:    [[D:%.*]] = or i32 [[C]], [[B]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X]], 0
+; CHECK-NEXT:    [[TMP2:%.*]] = or i1 [[TMP1]], [[A]]
+; CHECK-NEXT:    [[D:%.*]] = zext i1 [[TMP2]] to i32
 ; CHECK-NEXT:    ret i32 [[D]]
 ;
   %A = icmp eq i32 %x, 100
@@ -3003,9 +2973,9 @@ define i32 @icmp_slt_0_or_icmp_eq_100_i32_fail(i32 %x) {
 define i32 @icmp_slt_0_and_icmp_ne_neg2_i32_fail(i32 %x) {
 ; CHECK-LABEL: @icmp_slt_0_and_icmp_ne_neg2_i32_fail(
 ; CHECK-NEXT:    [[A:%.*]] = icmp ne i32 [[X:%.*]], -2
-; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i32
-; CHECK-NEXT:    [[C:%.*]] = lshr i32 [[X]], 31
-; CHECK-NEXT:    [[D:%.*]] = and i32 [[C]], [[B]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X]], 0
+; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[A]]
+; CHECK-NEXT:    [[D:%.*]] = zext i1 [[TMP2]] to i32
 ; CHECK-NEXT:    ret i32 [[D]]
 ;
   %A = icmp ne i32 %x, -2
@@ -3018,9 +2988,9 @@ define i32 @icmp_slt_0_and_icmp_ne_neg2_i32_fail(i32 %x) {
 define i32 @icmp_x_slt_0_and_icmp_y_ne_neg2_i32_fail(i32 %x, i32 %y) {
 ; CHECK-LABEL: @icmp_x_slt_0_and_icmp_y_ne_neg2_i32_fail(
 ; CHECK-NEXT:    [[A:%.*]] = icmp ne i32 [[X:%.*]], -2
-; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i32
-; CHECK-NEXT:    [[C:%.*]] = lshr i32 [[Y:%.*]], 31
-; CHECK-NEXT:    [[D:%.*]] = and i32 [[C]], [[B]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[Y:%.*]], 0
+; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[A]]
+; CHECK-NEXT:    [[D:%.*]] = zext i1 [[TMP2]] to i32
 ; CHECK-NEXT:    ret i32 [[D]]
 ;
   %A = icmp ne i32 %x, -2
@@ -3033,9 +3003,9 @@ define i32 @icmp_x_slt_0_and_icmp_y_ne_neg2_i32_fail(i32 %x, i32 %y) {
 define i32 @icmp_x_slt_0_and_icmp_y_sgt_neg1_i32_fail(i32 %x, i32 %y) {
 ; CHECK-LABEL: @icmp_x_slt_0_and_icmp_y_sgt_neg1_i32_fail(
 ; CHECK-NEXT:    [[A:%.*]] = icmp sgt i32 [[X:%.*]], -1
-; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i32
-; CHECK-NEXT:    [[C:%.*]] = lshr i32 [[Y:%.*]], 31
-; CHECK-NEXT:    [[D:%.*]] = and i32 [[C]], [[B]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[Y:%.*]], 0
+; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[A]]
+; CHECK-NEXT:    [[D:%.*]] = zext i1 [[TMP2]] to i32
 ; CHECK-NEXT:    ret i32 [[D]]
 ;
   %A = icmp sgt i32 %x, -1
@@ -3048,9 +3018,9 @@ define i32 @icmp_x_slt_0_and_icmp_y_sgt_neg1_i32_fail(i32 %x, i32 %y) {
 define i32 @icmp_slt_0_xor_icmp_sge_neg2_i32_fail(i32 %x) {
 ; CHECK-LABEL: @icmp_slt_0_xor_icmp_sge_neg2_i32_fail(
 ; CHECK-NEXT:    [[A:%.*]] = icmp sgt i32 [[X:%.*]], -3
-; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i32
-; CHECK-NEXT:    [[C:%.*]] = lshr i32 [[X]], 31
-; CHECK-NEXT:    [[D:%.*]] = xor i32 [[C]], [[B]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X]], 0
+; CHECK-NEXT:    [[TMP2:%.*]] = xor i1 [[TMP1]], [[A]]
+; CHECK-NEXT:    [[D:%.*]] = zext i1 [[TMP2]] to i32
 ; CHECK-NEXT:    ret i32 [[D]]
 ;
   %A = icmp sge i32 %x, -2
@@ -3064,9 +3034,9 @@ define i32 @icmp_slt_0_or_icmp_add_1_sge_100_i32_fail(i32 %x) {
 ; CHECK-LABEL: @icmp_slt_0_or_icmp_add_1_sge_100_i32_fail(
 ; CHECK-NEXT:    [[X1:%.*]] = add i32 [[X:%.*]], 1
 ; CHECK-NEXT:    [[A:%.*]] = icmp sgt i32 [[X1]], 99
-; CHECK-NEXT:    [[B:%.*]] = zext i1 [[A]] to i32
-; CHECK-NEXT:    [[C:%.*]] = lshr i32 [[X]], 31
-; CHECK-NEXT:    [[D:%.*]] = or i32 [[C]], [[B]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X]], 0
+; CHECK-NEXT:    [[TMP2:%.*]] = or i1 [[TMP1]], [[A]]
+; CHECK-NEXT:    [[D:%.*]] = zext i1 [[TMP2]] to i32
 ; CHECK-NEXT:    ret i32 [[D]]
 ;
   %X1 = add i32 %x, 1


        


More information about the llvm-commits mailing list