Implement Transforms/InstCombine/and.ll:test17, a common case that
authorChris Lattner <sabre@nondot.org>
Fri, 18 Jun 2004 06:07:51 +0000 (06:07 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 18 Jun 2004 06:07:51 +0000 (06:07 +0000)
occurs due to unordered comparison macros in math.h

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

lib/Transforms/Scalar/InstructionCombining.cpp

index 1df6eef4d2ebf708e746789641187861d31cc4f8..826e2c765e7b92a10aa11d262aa84c323ca8bb10 100644 (file)
@@ -1130,6 +1130,9 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
   Value *Op0NotVal = dyn_castNotVal(Op0);
   Value *Op1NotVal = dyn_castNotVal(Op1);
 
+  if (Op0NotVal == Op1 || Op1NotVal == Op0)  // A & ~A  == ~A & A == 0
+    return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
+
   // (~A & ~B) == (~(A | B)) - Demorgan's Law
   if (Op0NotVal && Op1NotVal && isOnlyUse(Op0) && isOnlyUse(Op1)) {
     Instruction *Or = BinaryOperator::createOr(Op0NotVal, Op1NotVal,
@@ -1138,9 +1141,6 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
     return BinaryOperator::createNot(Or);
   }
 
-  if (Op0NotVal == Op1 || Op1NotVal == Op0)  // A & ~A  == ~A & A == 0
-    return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
-
   // (setcc1 A, B) & (setcc2 A, B) --> (setcc3 A, B)
   if (SetCondInst *RHS = dyn_cast<SetCondInst>(I.getOperand(1)))
     if (Instruction *R = AssociativeOpt(I, FoldSetCCLogical(*this, RHS)))
@@ -1271,6 +1271,18 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
                                               ConstantInt::get(I.getType(), 1));
           return BinaryOperator::createAdd(Op0I->getOperand(1), ConstantRHS);
         }
+
+      // ~(~X & Y) --> (X | ~Y)
+      if (Op0I->getOpcode() == Instruction::And && RHS->isAllOnesValue()) {
+        if (dyn_castNotVal(Op0I->getOperand(1))) Op0I->swapOperands();
+        if (Value *Op0NotVal = dyn_castNotVal(Op0I->getOperand(0))) {
+          Instruction *NotY =
+            BinaryOperator::createNot(Op0I->getOperand(1), 
+                                      Op0I->getOperand(1)->getName()+".not");
+          InsertNewInstBefore(NotY, I);
+          return BinaryOperator::createOr(Op0NotVal, NotY);
+        }
+      }
           
       if (ConstantInt *Op0CI = dyn_cast<ConstantInt>(Op0I->getOperand(1)))
         switch (Op0I->getOpcode()) {