InstCombine: Fold A-b == C --> b == A-C if A and C are constants.
authorBenjamin Kramer <benny.kra@googlemail.com>
Mon, 13 Jun 2011 15:24:24 +0000 (15:24 +0000)
committerBenjamin Kramer <benny.kra@googlemail.com>
Mon, 13 Jun 2011 15:24:24 +0000 (15:24 +0000)
The backend already knew this trick.

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

lib/Target/README.txt
lib/Transforms/InstCombine/InstCombineCompares.cpp
test/Transforms/InstCombine/icmp.ll

index fcec368a213b6eedf332ed035be71f0d36a6b309..4e382e8f8ec1aa49dbfe5150e98918857a0e3b7d 100644 (file)
@@ -870,11 +870,6 @@ rshift_gt (unsigned int a)
    bar ();
 }
 
-void neg_eq_cst(unsigned int a) {
-if (-a == 123)
-bar();
-}
-
 All should simplify to a single comparison.  All of these are
 currently not optimized with "clang -emit-llvm-bc | opt
 -std-compile-opts".
index 5ddf23ba8e1870b40e9277443bf93d947732c2c0..42db444ff6d7926648669dc43e6777ca7755430c 100644 (file)
@@ -1407,18 +1407,27 @@ Instruction *InstCombiner::visitICmpInstWithInstAndIntCst(ICmpInst &ICI,
       case Instruction::Xor:
         // For the xor case, we can xor two constants together, eliminating
         // the explicit xor.
-        if (Constant *BOC = dyn_cast<Constant>(BO->getOperand(1)))
-          return new ICmpInst(ICI.getPredicate(), BO->getOperand(0), 
+        if (Constant *BOC = dyn_cast<Constant>(BO->getOperand(1))) {
+          return new ICmpInst(ICI.getPredicate(), BO->getOperand(0),
                               ConstantExpr::getXor(RHS, BOC));
-        
-        // FALLTHROUGH
+        } else if (RHSV == 0) {
+          // Replace ((xor A, B) != 0) with (A != B)
+          return new ICmpInst(ICI.getPredicate(), BO->getOperand(0),
+                              BO->getOperand(1));
+        }
+        break;
       case Instruction::Sub:
-        // Replace (([sub|xor] A, B) != 0) with (A != B)
-        if (RHSV == 0)
+        // Replace ((sub A, B) != C) with (B != A-C) if A & C are constants.
+        if (ConstantInt *BOp0C = dyn_cast<ConstantInt>(BO->getOperand(0))) {
+          if (BO->hasOneUse())
+            return new ICmpInst(ICI.getPredicate(), BO->getOperand(1),
+                                ConstantExpr::getSub(BOp0C, RHS));
+        } else if (RHSV == 0) {
+          // Replace ((sub A, B) != 0) with (A != B)
           return new ICmpInst(ICI.getPredicate(), BO->getOperand(0),
                               BO->getOperand(1));
+        }
         break;
-        
       case Instruction::Or:
         // If bits are being or'd in that are not present in the constant we
         // are comparing against, then the comparison could never succeed!
index ecbba23091c5f456d249a567f74d414fc8e1136a..c8f7f81468f0c06eab35ca218c88d5796bbe3f9e 100644 (file)
@@ -531,3 +531,19 @@ define i1 @test54(i8 %a) nounwind {
   %ret = icmp eq i32 %and, 128
   ret i1 %ret
 }
+
+; CHECK: @test55
+; CHECK-NEXT: icmp eq i32 %a, -123
+define i1 @test55(i32 %a) {
+  %sub = sub i32 0, %a
+  %cmp = icmp eq i32 %sub, 123
+  ret i1 %cmp
+}
+
+; CHECK: @test56
+; CHECK-NEXT: icmp eq i32 %a, -113
+define i1 @test56(i32 %a) {
+  %sub = sub i32 10, %a
+  %cmp = icmp eq i32 %sub, 123
+  ret i1 %cmp
+}