Add (D)CHECK_IMPLIES to ART logging

Adds an _IMPLIES macro which is equivalent to checking a => b. This
CL includes an example of how it could be useful to aid
readability.

Test: art/test/testrunner/testrunner.py --host --64 --optimizing -b
Change-Id: If36ccf2a1d10ebd0b0c9f9635020dc78f5ae94ae
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index 1016652..ff4ab59 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -5195,8 +5195,7 @@
         if (byte_swap) {
           v = BSWAP(v);
         }
-        // `field_type == DataType::Type::kReference` implies `v == 0`.
-        DCHECK((field_type != DataType::Type::kReference) || (v == 0));
+        DCHECK_IMPLIES(field_type == DataType::Type::kReference, v == 0);
         // Note: if heap poisoning is enabled, no need to poison
         // (negate) `v` if it is a reference, as it would be null.
         __ movl(field_addr, Immediate(v));
diff --git a/libartbase/base/logging.h b/libartbase/base/logging.h
index e573f03..7a421a4 100644
--- a/libartbase/base/logging.h
+++ b/libartbase/base/logging.h
@@ -149,6 +149,24 @@
                      -1)                       \
       .stream()
 
+// Check whether an implication holds between x and y, LOG(FATAL) if not. The value
+// of the expressions x and y is evaluated once. Extra logging can be appended
+// using << after. For example:
+//
+//     CHECK_IMPLIES(1==1, 0==1) results in
+//       "Check failed: 1==1 (true) implies 0==1 (false) ".
+// clang-format off
+#define CHECK_IMPLIES(LHS, RHS)                                                                  \
+  LIKELY(!(LHS) || (RHS)) || ABORT_AFTER_LOG_FATAL_EXPR(false) ||                                \
+      ::android::base::LogMessage(__FILE__, __LINE__, ::android::base::FATAL, _LOG_TAG_INTERNAL, \
+                                  -1)                                                            \
+              .stream()                                                                          \
+      << "Check failed: " #LHS << " (true) implies " #RHS << " (false)"
+// clang-format on
+
+#define DCHECK_IMPLIES(a, b) \
+  if (::android::base::kEnableDChecks) CHECK_IMPLIES(a, b)
+
 }  // namespace art
 
 #endif  // ART_LIBARTBASE_BASE_LOGGING_H_