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 id30882
push userryanvm@gmail.com
push dateSat, 29 Oct 2016 13:12:06 +0000
treeherdermozilla-central@16cdd6273c48 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnbp, waldo
bugs1312620
milestone52.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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));