[optimizing] Improve constant folding on logical and

Constant fold a & ~a = ~a & a = 0.

Test: added test to 442-checker-constant-folding
Test: test-art-host,test-art-target
Change-Id: Ib637c93e99ce22dd1ecd5684d05ce5ca4c9c823a
diff --git a/compiler/optimizing/constant_folding.cc b/compiler/optimizing/constant_folding.cc
index 09e7cab..2031707 100644
--- a/compiler/optimizing/constant_folding.cc
+++ b/compiler/optimizing/constant_folding.cc
@@ -217,6 +217,7 @@
 }
 
 void InstructionWithAbsorbingInputSimplifier::VisitAnd(HAnd* instruction) {
+  DataType::Type type = instruction->GetType();
   HConstant* input_cst = instruction->GetConstantRight();
   if ((input_cst != nullptr) && input_cst->IsZeroBitPattern()) {
     // Replace code looking like
@@ -226,6 +227,25 @@
     instruction->ReplaceWith(input_cst);
     instruction->GetBlock()->RemoveInstruction(instruction);
   }
+
+  HInstruction* left = instruction->GetLeft();
+  HInstruction* right = instruction->GetRight();
+
+  if (left->IsNot() ^ right->IsNot()) {
+    // Replace code looking like
+    //    NOT notsrc, src
+    //    AND dst, notsrc, src
+    // with
+    //    CONSTANT 0
+    HInstruction* hnot = (left->IsNot() ? left : right);
+    HInstruction* hother = (left->IsNot() ? right : left);
+    HInstruction* src = hnot->AsNot()->GetInput();
+
+    if (src == hother) {
+      instruction->ReplaceWith(GetGraph()->GetConstant(type, 0));
+      instruction->GetBlock()->RemoveInstruction(instruction);
+    }
+  }
 }
 
 void InstructionWithAbsorbingInputSimplifier::VisitCompare(HCompare* instruction) {