Bug 1312620 - Add IsPositiveZero function to mfbt and use it to replace MPhi by MNaNToZero iff c is +0.0. r=nbp, r=waldo
authorJohannes Schulte <j_schulte@outlook.com>
Wed, 26 Oct 2016 17:47:42 +0200
changeset 319901 c1ef258c04f1960f6c014394f371fc0d3068ccb8
parent 319900 3ed4c1405691d36144387453876a3cd1234b3b13
child 319902 57c5a60badc7073ec99c09b1e6468fde23a87b15
push id20749
push userryanvm@gmail.com
push dateSat, 29 Oct 2016 13:21:21 +0000
treeherderfx-team@1b170b39ed6b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnbp, waldo
bugs1312620
milestone52.0a1
Bug 1312620 - Add IsPositiveZero function to mfbt and use it to replace MPhi by MNaNToZero iff c is +0.0. r=nbp, r=waldo
js/src/jit/MIR.cpp
mfbt/FloatingPoint.h
mfbt/tests/TestFloatingPoint.cpp
--- a/js/src/jit/MIR.cpp
+++ b/js/src/jit/MIR.cpp
@@ -2413,17 +2413,19 @@ MPhi::foldsTernary(TempAllocator& alloc)
         // When folding to the constant we need to hoist it.
         if (trueDef == c && !c->block()->dominates(block()))
             c->block()->moveBefore(pred->lastIns(), c);
         return trueDef;
     }
 
     // If testArg is an double type we can:
     // - fold testArg ? testArg : 0.0 to MNaNToZero(testArg)
-    if (testArg->type() == MIRType::Double && c->numberToDouble() == 0 && c != trueDef) {
+    if (testArg->type() == MIRType::Double && mozilla::IsPositiveZero(c->numberToDouble()) &&
+        c != trueDef)
+    {
         MNaNToZero* replace = MNaNToZero::New(alloc, testArg);
         test->block()->insertBefore(test, replace);
         return replace;
     }
 
     // If testArg is a string type we can:
     // - fold testArg ? testArg : "" to testArg
     // - fold testArg ? "" : testArg to ""
--- a/mfbt/FloatingPoint.h
+++ b/mfbt/FloatingPoint.h
@@ -181,16 +181,28 @@ IsNegativeZero(T aValue)
 {
   /* Only the sign bit is set if the value is -0. */
   typedef FloatingPoint<T> Traits;
   typedef typename Traits::Bits Bits;
   Bits bits = BitwiseCast<Bits>(aValue);
   return bits == Traits::kSignBit;
 }
 
+/** Determines wether a float/double represents +0. */
+template<typename T>
+static MOZ_ALWAYS_INLINE bool
+IsPositiveZero(T aValue)
+{
+  /* All bits are zero if the value is +0. */
+  typedef FloatingPoint<T> Traits;
+  typedef typename Traits::Bits Bits;
+  Bits bits = BitwiseCast<Bits>(aValue);
+  return bits == 0;
+}
+
 /**
  * Returns 0 if a float/double is NaN or infinite;
  * otherwise, the float/double is returned.
  */
 template<typename T>
 static MOZ_ALWAYS_INLINE T
 ToZeroIfNonfinite(T aValue)
 {
--- a/mfbt/tests/TestFloatingPoint.cpp
+++ b/mfbt/tests/TestFloatingPoint.cpp
@@ -12,16 +12,17 @@ using mozilla::ExponentComponent;
 using mozilla::FloatingPoint;
 using mozilla::FuzzyEqualsAdditive;
 using mozilla::FuzzyEqualsMultiplicative;
 using mozilla::IsFinite;
 using mozilla::IsInfinite;
 using mozilla::IsNaN;
 using mozilla::IsNegative;
 using mozilla::IsNegativeZero;
+using mozilla::IsPositiveZero;
 using mozilla::NegativeInfinity;
 using mozilla::NumberEqualsInt32;
 using mozilla::NumberIsInt32;
 using mozilla::NumbersAreIdentical;
 using mozilla::PositiveInfinity;
 using mozilla::SpecificNaN;
 using mozilla::UnspecifiedNaN;
 
@@ -372,16 +373,28 @@ TestFloatsPredicates()
   A(!IsNegativeZero(SpecificNaN<float>(0, 17)));;
   A(!IsNegativeZero(SpecificNaN<float>(0, 0x7fff0fUL)));
   A(!IsNegativeZero(UnspecifiedNaN<float>()));
   A(IsNegativeZero(-0.0f));
   A(!IsNegativeZero(0.0f));
   A(!IsNegativeZero(-1.0f));
   A(!IsNegativeZero(1.0f));
 
+  A(!IsPositiveZero(PositiveInfinity<float>()));
+  A(!IsPositiveZero(NegativeInfinity<float>()));
+  A(!IsPositiveZero(SpecificNaN<float>(1, 17)));;
+  A(!IsPositiveZero(SpecificNaN<float>(1, 0x7fff0fUL)));
+  A(!IsPositiveZero(SpecificNaN<float>(0, 17)));;
+  A(!IsPositiveZero(SpecificNaN<float>(0, 0x7fff0fUL)));
+  A(!IsPositiveZero(UnspecifiedNaN<float>()));
+  A(IsPositiveZero(0.0f));
+  A(!IsPositiveZero(-0.0f));
+  A(!IsPositiveZero(-1.0f));
+  A(!IsPositiveZero(1.0f));
+
   int32_t i;
   const int32_t BIG = 2097151;
   A(NumberIsInt32(0.0f, &i));
   A(i == 0);
   A(!NumberIsInt32(-0.0f, &i));
   A(NumberEqualsInt32(0.0f, &i));
   A(i == 0);
   A(NumberEqualsInt32(-0.0f, &i));