[llvm] r303660 - [InstCombine] allow icmp-xor folds for vectors (PR33138)

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Tue May 23 10:29:58 PDT 2017


Author: spatel
Date: Tue May 23 12:29:58 2017
New Revision: 303660

URL: http://llvm.org/viewvc/llvm-project?rev=303660&view=rev
Log:
[InstCombine] allow icmp-xor folds for vectors (PR33138)

This fixes the first part of:
https://bugs.llvm.org/show_bug.cgi?id=33138

More work is needed for the bitcasted variant.

Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
    llvm/trunk/test/Transforms/InstCombine/icmp-xor-signbit.ll

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp?rev=303660&r1=303659&r2=303660&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp Tue May 23 12:29:58 2017
@@ -3030,18 +3030,21 @@ Instruction *InstCombiner::foldICmpBinOp
       break;
     case Instruction::Add:
     case Instruction::Sub:
-    case Instruction::Xor:
+    case Instruction::Xor: {
       if (I.isEquality()) // a+x icmp eq/ne b+x --> a icmp b
         return new ICmpInst(Pred, BO0->getOperand(0), BO1->getOperand(0));
-      // icmp u/s (a ^ signmask), (b ^ signmask) --> icmp s/u a, b
-      if (ConstantInt *CI = dyn_cast<ConstantInt>(BO0->getOperand(1))) {
-        if (CI->getValue().isSignMask()) {
+
+      const APInt *C;
+      if (match(BO0->getOperand(1), m_APInt(C))) {
+        // icmp u/s (a ^ signmask), (b ^ signmask) --> icmp s/u a, b
+        if (C->isSignMask()) {
           ICmpInst::Predicate NewPred =
               I.isSigned() ? I.getUnsignedPredicate() : I.getSignedPredicate();
           return new ICmpInst(NewPred, BO0->getOperand(0), BO1->getOperand(0));
         }
 
-        if (BO0->getOpcode() == Instruction::Xor && CI->isMaxValue(true)) {
+        // icmp u/s (a ^ maxsignval), (b ^ maxsignval) --> icmp s/u' a, b
+        if (BO0->getOpcode() == Instruction::Xor && C->isMaxSignedValue()) {
           ICmpInst::Predicate NewPred =
               I.isSigned() ? I.getUnsignedPredicate() : I.getSignedPredicate();
           NewPred = I.getSwappedPredicate(NewPred);
@@ -3049,6 +3052,7 @@ Instruction *InstCombiner::foldICmpBinOp
         }
       }
       break;
+    }
     case Instruction::Mul:
       if (!I.isEquality())
         break;

Modified: llvm/trunk/test/Transforms/InstCombine/icmp-xor-signbit.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/icmp-xor-signbit.ll?rev=303660&r1=303659&r2=303660&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/icmp-xor-signbit.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/icmp-xor-signbit.ll Tue May 23 12:29:58 2017
@@ -18,9 +18,7 @@ define i1 @slt_to_ult(i8 %x, i8 %y) {
 
 define <2 x i1> @slt_to_ult_splat(<2 x i8> %x, <2 x i8> %y) {
 ; CHECK-LABEL: @slt_to_ult_splat(
-; CHECK-NEXT:    [[A:%.*]] = xor <2 x i8> %x, <i8 -128, i8 -128>
-; CHECK-NEXT:    [[B:%.*]] = xor <2 x i8> %y, <i8 -128, i8 -128>
-; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i8> [[A]], [[B]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i8> %x, %y
 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
 ;
   %a = xor <2 x i8> %x, <i8 128, i8 128>
@@ -44,9 +42,7 @@ define i1 @ult_to_slt(i8 %x, i8 %y) {
 
 define <2 x i1> @ult_to_slt_splat(<2 x i8> %x, <2 x i8> %y) {
 ; CHECK-LABEL: @ult_to_slt_splat(
-; CHECK-NEXT:    [[A:%.*]] = xor <2 x i8> %x, <i8 -128, i8 -128>
-; CHECK-NEXT:    [[B:%.*]] = xor <2 x i8> %y, <i8 -128, i8 -128>
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i8> [[A]], [[B]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i8> %x, %y
 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
 ;
   %a = xor <2 x i8> %x, <i8 128, i8 128>
@@ -70,9 +66,7 @@ define i1 @slt_to_ugt(i8 %x, i8 %y) {
 
 define <2 x i1> @slt_to_ugt_splat(<2 x i8> %x, <2 x i8> %y) {
 ; CHECK-LABEL: @slt_to_ugt_splat(
-; CHECK-NEXT:    [[A:%.*]] = xor <2 x i8> %x, <i8 127, i8 127>
-; CHECK-NEXT:    [[B:%.*]] = xor <2 x i8> %y, <i8 127, i8 127>
-; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i8> [[A]], [[B]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt <2 x i8> %x, %y
 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
 ;
   %a = xor <2 x i8> %x, <i8 127, i8 127>
@@ -96,9 +90,7 @@ define i1 @ult_to_sgt(i8 %x, i8 %y) {
 
 define <2 x i1> @ult_to_sgt_splat(<2 x i8> %x, <2 x i8> %y) {
 ; CHECK-LABEL: @ult_to_sgt_splat(
-; CHECK-NEXT:    [[A:%.*]] = xor <2 x i8> %x, <i8 127, i8 127>
-; CHECK-NEXT:    [[B:%.*]] = xor <2 x i8> %y, <i8 127, i8 127>
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i8> [[A]], [[B]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt <2 x i8> %x, %y
 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
 ;
   %a = xor <2 x i8> %x, <i8 127, i8 127>




More information about the llvm-commits mailing list