Clean up art::HConstant predicates.

- Make the difference between arithmetic zero and zero-bit
  pattern non ambiguous.
- Introduce Boolean predicates in art::HIntConstant for when
  they are used as Booleans.
- Introduce aritmetic positive and negative zero predicates
  for floating-point constants.

Bug: 27639313
Change-Id: Ia04ecc6f6aa7450136028c5362ed429760c883bd
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 3733850..88d39d1 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -2427,8 +2427,13 @@
 
   bool CanBeMoved() const OVERRIDE { return true; }
 
+  // Is this constant -1 in the arithmetic sense?
   virtual bool IsMinusOne() const { return false; }
-  virtual bool IsZero() const { return false; }
+  // Is this constant 0 in the arithmetic sense?
+  virtual bool IsArithmeticZero() const { return false; }
+  // Is this constant a 0-bit pattern?
+  virtual bool IsZeroBitPattern() const { return false; }
+  // Is this constant 1 in the arithmetic sense?
   virtual bool IsOne() const { return false; }
 
   virtual uint64_t GetValueAsUint64() const = 0;
@@ -2449,6 +2454,9 @@
 
   size_t ComputeHashCode() const OVERRIDE { return 0; }
 
+  // The null constant representation is a 0-bit pattern.
+  virtual bool IsZeroBitPattern() const { return true; }
+
   DECLARE_INSTRUCTION(NullConstant);
 
  private:
@@ -2476,9 +2484,15 @@
   size_t ComputeHashCode() const OVERRIDE { return GetValue(); }
 
   bool IsMinusOne() const OVERRIDE { return GetValue() == -1; }
-  bool IsZero() const OVERRIDE { return GetValue() == 0; }
+  bool IsArithmeticZero() const OVERRIDE { return GetValue() == 0; }
+  bool IsZeroBitPattern() const OVERRIDE { return GetValue() == 0; }
   bool IsOne() const OVERRIDE { return GetValue() == 1; }
 
+  // Integer constants are used to encode Boolean values as well,
+  // where 1 means true and 0 means false.
+  bool IsTrue() const { return GetValue() == 1; }
+  bool IsFalse() const { return GetValue() == 0; }
+
   DECLARE_INSTRUCTION(IntConstant);
 
  private:
@@ -2509,7 +2523,8 @@
   size_t ComputeHashCode() const OVERRIDE { return static_cast<size_t>(GetValue()); }
 
   bool IsMinusOne() const OVERRIDE { return GetValue() == -1; }
-  bool IsZero() const OVERRIDE { return GetValue() == 0; }
+  bool IsArithmeticZero() const OVERRIDE { return GetValue() == 0; }
+  bool IsZeroBitPattern() const OVERRIDE { return GetValue() == 0; }
   bool IsOne() const OVERRIDE { return GetValue() == 1; }
 
   DECLARE_INSTRUCTION(LongConstant);
@@ -2542,7 +2557,16 @@
   bool IsMinusOne() const OVERRIDE {
     return bit_cast<uint32_t, float>(value_) == bit_cast<uint32_t, float>((-1.0f));
   }
-  bool IsZero() const OVERRIDE {
+  bool IsArithmeticZero() const OVERRIDE {
+    return std::fpclassify(value_) == FP_ZERO;
+  }
+  bool IsArithmeticPositiveZero() const {
+    return IsArithmeticZero() && !std::signbit(value_);
+  }
+  bool IsArithmeticNegativeZero() const {
+    return IsArithmeticZero() && std::signbit(value_);
+  }
+  bool IsZeroBitPattern() const OVERRIDE {
     return bit_cast<uint32_t, float>(value_) == bit_cast<uint32_t, float>(0.0f);
   }
   bool IsOne() const OVERRIDE {
@@ -2584,7 +2608,16 @@
   bool IsMinusOne() const OVERRIDE {
     return bit_cast<uint64_t, double>(value_) == bit_cast<uint64_t, double>((-1.0));
   }
-  bool IsZero() const OVERRIDE {
+  bool IsArithmeticZero() const OVERRIDE {
+    return std::fpclassify(value_) == FP_ZERO;
+  }
+  bool IsArithmeticPositiveZero() const {
+    return IsArithmeticZero() && !std::signbit(value_);
+  }
+  bool IsArithmeticNegativeZero() const {
+    return IsArithmeticZero() && std::signbit(value_);
+  }
+  bool IsZeroBitPattern() const OVERRIDE {
     return bit_cast<uint64_t, double>(value_) == bit_cast<uint64_t, double>((0.0));
   }
   bool IsOne() const OVERRIDE {