- instcombine demorgan's law: and (not A), (not B) == not (or A, B)


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3495 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index 0f8ae0c..14a13fe 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -81,6 +81,8 @@
     // in the program.  Add the new instruction to the worklist.
     //
     void InsertNewInstBefore(Instruction *New, Instruction &Old) {
+      assert(New && New->getParent() == 0 &&
+             "New instruction already inserted into a basic block!");
       BasicBlock *BB = Old.getParent();
       BB->getInstList().insert(&Old, New);  // Insert inst
       WorkList.push_back(New);              // Add to worklist
@@ -292,6 +294,16 @@
     if (RHS->isAllOnesValue())
       return ReplaceInstUsesWith(I, Op0);
 
+  // and (not A), (not B) == not (or A, B)
+  if (Op0->use_size() == 1 && Op1->use_size() == 1)
+    if (Value *A = dyn_castNotInst(Op0))
+      if (Value *B = dyn_castNotInst(Op1)) {
+        Instruction *Or = BinaryOperator::create(Instruction::Or, A, B,
+                                                 I.getName()+".demorgan");
+        InsertNewInstBefore(Or, I);
+        return BinaryOperator::createNot(Or, I.getName());
+      }
+
   return Changed ? &I : 0;
 }