Reduce x - y to -y when we know the 'x' part will get masked off anyways.
authorNick Lewycky <nicholas@mxc.ca>
Wed, 9 Jul 2008 04:32:37 +0000 (04:32 +0000)
committerNick Lewycky <nicholas@mxc.ca>
Wed, 9 Jul 2008 04:32:37 +0000 (04:32 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@53271 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/InstructionCombining.cpp
test/Transforms/InstCombine/2008-07-08-SubAnd.ll [new file with mode: 0644]

index f8ad98c5170a9c58f18b1bf8e9e67971181f030e..675f7ec57146f76f99546b59dbe799c4ccac9878 100644 (file)
@@ -3461,6 +3461,17 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
         // ((A ^ N) - B) & AndRHS -> (A - B) & AndRHS iff N&AndRHS == 0
         if (Value *V = FoldLogicalPlusAnd(Op0LHS, Op0RHS, AndRHS, true, I))
           return BinaryOperator::CreateAnd(V, AndRHS);
+
+        // (A - N) & AndRHS -> -N & AndRHS where A & AndRHS == 0
+        if (Op0I->hasOneUse() && MaskedValueIsZero(Op0LHS, AndRHSMask)) {
+          ConstantInt *A = dyn_cast<ConstantInt>(Op0LHS);
+          if (!A || !A->isZero()) {
+            Instruction *NewNeg = BinaryOperator::CreateNeg(Op0RHS);
+            InsertNewInstBefore(NewNeg, I);
+            return BinaryOperator::CreateAnd(NewNeg, AndRHS);
+          }
+        }
+
         break;
       }
 
@@ -3780,7 +3791,7 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
           }
     }
   }
-      
+
   return Changed ? &I : 0;
 }
 
diff --git a/test/Transforms/InstCombine/2008-07-08-SubAnd.ll b/test/Transforms/InstCombine/2008-07-08-SubAnd.ll
new file mode 100644 (file)
index 0000000..bf3afb9
--- /dev/null
@@ -0,0 +1,9 @@
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep -v {i32 8}
+; PR2330
+
+define i32 @a(i32 %a) nounwind  {
+entry:
+       %tmp2 = sub i32 8, %a           ; <i32> [#uses=1]
+       %tmp3 = and i32 %tmp2, 7                ; <i32> [#uses=1]
+       ret i32 %tmp3
+}