[llvm-commits] [llvm] r63487 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/2008-08-17-ICmpXorSignbit.ll test/Transforms/InstCombine/2009-01-31-Pressure.ll

Nick Lewycky nicholas at mxc.ca
Sat Jan 31 13:30:05 PST 2009


Author: nicholas
Date: Sat Jan 31 15:30:05 2009
New Revision: 63487

URL: http://llvm.org/viewvc/llvm-project?rev=63487&view=rev
Log:
Reinstate this optimization to fold icmp of xor when possible. Don't try to
turn icmp eq a+x, b+x into icmp eq a, b if a+x or b+x has other uses. This
may have been increasing register pressure leading to the bzip2 slowdown.

Added:
    llvm/trunk/test/Transforms/InstCombine/2009-01-31-Pressure.ll
Modified:
    llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
    llvm/trunk/test/Transforms/InstCombine/2008-08-17-ICmpXorSignbit.ll

Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=63487&r1=63486&r2=63487&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Sat Jan 31 15:30:05 2009
@@ -6095,18 +6095,40 @@
   if (BinaryOperator *Op0I = dyn_cast<BinaryOperator>(Op0)) {
     if (BinaryOperator *Op1I = dyn_cast<BinaryOperator>(Op1)) {
       if (Op0I->getOpcode() == Op1I->getOpcode() && Op0I->hasOneUse() &&
-          Op1I->hasOneUse() && Op0I->getOperand(1) == Op1I->getOperand(1) &&
-          I.isEquality()) {
+          Op1I->hasOneUse() && Op0I->getOperand(1) == Op1I->getOperand(1)) {
         switch (Op0I->getOpcode()) {
         default: break;
         case Instruction::Add:
         case Instruction::Sub:
         case Instruction::Xor:
-          // a+x icmp eq/ne b+x --> a icmp b
-          return new ICmpInst(I.getPredicate(), Op0I->getOperand(0),
-                              Op1I->getOperand(0));
+          if (I.isEquality()) {
+            // a+x icmp eq/ne b+x --> a icmp b
+            return new ICmpInst(I.getPredicate(), Op0I->getOperand(0),
+                                Op1I->getOperand(0));
+          } else {
+            // icmp u/s (a ^ signbit), (b ^ signbit) --> icmp s/u a, b
+            if (ConstantInt *CI = dyn_cast<ConstantInt>(Op0I->getOperand(1))) {
+              if (CI->getValue().isSignBit()) {
+                ICmpInst::Predicate Pred = I.isSignedPredicate()
+                                               ? I.getUnsignedPredicate()
+                                               : I.getSignedPredicate();
+                return new ICmpInst(Pred, Op0I->getOperand(0),
+                                    Op1I->getOperand(0));
+              } else if ((~CI->getValue()).isSignBit()) {
+                ICmpInst::Predicate Pred = I.isSignedPredicate()
+                                               ? I.getUnsignedPredicate()
+                                               : I.getSignedPredicate();
+                Pred = I.getSwappedPredicate(Pred);
+                return new ICmpInst(Pred, Op0I->getOperand(0),
+                                    Op1I->getOperand(0));
+              }
+            }
+          }
           break;
         case Instruction::Mul:
+          if (!I.isEquality())
+            break;
+
           if (ConstantInt *CI = dyn_cast<ConstantInt>(Op0I->getOperand(1))) {
             // a * Cst icmp eq/ne b * Cst --> a & Mask icmp b & Mask
             // Mask = -1 >> count-trailing-zeros(Cst).
@@ -6425,6 +6447,29 @@
         else
           return new ICmpInst(ICmpInst::ICMP_SLT, CompareVal, AddOne(RHS));
       }
+
+      if (LHSI->hasOneUse()) {
+        // (icmp u/s (xor A SignBit), C) -> (icmp s/u A, (xor C SignBit))
+        if (!ICI.isEquality() && XorCST->getValue().isSignBit()) {
+          const APInt &SignBit = XorCST->getValue();
+          ICmpInst::Predicate Pred = ICI.isSignedPredicate()
+                                         ? ICI.getUnsignedPredicate()
+                                         : ICI.getSignedPredicate();
+          return new ICmpInst(Pred, LHSI->getOperand(0),
+                              ConstantInt::get(RHSV ^ SignBit));
+        }
+
+        // (icmp u/s (xor A ~SignBit), C) -> (icmp s/u (xor C ~SignBit), A)
+        if (!ICI.isEquality() && (~XorCST->getValue()).isSignBit()) {
+          const APInt &NotSignBit = XorCST->getValue();
+          ICmpInst::Predicate Pred = ICI.isSignedPredicate()
+                                         ? ICI.getUnsignedPredicate()
+                                         : ICI.getSignedPredicate();
+          Pred = ICI.getSwappedPredicate(Pred);
+          return new ICmpInst(Pred, LHSI->getOperand(0),
+                              ConstantInt::get(RHSV ^ NotSignBit));
+        }
+      }
     }
     break;
   case Instruction::And:         // (icmp pred (and X, AndCST), RHS)

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=63487&r1=63486&r2=63487&view=diff

==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/2008-08-17-ICmpXorSignbit.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/2008-08-17-ICmpXorSignbit.ll Sat Jan 31 15:30:05 2009
@@ -1,5 +1,4 @@
 ; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep xor
-; XFAIL: *
 
 define i1 @test1(i8 %x, i8 %y) {
   %X = xor i8 %x, 128

Added: llvm/trunk/test/Transforms/InstCombine/2009-01-31-Pressure.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/2009-01-31-Pressure.ll?rev=63487&view=auto

==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/2009-01-31-Pressure.ll (added)
+++ llvm/trunk/test/Transforms/InstCombine/2009-01-31-Pressure.ll Sat Jan 31 15:30:05 2009
@@ -0,0 +1,22 @@
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep {%B = add i8 %b, %x}
+; PR2698
+
+declare void @use1(i1)
+declare void @use8(i8)
+
+define void @test1(i8 %a, i8 %b, i8 %x) {
+  %A = add i8 %a, %x
+  %B = add i8 %b, %x
+  %C = icmp eq i8 %A, %B
+  call void @use1(i1 %C)
+  ret void
+}
+
+define void @test2(i8 %a, i8 %b, i8 %x) {
+  %A = add i8 %a, %x
+  %B = add i8 %b, %x
+  %C = icmp eq i8 %A, %B
+  call void @use1(i1 %C)
+  call void @use8(i8 %A)
+  ret void
+}





More information about the llvm-commits mailing list