[InstCombine] use m_APInt to allow icmp eq (and X, C1), C2 folds for splat constant...
authorSanjay Patel <spatel@rotateright.com>
Thu, 4 Aug 2016 20:05:02 +0000 (20:05 +0000)
committerSanjay Patel <spatel@rotateright.com>
Thu, 4 Aug 2016 20:05:02 +0000 (20:05 +0000)
llvm-svn: 277762

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
llvm/test/Transforms/InstCombine/and.ll
llvm/test/Transforms/InstCombine/icmp.ll

index 192dad0..6c795db 100644 (file)
@@ -176,12 +176,6 @@ static bool isSignTest(ICmpInst::Predicate &Pred, const ConstantInt *RHS) {
   return false;
 }
 
-/// Return true if the constant is of the form 1+0+. This is the same as
-/// lowones(~X).
-static bool isHighOnes(const ConstantInt *CI) {
-  return (~CI->getValue() + 1).isPowerOf2();
-}
-
 /// Given a signed integer type and a set of known zero and one bits, compute
 /// the maximum and minimum values that could have the specified known zero and
 /// known one bits, returning them in Min/Max.
@@ -2288,11 +2282,11 @@ Instruction *InstCombiner::foldICmpEqualityWithConstant(ICmpInst &ICI) {
     }
     break;
   }
-  case Instruction::And:
-    // FIXME: Vectors are excluded by ConstantInt.
-    if (ConstantInt *BOC = dyn_cast<ConstantInt>(BOp1)) {
+  case Instruction::And: {
+    const APInt *BOC;
+    if (match(BOp1, m_APInt(BOC))) {
       // If we have ((X & C) == C), turn it into ((X & C) != 0).
-      if (RHS == BOC && RHSV->isPowerOf2())
+      if (RHSV == BOC && RHSV->isPowerOf2())
         return new ICmpInst(isICMP_NE ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE,
                             BO, Constant::getNullValue(RHS->getType()));
 
@@ -2301,7 +2295,7 @@ Instruction *InstCombiner::foldICmpEqualityWithConstant(ICmpInst &ICI) {
         break;
 
       // Replace (and X, (1 << size(X)-1) != 0) with x s< 0
-      if (BOC->getValue().isSignBit()) {
+      if (BOC->isSignBit()) {
         Constant *Zero = Constant::getNullValue(BOp0->getType());
         ICmpInst::Predicate Pred =
             isICMP_NE ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_SGE;
@@ -2309,14 +2303,15 @@ Instruction *InstCombiner::foldICmpEqualityWithConstant(ICmpInst &ICI) {
       }
 
       // ((X & ~7) == 0) --> X < 8
-      if (*RHSV == 0 && isHighOnes(BOC)) {
-        Constant *NegX = ConstantExpr::getNeg(BOC);
+      if (*RHSV == 0 && (~(*BOC) + 1).isPowerOf2()) {
+        Constant *NegBOC = ConstantExpr::getNeg(cast<Constant>(BOp1));
         ICmpInst::Predicate Pred =
             isICMP_NE ? ICmpInst::ICMP_UGE : ICmpInst::ICMP_ULT;
-        return new ICmpInst(Pred, BOp0, NegX);
+        return new ICmpInst(Pred, BOp0, NegBOC);
       }
     }
     break;
+  }
   case Instruction::Mul:
     if (*RHSV == 0 && BO->hasNoSignedWrap()) {
       // FIXME: Vectors are excluded by ConstantInt.
index 9a6ae74..5b48f33 100644 (file)
@@ -196,11 +196,9 @@ define i1 @test18(i32 %A) {
   ret i1 %C
 }
 
-; FIXME: Vectors should fold the same way.
 define <2 x i1> @test18_vec(<2 x i32> %A) {
 ; CHECK-LABEL: @test18_vec(
-; CHECK-NEXT:    [[B:%.*]] = and <2 x i32> %A, <i32 -128, i32 -128>
-; CHECK-NEXT:    [[C:%.*]] = icmp ne <2 x i32> [[B]], zeroinitializer
+; CHECK-NEXT:    [[C:%.*]] = icmp ugt <2 x i32> %A, <i32 127, i32 127>
 ; CHECK-NEXT:    ret <2 x i1> [[C]]
 ;
   %B = and <2 x i32> %A, <i32 -128, i32 -128>
@@ -218,11 +216,9 @@ define i1 @test18a(i8 %A) {
   ret i1 %C
 }
 
-; FIXME: Vectors should fold the same way.
 define <2 x i1> @test18a_vec(<2 x i8> %A) {
 ; CHECK-LABEL: @test18a_vec(
-; CHECK-NEXT:    [[B:%.*]] = and <2 x i8> %A, <i8 -2, i8 -2>
-; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x i8> [[B]], zeroinitializer
+; CHECK-NEXT:    [[C:%.*]] = icmp ult <2 x i8> %A, <i8 2, i8 2>
 ; CHECK-NEXT:    ret <2 x i1> [[C]]
 ;
   %B = and <2 x i8> %A, <i8 -2, i8 -2>
index db84eba..88cf0cd 100644 (file)
@@ -205,11 +205,12 @@ define i1 @test19(i32 %x) {
 }
 
 ; FIXME: Vectors should fold the same way.
+
 define <2 x i1> @test19vec(<2 x i32> %x) {
 ; CHECK-LABEL: @test19vec(
 ; CHECK-NEXT:    [[SHL:%.*]] = shl <2 x i32> <i32 1, i32 1>, %x
 ; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[SHL]], <i32 8, i32 8>
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[AND]], <i32 8, i32 8>
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[AND]], zeroinitializer
 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
 ;
   %shl = shl <2 x i32> <i32 1, i32 1>, %x
@@ -220,8 +221,7 @@ define <2 x i1> @test19vec(<2 x i32> %x) {
 
 define <2 x i1> @cmp_and_signbit_vec(<2 x i3> %x) {
 ; CHECK-LABEL: @cmp_and_signbit_vec(
-; CHECK-NEXT:    [[AND:%.*]] = and <2 x i3> %x, <i3 -4, i3 -4>
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i3> [[AND]], zeroinitializer
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i3> %x, zeroinitializer
 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
 ;
   %and = and <2 x i3> %x, <i3 4, i3 4>