[llvm] r279066 - [InstCombine] use m_APInt to allow icmp (xor X, Y), C folds for splat constant vectors

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 18 07:10:49 PDT 2016


Author: spatel
Date: Thu Aug 18 09:10:48 2016
New Revision: 279066

URL: http://llvm.org/viewvc/llvm-project?rev=279066&view=rev
Log:
[InstCombine] use m_APInt to allow icmp (xor X, Y), C folds for splat constant vectors

This is a sibling of:
https://reviews.llvm.org/rL278859
https://reviews.llvm.org/rL278935
https://reviews.llvm.org/rL278945

Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
    llvm/trunk/test/Transforms/InstCombine/2008-08-17-ICmpXorSignbit.ll
    llvm/trunk/test/Transforms/InstCombine/icmp.ll
    llvm/trunk/test/Transforms/InstCombine/vec_sext.ll
    llvm/trunk/test/Transforms/InstCombine/xor2.ll

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp?rev=279066&r1=279065&r2=279066&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp Thu Aug 18 09:10:48 2016
@@ -1572,18 +1572,14 @@ Instruction *InstCombiner::foldICmpTrunc
 /// Fold icmp (xor X, Y), C.
 Instruction *InstCombiner::foldICmpXorConstant(ICmpInst &Cmp, Instruction *Xor,
                                                const APInt *C) {
-  // FIXME: This check restricts all folds under here to scalar types.
-  ConstantInt *RHS = dyn_cast<ConstantInt>(Cmp.getOperand(1));
-  if (!RHS)
-    return nullptr;
-
+  Value *X = Xor->getOperand(0);
+  Value *Y = Xor->getOperand(1);
   const APInt *XorC;
-  if (!match(Xor->getOperand(1), m_APInt(XorC)))
+  if (!match(Y, m_APInt(XorC)))
     return nullptr;
 
   // If this is a comparison that tests the signbit (X < 0) or (x > -1),
   // fold the xor.
-  Value *X = Xor->getOperand(0);
   ICmpInst::Predicate Pred = Cmp.getPredicate();
   if ((Pred == ICmpInst::ICMP_SLT && *C == 0) ||
       (Pred == ICmpInst::ICMP_SGT && C->isAllOnesValue())) {
@@ -1602,10 +1598,11 @@ Instruction *InstCombiner::foldICmpXorCo
     // If so, the new one isn't.
     isTrueIfPositive ^= true;
 
+    Constant *CmpConstant = cast<Constant>(Cmp.getOperand(1));
     if (isTrueIfPositive)
-      return new ICmpInst(ICmpInst::ICMP_SGT, X, SubOne(RHS));
+      return new ICmpInst(ICmpInst::ICMP_SGT, X, SubOne(CmpConstant));
     else
-      return new ICmpInst(ICmpInst::ICMP_SLT, X, AddOne(RHS));
+      return new ICmpInst(ICmpInst::ICMP_SLT, X, AddOne(CmpConstant));
   }
 
   if (Xor->hasOneUse()) {
@@ -1613,7 +1610,7 @@ Instruction *InstCombiner::foldICmpXorCo
     if (!Cmp.isEquality() && XorC->isSignBit()) {
       Pred = Cmp.isSigned() ? Cmp.getUnsignedPredicate()
                             : Cmp.getSignedPredicate();
-      return new ICmpInst(Pred, X, Builder->getInt(*C ^ *XorC));
+      return new ICmpInst(Pred, X, ConstantInt::get(X->getType(), *C ^ *XorC));
     }
 
     // (icmp u/s (xor X ~SignBit), C) -> (icmp s/u X, (xor C ~SignBit))
@@ -1621,19 +1618,19 @@ Instruction *InstCombiner::foldICmpXorCo
       Pred = Cmp.isSigned() ? Cmp.getUnsignedPredicate()
                             : Cmp.getSignedPredicate();
       Pred = Cmp.getSwappedPredicate(Pred);
-      return new ICmpInst(Pred, X, Builder->getInt(*C ^ *XorC));
+      return new ICmpInst(Pred, X, ConstantInt::get(X->getType(), *C ^ *XorC));
     }
   }
 
   // (icmp ugt (xor X, C), ~C) -> (icmp ult X, C)
   //   iff -C is a power of 2
   if (Pred == ICmpInst::ICMP_UGT && *XorC == ~(*C) && (*C + 1).isPowerOf2())
-    return new ICmpInst(ICmpInst::ICMP_ULT, X, Xor->getOperand(1));
+    return new ICmpInst(ICmpInst::ICMP_ULT, X, Y);
 
   // (icmp ult (xor X, C), -C) -> (icmp uge X, C)
   //   iff -C is a power of 2
   if (Pred == ICmpInst::ICMP_ULT && *XorC == -(*C) && C->isPowerOf2())
-    return new ICmpInst(ICmpInst::ICMP_UGE, X, Xor->getOperand(1));
+    return new ICmpInst(ICmpInst::ICMP_UGE, X, Y);
 
   return nullptr;
 }

Modified: llvm/trunk/test/Transforms/InstCombine/2008-08-17-ICmpXorSignbit.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/2008-08-17-ICmpXorSignbit.ll?rev=279066&r1=279065&r2=279066&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/2008-08-17-ICmpXorSignbit.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/2008-08-17-ICmpXorSignbit.ll Thu Aug 18 09:10:48 2016
@@ -33,11 +33,9 @@ define i1 @test3(i8 %x) {
   ret i1 %tmp
 }
 
-; FIXME: Vectors should fold too.
 define <2 x i1> @test3vec(<2 x i8> %x) {
 ; CHECK-LABEL: @test3vec(
-; CHECK-NEXT:    [[X:%.*]] = xor <2 x i8> %x, <i8 -128, i8 -128>
-; CHECK-NEXT:    [[TMP:%.*]] = icmp ugt <2 x i8> [[X]], <i8 14, i8 14>
+; CHECK-NEXT:    [[TMP:%.*]] = icmp sgt <2 x i8> %x, <i8 -114, i8 -114>
 ; CHECK-NEXT:    ret <2 x i1> [[TMP]]
 ;
   %X = xor <2 x i8> %x, <i8 128, i8 128>
@@ -77,11 +75,9 @@ define i1 @test6(i8 %x) {
   ret i1 %tmp
 }
 
-; FIXME: Vectors should fold too.
 define <2 x i1> @test6vec(<2 x i8> %x) {
 ; CHECK-LABEL: @test6vec(
-; CHECK-NEXT:    [[X:%.*]] = xor <2 x i8> %x, <i8 127, i8 127>
-; CHECK-NEXT:    [[TMP:%.*]] = icmp ugt <2 x i8> [[X]], <i8 14, i8 14>
+; CHECK-NEXT:    [[TMP:%.*]] = icmp slt <2 x i8> %x, <i8 113, i8 113>
 ; CHECK-NEXT:    ret <2 x i1> [[TMP]]
 ;
   %X = xor <2 x i8> %x, <i8 127, i8 127>

Modified: llvm/trunk/test/Transforms/InstCombine/icmp.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/icmp.ll?rev=279066&r1=279065&r2=279066&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/icmp.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/icmp.ll Thu Aug 18 09:10:48 2016
@@ -1882,11 +1882,9 @@ define i1 @icmp_sub_-1_X_ult_4(i32 %X) {
   ret i1 %cmp
 }
 
-; FIXME: Vectors should fold too.
 define <2 x i1> @icmp_xor_neg4_X_ult_4_vec(<2 x i32> %X) {
 ; CHECK-LABEL: @icmp_xor_neg4_X_ult_4_vec(
-; CHECK-NEXT:    [[XOR:%.*]] = xor <2 x i32> %X, <i32 -4, i32 -4>
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[XOR]], <i32 4, i32 4>
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i32> %X, <i32 -5, i32 -5>
 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
 ;
   %xor = xor <2 x i32> %X, <i32 -4, i32 -4>
@@ -1904,11 +1902,9 @@ define i1 @icmp_sub_-1_X_uge_4(i32 %X) {
   ret i1 %cmp
 }
 
-; FIXME: Vectors should fold too.
 define <2 x i1> @icmp_xor_neg4_X_uge_4_vec(<2 x i32> %X) {
 ; CHECK-LABEL: @icmp_xor_neg4_X_uge_4_vec(
-; CHECK-NEXT:    [[XOR:%.*]] = xor <2 x i32> %X, <i32 -4, i32 -4>
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i32> [[XOR]], <i32 3, i32 3>
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> %X, <i32 -4, i32 -4>
 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
 ;
   %xor = xor <2 x i32> %X, <i32 -4, i32 -4>

Modified: llvm/trunk/test/Transforms/InstCombine/vec_sext.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/vec_sext.ll?rev=279066&r1=279065&r2=279066&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/vec_sext.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/vec_sext.ll Thu Aug 18 09:10:48 2016
@@ -26,8 +26,8 @@ define <4 x i32> @psignd_3(<4 x i32> %a,
 define <4 x i32> @test1(<4 x i32> %a, <4 x i32> %b) {
 ; CHECK-LABEL: @test1(
 ; CHECK-NEXT:    [[B_LOBIT:%.*]] = ashr <4 x i32> %b, <i32 31, i32 31, i32 31, i32 31>
-; CHECK-NEXT:    [[B_LOBIT_NOT:%.*]] = xor <4 x i32> [[B_LOBIT]], <i32 -1, i32 -1, i32 -1, i32 -1>
 ; CHECK-NEXT:    [[SUB:%.*]] = sub nsw <4 x i32> zeroinitializer, %a
+; CHECK-NEXT:    [[B_LOBIT_NOT:%.*]] = xor <4 x i32> [[B_LOBIT]], <i32 -1, i32 -1, i32 -1, i32 -1>
 ; CHECK-NEXT:    [[T2:%.*]] = and <4 x i32> [[B_LOBIT]], %a
 ; CHECK-NEXT:    [[T3:%.*]] = and <4 x i32> [[B_LOBIT_NOT]], [[SUB]]
 ; CHECK-NEXT:    [[COND:%.*]] = or <4 x i32> [[T2]], [[T3]]

Modified: llvm/trunk/test/Transforms/InstCombine/xor2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/xor2.ll?rev=279066&r1=279065&r2=279066&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/xor2.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/xor2.ll Thu Aug 18 09:10:48 2016
@@ -12,11 +12,9 @@ define i1 @test0(i32 %A) {
   ret i1 %C
 }
 
-; FIXME: Vectors should fold too.
 define <2 x i1> @test0vec(<2 x i32> %A) {
 ; CHECK-LABEL: @test0vec(
-; CHECK-NEXT:    [[B:%.*]] = xor <2 x i32> %A, <i32 -2147483648, i32 -2147483648>
-; CHECK-NEXT:    [[C:%.*]] = icmp sgt <2 x i32> [[B]], <i32 -1, i32 -1>
+; CHECK-NEXT:    [[C:%.*]] = icmp slt <2 x i32> %A, zeroinitializer
 ; CHECK-NEXT:    ret <2 x i1> [[C]]
 ;
   %B = xor <2 x i32> %A, <i32 -2147483648, i32 -2147483648>




More information about the llvm-commits mailing list