[llvm] f55d1eb - [InstCombine] use decomposeBitTestICmp to make icmp (trunc X), C more consistent

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Sun Nov 28 07:03:54 PST 2021


Author: Sanjay Patel
Date: 2021-11-28T09:59:37-05:00
New Revision: f55d1eb3746a17688ca10d4e699ccea7d0f15378

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

LOG: [InstCombine] use decomposeBitTestICmp to make icmp (trunc X), C more consistent

This is a follow-on suggested in D112634.
Two folds that were added with that patch are subsumed in the call to
decomposeBitTestICmp, and two other folds are potentially inverted.

The deleted folds were very specialized by instcombine standards
because they were restricted to legal integer types based on the data
layout. This generalizes the canonical form independent of target/types.

This change has a reasonable chance of exposing regressions either in
IR or codegen, but I don't have any evidence for either of those yet.
A spot check of asm across several in-tree targets shows variations
that I expect are mostly neutral.

We have one improvement in an existing IR test that I noted with a
comment. Using mask ops might also make more code match with D114272.

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

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
    llvm/test/Transforms/InstCombine/and-compare.ll
    llvm/test/Transforms/InstCombine/compare-signs.ll
    llvm/test/Transforms/InstCombine/getelementptr.ll
    llvm/test/Transforms/InstCombine/icmp-trunc.ll
    llvm/test/Transforms/InstCombine/select-icmp-and.ll
    llvm/test/Transforms/InstCombine/select-with-bitwise-ops.ll
    llvm/test/Transforms/InstCombine/signed-truncation-check.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index f011692a5008..ed53b88aed61 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -14,6 +14,7 @@
 #include "llvm/ADT/APSInt.h"
 #include "llvm/ADT/SetVector.h"
 #include "llvm/ADT/Statistic.h"
+#include "llvm/Analysis/CmpInstAnalysis.h"
 #include "llvm/Analysis/ConstantFolding.h"
 #include "llvm/Analysis/InstructionSimplify.h"
 #include "llvm/Analysis/TargetLibraryInfo.h"
@@ -1894,23 +1895,6 @@ Instruction *InstCombinerImpl::foldICmpAndConstant(ICmpInst &Cmp,
     return new ICmpInst(NewPred, X, SubOne(cast<Constant>(Cmp.getOperand(1))));
   }
 
-  // (X & C2) == 0 -> (trunc X) >= 0
-  // (X & C2) != 0 -> (trunc X) <  0
-  //   iff C2 is a power of 2 and it masks the sign bit of a legal integer type.
-  const APInt *C2;
-  if (And->hasOneUse() && C.isZero() && match(Y, m_APInt(C2))) {
-    int32_t ExactLogBase2 = C2->exactLogBase2();
-    if (ExactLogBase2 != -1 && DL.isLegalInteger(ExactLogBase2 + 1)) {
-      Type *NTy = IntegerType::get(Cmp.getContext(), ExactLogBase2 + 1);
-      if (auto *AndVTy = dyn_cast<VectorType>(And->getType()))
-        NTy = VectorType::get(NTy, AndVTy->getElementCount());
-      Value *Trunc = Builder.CreateTrunc(X, NTy);
-      auto NewPred =
-          Pred == CmpInst::ICMP_EQ ? CmpInst::ICMP_SGE : CmpInst::ICMP_SLT;
-      return new ICmpInst(NewPred, Trunc, Constant::getNullValue(NTy));
-    }
-  }
-
   return nullptr;
 }
 
@@ -4615,7 +4599,7 @@ Instruction *InstCombinerImpl::foldICmpEquality(ICmpInst &I) {
 
 static Instruction *foldICmpWithTrunc(ICmpInst &ICmp,
                                       InstCombiner::BuilderTy &Builder) {
-  const ICmpInst::Predicate Pred = ICmp.getPredicate();
+  ICmpInst::Predicate Pred = ICmp.getPredicate();
   Value *Op0 = ICmp.getOperand(0), *Op1 = ICmp.getOperand(1);
 
   // Try to canonicalize trunc + compare-to-constant into a mask + cmp.
@@ -4625,41 +4609,31 @@ static Instruction *foldICmpWithTrunc(ICmpInst &ICmp,
   if (!match(Op0, m_OneUse(m_Trunc(m_Value(X)))) || !match(Op1, m_APInt(C)))
     return nullptr;
 
+  // This matches patterns corresponding to tests of the signbit as well as:
+  // (trunc X) u< C --> (X & -C) == 0 (are all masked-high-bits clear?)
+  // (trunc X) u> C --> (X & ~C) != 0 (are any masked-high-bits set?)
+  APInt Mask;
+  if (decomposeBitTestICmp(Op0, Op1, Pred, X, Mask, true /* WithTrunc */)) {
+    Value *And = Builder.CreateAnd(X, Mask);
+    Constant *Zero = ConstantInt::getNullValue(X->getType());
+    return new ICmpInst(Pred, And, Zero);
+  }
+
   unsigned SrcBits = X->getType()->getScalarSizeInBits();
-  if (Pred == ICmpInst::ICMP_ULT) {
-    if (C->isPowerOf2()) {
-      // If C is a power-of-2 (one set bit):
-      // (trunc X) u< C --> (X & -C) == 0 (are all masked-high-bits clear?)
-      Constant *MaskC = ConstantInt::get(X->getType(), (-*C).zext(SrcBits));
-      Value *And = Builder.CreateAnd(X, MaskC);
-      Constant *Zero = ConstantInt::getNullValue(X->getType());
-      return new ICmpInst(ICmpInst::ICMP_EQ, And, Zero);
-    }
+  if (Pred == ICmpInst::ICMP_ULT && C->isNegatedPowerOf2()) {
     // If C is a negative power-of-2 (high-bit mask):
     // (trunc X) u< C --> (X & C) != C (are any masked-high-bits clear?)
-    if (C->isNegatedPowerOf2()) {
-      Constant *MaskC = ConstantInt::get(X->getType(), C->zext(SrcBits));
-      Value *And = Builder.CreateAnd(X, MaskC);
-      return new ICmpInst(ICmpInst::ICMP_NE, And, MaskC);
-    }
+    Constant *MaskC = ConstantInt::get(X->getType(), C->zext(SrcBits));
+    Value *And = Builder.CreateAnd(X, MaskC);
+    return new ICmpInst(ICmpInst::ICMP_NE, And, MaskC);
   }
 
-  if (Pred == ICmpInst::ICMP_UGT) {
-    // If C is a low-bit-mask (C+1 is a power-of-2):
-    // (trunc X) u> C --> (X & ~C) != 0 (are any masked-high-bits set?)
-    if (C->isMask()) {
-      Constant *MaskC = ConstantInt::get(X->getType(), (~*C).zext(SrcBits));
-      Value *And = Builder.CreateAnd(X, MaskC);
-      Constant *Zero = ConstantInt::getNullValue(X->getType());
-      return new ICmpInst(ICmpInst::ICMP_NE, And, Zero);
-    }
+  if (Pred == ICmpInst::ICMP_UGT && (~*C).isPowerOf2()) {
     // If C is not-of-power-of-2 (one clear bit):
     // (trunc X) u> C --> (X & (C+1)) == C+1 (are all masked-high-bits set?)
-    if ((~*C).isPowerOf2()) {
-      Constant *MaskC = ConstantInt::get(X->getType(), (*C + 1).zext(SrcBits));
-      Value *And = Builder.CreateAnd(X, MaskC);
-      return new ICmpInst(ICmpInst::ICMP_EQ, And, MaskC);
-    }
+    Constant *MaskC = ConstantInt::get(X->getType(), (*C + 1).zext(SrcBits));
+    Value *And = Builder.CreateAnd(X, MaskC);
+    return new ICmpInst(ICmpInst::ICMP_EQ, And, MaskC);
   }
 
   return nullptr;

diff  --git a/llvm/test/Transforms/InstCombine/and-compare.ll b/llvm/test/Transforms/InstCombine/and-compare.ll
index f3f0b5ad3dfa..a9af18438730 100644
--- a/llvm/test/Transforms/InstCombine/and-compare.ll
+++ b/llvm/test/Transforms/InstCombine/and-compare.ll
@@ -33,8 +33,8 @@ define <2 x i1> @test1vec(<2 x i32> %a, <2 x i32> %b) {
 
 define i1 @test2(i64 %A) {
 ; CHECK-LABEL: @test2(
-; CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[A:%.*]] to i8
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[TMP1]], -1
+; CHECK-NEXT:    [[AND:%.*]] = and i64 [[A:%.*]], 128
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[AND]], 0
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %and = and i64 %A, 128
@@ -44,8 +44,8 @@ define i1 @test2(i64 %A) {
 
 define <2 x i1> @test2vec(<2 x i64> %A) {
 ; CHECK-LABEL: @test2vec(
-; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i64> [[A:%.*]] to <2 x i8>
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt <2 x i8> [[TMP1]], <i8 -1, i8 -1>
+; CHECK-NEXT:    [[AND:%.*]] = and <2 x i64> [[A:%.*]], <i64 128, i64 128>
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i64> [[AND]], zeroinitializer
 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
 ;
   %and = and <2 x i64> %A, <i64 128, i64 128>
@@ -55,8 +55,8 @@ define <2 x i1> @test2vec(<2 x i64> %A) {
 
 define i1 @test3(i64 %A) {
 ; CHECK-LABEL: @test3(
-; CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[A:%.*]] to i8
-; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[TMP1]], 0
+; CHECK-NEXT:    [[AND:%.*]] = and i64 [[A:%.*]], 128
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i64 [[AND]], 0
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %and = and i64 %A, 128
@@ -66,8 +66,8 @@ define i1 @test3(i64 %A) {
 
 define <2 x i1> @test3vec(<2 x i64> %A) {
 ; CHECK-LABEL: @test3vec(
-; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i64> [[A:%.*]] to <2 x i8>
-; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i8> [[TMP1]], zeroinitializer
+; CHECK-NEXT:    [[AND:%.*]] = and <2 x i64> [[A:%.*]], <i64 128, i64 128>
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i64> [[AND]], zeroinitializer
 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
 ;
   %and = and <2 x i64> %A, <i64 128, i64 128>

diff  --git a/llvm/test/Transforms/InstCombine/compare-signs.ll b/llvm/test/Transforms/InstCombine/compare-signs.ll
index fdc62947e1f5..2be4c7813e1e 100644
--- a/llvm/test/Transforms/InstCombine/compare-signs.ll
+++ b/llvm/test/Transforms/InstCombine/compare-signs.ll
@@ -178,13 +178,12 @@ define <2 x i1> @shift_trunc_signbit_test_vec_uses(<2 x i17> %x, <2 x i17>* %p1,
   ret <2 x i1> %r
 }
 
-; negative test
+; negative test - but this reduces with a mask op
 
 define i1 @shift_trunc_wrong_shift(i32 %x) {
 ; CHECK-LABEL: @shift_trunc_wrong_shift(
-; CHECK-NEXT:    [[SH:%.*]] = lshr i32 [[X:%.*]], 23
-; CHECK-NEXT:    [[TR:%.*]] = trunc i32 [[SH]] to i8
-; CHECK-NEXT:    [[R:%.*]] = icmp slt i8 [[TR]], 0
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 1073741824
+; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[TMP1]], 0
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
   %sh = lshr i32 %x, 23

diff  --git a/llvm/test/Transforms/InstCombine/getelementptr.ll b/llvm/test/Transforms/InstCombine/getelementptr.ll
index 199cbca37776..c01782e282ca 100644
--- a/llvm/test/Transforms/InstCombine/getelementptr.ll
+++ b/llvm/test/Transforms/InstCombine/getelementptr.ll
@@ -359,8 +359,8 @@ define i1 @test18(i16* %P, i32 %I) {
 ; Larger than the pointer size for a non-zero address space
 define i1 @test18_as1(i16 addrspace(1)* %P, i32 %I) {
 ; CHECK-LABEL: @test18_as1(
-; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[I:%.*]] to i16
-; CHECK-NEXT:    [[C:%.*]] = icmp slt i16 [[TMP1]], 0
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[I:%.*]], 32768
+; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[TMP1]], 0
 ; CHECK-NEXT:    ret i1 [[C]]
 ;
   %X = getelementptr inbounds i16, i16 addrspace(1)* %P, i32 %I
@@ -371,8 +371,8 @@ define i1 @test18_as1(i16 addrspace(1)* %P, i32 %I) {
 ; Smaller than the pointer size for a non-zero address space
 define i1 @test18_as1_i32(i16 addrspace(1)* %P, i32 %I) {
 ; CHECK-LABEL: @test18_as1_i32(
-; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[I:%.*]] to i16
-; CHECK-NEXT:    [[C:%.*]] = icmp slt i16 [[TMP1]], 0
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[I:%.*]], 32768
+; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[TMP1]], 0
 ; CHECK-NEXT:    ret i1 [[C]]
 ;
   %X = getelementptr inbounds i16, i16 addrspace(1)* %P, i32 %I
@@ -405,8 +405,8 @@ define i1 @test18_i64(i16* %P, i64 %I) {
 ; Larger than the pointer size
 define i1 @test18_i128(i16* %P, i128 %I) {
 ; CHECK-LABEL: @test18_i128(
-; CHECK-NEXT:    [[TMP1:%.*]] = trunc i128 [[I:%.*]] to i64
-; CHECK-NEXT:    [[C:%.*]] = icmp slt i64 [[TMP1]], 0
+; CHECK-NEXT:    [[TMP1:%.*]] = and i128 [[I:%.*]], 9223372036854775808
+; CHECK-NEXT:    [[C:%.*]] = icmp ne i128 [[TMP1]], 0
 ; CHECK-NEXT:    ret i1 [[C]]
 ;
   %X = getelementptr inbounds i16, i16* %P, i128 %I

diff  --git a/llvm/test/Transforms/InstCombine/icmp-trunc.ll b/llvm/test/Transforms/InstCombine/icmp-trunc.ll
index 54e4a9d0e5dc..44bb4ecaf8fa 100644
--- a/llvm/test/Transforms/InstCombine/icmp-trunc.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-trunc.ll
@@ -221,8 +221,8 @@ define i1 @ugt_253_use(i32 %x) {
 
 define i1 @slt_0(i32 %x) {
 ; CHECK-LABEL: @slt_0(
-; CHECK-NEXT:    [[T:%.*]] = trunc i32 [[X:%.*]] to i8
-; CHECK-NEXT:    [[R:%.*]] = icmp slt i8 [[T]], 0
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 128
+; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[TMP1]], 0
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
   %t = trunc i32 %x to i8
@@ -232,8 +232,8 @@ define i1 @slt_0(i32 %x) {
 
 define <2 x i1> @slt_0_splat(<2 x i16> %x) {
 ; CHECK-LABEL: @slt_0_splat(
-; CHECK-NEXT:    [[T:%.*]] = trunc <2 x i16> [[X:%.*]] to <2 x i11>
-; CHECK-NEXT:    [[R:%.*]] = icmp slt <2 x i11> [[T]], zeroinitializer
+; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i16> [[X:%.*]], <i16 1024, i16 1024>
+; CHECK-NEXT:    [[R:%.*]] = icmp ne <2 x i16> [[TMP1]], zeroinitializer
 ; CHECK-NEXT:    ret <2 x i1> [[R]]
 ;
   %t = trunc <2 x i16> %x to <2 x i11>
@@ -267,8 +267,8 @@ define i1 @slt_0_use(i32 %x) {
 
 define i1 @sgt_n1(i32 %x) {
 ; CHECK-LABEL: @sgt_n1(
-; CHECK-NEXT:    [[T:%.*]] = trunc i32 [[X:%.*]] to i8
-; CHECK-NEXT:    [[R:%.*]] = icmp sgt i8 [[T]], -1
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 128
+; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[TMP1]], 0
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
   %t = trunc i32 %x to i8
@@ -278,8 +278,8 @@ define i1 @sgt_n1(i32 %x) {
 
 define <2 x i1> @sgt_n1_splat(<2 x i16> %x) {
 ; CHECK-LABEL: @sgt_n1_splat(
-; CHECK-NEXT:    [[T:%.*]] = trunc <2 x i16> [[X:%.*]] to <2 x i11>
-; CHECK-NEXT:    [[R:%.*]] = icmp sgt <2 x i11> [[T]], <i11 -1, i11 -1>
+; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i16> [[X:%.*]], <i16 1024, i16 1024>
+; CHECK-NEXT:    [[R:%.*]] = icmp eq <2 x i16> [[TMP1]], zeroinitializer
 ; CHECK-NEXT:    ret <2 x i1> [[R]]
 ;
   %t = trunc <2 x i16> %x to <2 x i11>

diff  --git a/llvm/test/Transforms/InstCombine/select-icmp-and.ll b/llvm/test/Transforms/InstCombine/select-icmp-and.ll
index 9aa6b4394ed8..0c185bca1710 100644
--- a/llvm/test/Transforms/InstCombine/select-icmp-and.ll
+++ b/llvm/test/Transforms/InstCombine/select-icmp-and.ll
@@ -52,8 +52,8 @@ define <2 x i32> @test35vec(<2 x i32> %x) {
 ; Make sure we can still perform this optimization with a truncate present
 define i32 @test35_with_trunc(i64 %x) {
 ; CHECK-LABEL: @test35_with_trunc(
-; CHECK-NEXT:    [[X1:%.*]] = trunc i64 [[X:%.*]] to i32
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X1]], -1
+; CHECK-NEXT:    [[TMP1:%.*]] = and i64 [[X:%.*]], 2147483648
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[TMP1]], 0
 ; CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 60, i32 100
 ; CHECK-NEXT:    ret i32 [[COND]]
 ;
@@ -253,8 +253,8 @@ define <2 x i32> @test72vec(<2 x i32> %x) {
 
 define i32 @test73(i32 %x) {
 ; CHECK-LABEL: @test73(
-; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i8
-; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i8 [[TMP1]], -1
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 128
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
 ; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP2]], i32 40, i32 42
 ; CHECK-NEXT:    ret i32 [[TMP3]]
 ;
@@ -266,8 +266,8 @@ define i32 @test73(i32 %x) {
 
 define <2 x i32> @test73vec(<2 x i32> %x) {
 ; CHECK-LABEL: @test73vec(
-; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i32> [[X:%.*]] to <2 x i8>
-; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt <2 x i8> [[TMP1]], <i8 -1, i8 -1>
+; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 128, i32 128>
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq <2 x i32> [[TMP1]], zeroinitializer
 ; CHECK-NEXT:    [[TMP3:%.*]] = select <2 x i1> [[TMP2]], <2 x i32> <i32 40, i32 40>, <2 x i32> <i32 42, i32 42>
 ; CHECK-NEXT:    ret <2 x i32> [[TMP3]]
 ;

diff  --git a/llvm/test/Transforms/InstCombine/select-with-bitwise-ops.ll b/llvm/test/Transforms/InstCombine/select-with-bitwise-ops.ll
index 6eccbecd1d4d..c3aed936dbe9 100644
--- a/llvm/test/Transforms/InstCombine/select-with-bitwise-ops.ll
+++ b/llvm/test/Transforms/InstCombine/select-with-bitwise-ops.ll
@@ -642,10 +642,10 @@ define i32 @select_icmp_x_and_2147483648_ne_0_or_2147483648(i32 %x) {
 
 define i32 @test68(i32 %x, i32 %y) {
 ; CHECK-LABEL: @test68(
-; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 6
-; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], 2
-; CHECK-NEXT:    [[TMP3:%.*]] = or i32 [[TMP2]], [[Y:%.*]]
-; CHECK-NEXT:    ret i32 [[TMP3]]
+; CHECK-NEXT:    [[AND:%.*]] = lshr i32 [[X:%.*]], 6
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[AND]], 2
+; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], [[Y:%.*]]
+; CHECK-NEXT:    ret i32 [[TMP2]]
 ;
   %and = and i32 %x, 128
   %cmp = icmp eq i32 %and, 0
@@ -656,10 +656,10 @@ define i32 @test68(i32 %x, i32 %y) {
 
 define <2 x i32> @test68vec(<2 x i32> %x, <2 x i32> %y) {
 ; CHECK-LABEL: @test68vec(
-; CHECK-NEXT:    [[TMP1:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 6, i32 6>
-; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[TMP1]], <i32 2, i32 2>
-; CHECK-NEXT:    [[TMP3:%.*]] = or <2 x i32> [[TMP2]], [[Y:%.*]]
-; CHECK-NEXT:    ret <2 x i32> [[TMP3]]
+; CHECK-NEXT:    [[AND:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 6, i32 6>
+; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[AND]], <i32 2, i32 2>
+; CHECK-NEXT:    [[TMP2:%.*]] = or <2 x i32> [[TMP1]], [[Y:%.*]]
+; CHECK-NEXT:    ret <2 x i32> [[TMP2]]
 ;
   %and = and <2 x i32> %x, <i32 128, i32 128>
   %cmp = icmp eq <2 x i32> %and, zeroinitializer
@@ -670,8 +670,8 @@ define <2 x i32> @test68vec(<2 x i32> %x, <2 x i32> %y) {
 
 define i32 @test68_xor(i32 %x, i32 %y) {
 ; CHECK-LABEL: @test68_xor(
-; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i8
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[TMP1]], -1
+; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 128
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 0
 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y:%.*]], 2
 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[XOR]]
 ; CHECK-NEXT:    ret i32 [[SELECT]]
@@ -685,8 +685,8 @@ define i32 @test68_xor(i32 %x, i32 %y) {
 
 define i32 @test68_and(i32 %x, i32 %y) {
 ; CHECK-LABEL: @test68_and(
-; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i8
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[TMP1]], -1
+; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 128
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], 0
 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[Y:%.*]], -3
 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[AND2]]
 ; CHECK-NEXT:    ret i32 [[SELECT]]
@@ -700,11 +700,11 @@ define i32 @test68_and(i32 %x, i32 %y) {
 
 define i32 @test69(i32 %x, i32 %y) {
 ; CHECK-LABEL: @test69(
-; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 6
-; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], 2
-; CHECK-NEXT:    [[TMP3:%.*]] = xor i32 [[TMP2]], 2
-; CHECK-NEXT:    [[TMP4:%.*]] = or i32 [[TMP3]], [[Y:%.*]]
-; CHECK-NEXT:    ret i32 [[TMP4]]
+; CHECK-NEXT:    [[AND:%.*]] = lshr i32 [[X:%.*]], 6
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[AND]], 2
+; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[TMP1]], 2
+; CHECK-NEXT:    [[TMP3:%.*]] = or i32 [[TMP2]], [[Y:%.*]]
+; CHECK-NEXT:    ret i32 [[TMP3]]
 ;
   %and = and i32 %x, 128
   %cmp = icmp ne i32 %and, 0
@@ -715,11 +715,11 @@ define i32 @test69(i32 %x, i32 %y) {
 
 define <2 x i32> @test69vec(<2 x i32> %x, <2 x i32> %y) {
 ; CHECK-LABEL: @test69vec(
-; CHECK-NEXT:    [[TMP1:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 6, i32 6>
-; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[TMP1]], <i32 2, i32 2>
-; CHECK-NEXT:    [[TMP3:%.*]] = xor <2 x i32> [[TMP2]], <i32 2, i32 2>
-; CHECK-NEXT:    [[TMP4:%.*]] = or <2 x i32> [[TMP3]], [[Y:%.*]]
-; CHECK-NEXT:    ret <2 x i32> [[TMP4]]
+; CHECK-NEXT:    [[AND:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 6, i32 6>
+; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[AND]], <i32 2, i32 2>
+; CHECK-NEXT:    [[TMP2:%.*]] = xor <2 x i32> [[TMP1]], <i32 2, i32 2>
+; CHECK-NEXT:    [[TMP3:%.*]] = or <2 x i32> [[TMP2]], [[Y:%.*]]
+; CHECK-NEXT:    ret <2 x i32> [[TMP3]]
 ;
   %and = and <2 x i32> %x, <i32 128, i32 128>
   %cmp = icmp ne <2 x i32> %and, zeroinitializer
@@ -730,8 +730,8 @@ define <2 x i32> @test69vec(<2 x i32> %x, <2 x i32> %y) {
 
 define i32 @test69_xor(i32 %x, i32 %y) {
 ; CHECK-LABEL: @test69_xor(
-; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i8
-; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i8 [[TMP1]], -1
+; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 128
+; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0
 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y:%.*]], 2
 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[XOR]], i32 [[Y]]
 ; CHECK-NEXT:    ret i32 [[SELECT]]
@@ -745,8 +745,8 @@ define i32 @test69_xor(i32 %x, i32 %y) {
 
 define i32 @test69_and(i32 %x, i32 %y) {
 ; CHECK-LABEL: @test69_and(
-; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i8
-; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i8 [[TMP1]], -1
+; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 128
+; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0
 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[Y:%.*]], 2
 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[AND2]], i32 [[Y]]
 ; CHECK-NEXT:    ret i32 [[SELECT]]

diff  --git a/llvm/test/Transforms/InstCombine/signed-truncation-check.ll b/llvm/test/Transforms/InstCombine/signed-truncation-check.ll
index b4a94b2bedb5..49e41e6bdc34 100644
--- a/llvm/test/Transforms/InstCombine/signed-truncation-check.ll
+++ b/llvm/test/Transforms/InstCombine/signed-truncation-check.ll
@@ -425,8 +425,8 @@ define i1 @positive_trunc_base_logical(i32 %arg) {
 
 define i1 @positive_
diff erent_trunc_both(i32 %arg) {
 ; CHECK-LABEL: @positive_
diff erent_trunc_both(
-; CHECK-NEXT:    [[T1:%.*]] = trunc i32 [[ARG:%.*]] to i15
-; CHECK-NEXT:    [[T2:%.*]] = icmp sgt i15 [[T1]], -1
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARG:%.*]], 16384
+; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[TMP1]], 0
 ; CHECK-NEXT:    [[T3:%.*]] = trunc i32 [[ARG]] to i16
 ; CHECK-NEXT:    [[T4:%.*]] = add i16 [[T3]], 128
 ; CHECK-NEXT:    [[T5:%.*]] = icmp ult i16 [[T4]], 256
@@ -444,8 +444,8 @@ define i1 @positive_
diff erent_trunc_both(i32 %arg) {
 
 define i1 @positive_
diff erent_trunc_both_logical(i32 %arg) {
 ; CHECK-LABEL: @positive_
diff erent_trunc_both_logical(
-; CHECK-NEXT:    [[T1:%.*]] = trunc i32 [[ARG:%.*]] to i15
-; CHECK-NEXT:    [[T2:%.*]] = icmp sgt i15 [[T1]], -1
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARG:%.*]], 16384
+; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[TMP1]], 0
 ; CHECK-NEXT:    [[T3:%.*]] = trunc i32 [[ARG]] to i16
 ; CHECK-NEXT:    [[T4:%.*]] = add i16 [[T3]], 128
 ; CHECK-NEXT:    [[T5:%.*]] = icmp ult i16 [[T4]], 256
@@ -717,8 +717,8 @@ define i1 @negative_not_arg_logical(i32 %arg, i32 %arg2) {
 
 define i1 @negative_trunc_not_arg(i32 %arg, i32 %arg2) {
 ; CHECK-LABEL: @negative_trunc_not_arg(
-; CHECK-NEXT:    [[T1:%.*]] = trunc i32 [[ARG:%.*]] to i8
-; CHECK-NEXT:    [[T2:%.*]] = icmp sgt i8 [[T1]], -1
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARG:%.*]], 128
+; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[TMP1]], 0
 ; CHECK-NEXT:    [[T3:%.*]] = add i32 [[ARG2:%.*]], 128
 ; CHECK-NEXT:    [[T4:%.*]] = icmp ult i32 [[T3]], 256
 ; CHECK-NEXT:    [[T5:%.*]] = and i1 [[T2]], [[T4]]
@@ -734,8 +734,8 @@ define i1 @negative_trunc_not_arg(i32 %arg, i32 %arg2) {
 
 define i1 @negative_trunc_not_arg_logical(i32 %arg, i32 %arg2) {
 ; CHECK-LABEL: @negative_trunc_not_arg_logical(
-; CHECK-NEXT:    [[T1:%.*]] = trunc i32 [[ARG:%.*]] to i8
-; CHECK-NEXT:    [[T2:%.*]] = icmp sgt i8 [[T1]], -1
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARG:%.*]], 128
+; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[TMP1]], 0
 ; CHECK-NEXT:    [[T3:%.*]] = add i32 [[ARG2:%.*]], 128
 ; CHECK-NEXT:    [[T4:%.*]] = icmp ult i32 [[T3]], 256
 ; CHECK-NEXT:    [[T5:%.*]] = select i1 [[T2]], i1 [[T4]], i1 false


        


More information about the llvm-commits mailing list