[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp

Chris Lattner sabre at nondot.org
Thu Jun 14 22:58:46 PDT 2007



Changes in directory llvm/lib/Transforms/Scalar:

InstructionCombining.cpp updated: 1.770 -> 1.771
---
Log message:

Implement two xforms:
1. ~(~X | Y) === (X & ~Y) 
2. (A|B) & ~(A&B) -> A^B

This allows us to transform  ~(~(a|b) | (a&b)) -> a^b.

This implements PR1510: http://llvm.org/PR1510  for scalar values.


---
Diffs of the changes:  (+26 -6)

 InstructionCombining.cpp |   32 ++++++++++++++++++++++++++------
 1 files changed, 26 insertions(+), 6 deletions(-)


Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.770 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.771
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.770	Fri Jun 15 00:26:55 2007
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp	Fri Jun 15 00:58:24 2007
@@ -3363,13 +3363,28 @@
   }
   
   {
-    Value *A = 0, *B = 0;
-    if (match(Op0, m_Or(m_Value(A), m_Value(B))))
+    Value *A = 0, *B = 0, *C = 0, *D = 0;
+    if (match(Op0, m_Or(m_Value(A), m_Value(B)))) {
       if (A == Op1 || B == Op1)    // (A | ?) & A  --> A
         return ReplaceInstUsesWith(I, Op1);
-    if (match(Op1, m_Or(m_Value(A), m_Value(B))))
+    
+      // (A|B) & ~(A&B) -> A^B
+      if (match(Op1, m_Not(m_And(m_Value(C), m_Value(D))))) {
+        if ((A == C && B == D) || (A == D && B == C))
+          return BinaryOperator::createXor(A, B);
+      }
+    }
+    
+    if (match(Op1, m_Or(m_Value(A), m_Value(B)))) {
       if (A == Op0 || B == Op0)    // A & (A | ?)  --> A
         return ReplaceInstUsesWith(I, Op0);
+
+      // ~(A&B) & (A|B) -> A^B
+      if (match(Op0, m_Not(m_And(m_Value(C), m_Value(D))))) {
+        if ((A == C && B == D) || (A == D && B == C))
+          return BinaryOperator::createXor(A, B);
+      }
+    }
     
     if (Op0->hasOneUse() &&
         match(Op0, m_Xor(m_Value(A), m_Value(B)))) {
@@ -4137,15 +4152,20 @@
           return BinaryOperator::createAdd(Op0I->getOperand(1), ConstantRHS);
         }
 
-      // ~(~X & Y) --> (X | ~Y)
-      if (Op0I->getOpcode() == Instruction::And && RHS->isAllOnesValue()) {
+      // ~(~X & Y) --> (X | ~Y) - De Morgan's Law
+      // ~(~X | Y) === (X & ~Y) - De Morgan's Law
+      if ((Op0I->getOpcode() == Instruction::And || 
+           Op0I->getOpcode() == Instruction::Or) && 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 (Op0I->getOpcode() == Instruction::And)
+            return BinaryOperator::createOr(Op0NotVal, NotY);
+          else
+            return BinaryOperator::createAnd(Op0NotVal, NotY);
         }
       }
           






More information about the llvm-commits mailing list