Add new transformation: // (~A | ~B) == (~(A & B))
authorChris Lattner <sabre@nondot.org>
Mon, 10 Mar 2003 23:13:59 +0000 (23:13 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 10 Mar 2003 23:13:59 +0000 (23:13 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@5738 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/InstructionCombining.cpp

index b020a85dcc71402bea850f30108d43186748f16e..79a551f70c887d83d2fbbb730d414cf11bec711f 100644 (file)
@@ -446,6 +446,7 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
     Instruction *Or = BinaryOperator::create(Instruction::Or, Op0NotVal,
                                              Op1NotVal,I.getName()+".demorgan",
                                              &I);
+    WorkList.push_back(Or);
     return BinaryOperator::createNot(Or);
   }
 
@@ -470,15 +471,25 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
     if (RHS->isAllOnesValue())
       return ReplaceInstUsesWith(I, Op1);
 
-  if (Value *X = dyn_castNotVal(Op0))   // ~A | A == -1
-    if (X == Op1)
-      return ReplaceInstUsesWith(I, 
-                            ConstantIntegral::getAllOnesValue(I.getType()));
+  Value *Op0NotVal = dyn_castNotVal(Op0);
+  Value *Op1NotVal = dyn_castNotVal(Op1);
 
-  if (Value *X = dyn_castNotVal(Op1))   // A | ~A == -1
-    if (X == Op0)
-      return ReplaceInstUsesWith(I, 
-                            ConstantIntegral::getAllOnesValue(I.getType()));
+  if (Op1 == Op0NotVal)   // ~A | A == -1
+    return ReplaceInstUsesWith(I, 
+                               ConstantIntegral::getAllOnesValue(I.getType()));
+
+  if (Op0 == Op1NotVal)   // A | ~A == -1
+    return ReplaceInstUsesWith(I, 
+                               ConstantIntegral::getAllOnesValue(I.getType()));
+
+  // (~A | ~B) == (~(A & B)) - Demorgan's Law
+  if (Op0NotVal && Op1NotVal && isOnlyUse(Op0) && isOnlyUse(Op1)) {
+    Instruction *And = BinaryOperator::create(Instruction::And, Op0NotVal,
+                                              Op1NotVal,I.getName()+".demorgan",
+                                              &I);
+    WorkList.push_back(And);
+    return BinaryOperator::createNot(And);
+  }
 
   return Changed ? &I : 0;
 }