Reinstate this optimization to fold icmp of xor when possible. Don't try to
authorNick Lewycky <nicholas@mxc.ca>
Sat, 31 Jan 2009 21:30:05 +0000 (21:30 +0000)
committerNick Lewycky <nicholas@mxc.ca>
Sat, 31 Jan 2009 21:30:05 +0000 (21:30 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@63487 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/InstructionCombining.cpp
test/Transforms/InstCombine/2008-08-17-ICmpXorSignbit.ll
test/Transforms/InstCombine/2009-01-31-Pressure.ll [new file with mode: 0644]

index 8b9c5999477967e39669faf29cfc0742cedd9d96..a1cb3dc39fc495515c5ef0eb35c7a15bd7ca717f 100644 (file)
@@ -6095,18 +6095,40 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
   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 @@ Instruction *InstCombiner::visitICmpInstWithInstAndIntCst(ICmpInst &ICI,
         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)
index 1540d41a26524e24f903a9852c106f0eea066fae..428a35947d1d4febd3d89fc65a6734754b1ccedf 100644 (file)
@@ -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
diff --git a/test/Transforms/InstCombine/2009-01-31-Pressure.ll b/test/Transforms/InstCombine/2009-01-31-Pressure.ll
new file mode 100644 (file)
index 0000000..0c3066b
--- /dev/null
@@ -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
+}