Bug 1207449: Conservatively mark MFilterTypeSet with phis as not float32-compatible; r=h4writer
authorBenjamin Bouvier <benj@benj.me>
Wed, 23 Sep 2015 19:43:00 +0200
changeset 264411 dd8f99f562aedc7f0e243f7b45a65d0959a79911
parent 264410 43269fbb9bd83d7b85f0de47f2f82cfac4b03f52
child 264412 c6765de566a32511826143c2d5c83512e83f68ab
push id65617
push userbenj@benj.me
push dateFri, 25 Sep 2015 12:46:11 +0000
treeherdermozilla-inbound@dd8f99f562ae [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersh4writer
bugs1207449
milestone44.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 1207449: Conservatively mark MFilterTypeSet with phis as not float32-compatible; r=h4writer
js/src/jit-test/tests/ion/filtertypeset-float32.js
js/src/jit/MIR.cpp
js/src/jit/MIR.h
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/filtertypeset-float32.js
@@ -0,0 +1,6 @@
+function f(x) {
+    return Math.fround((x ? 0 : x) | Math.max(x, x));
+}
+for (var j = 0; j < 2; ++j) {
+    assertEq(f((function(){}) - 4294967297 ? 1 : 1 | 0 && 4294967297), 1);
+}
--- a/js/src/jit/MIR.cpp
+++ b/js/src/jit/MIR.cpp
@@ -2390,20 +2390,35 @@ MFilterTypeSet::trySpecializeFloat32(Tem
     MDefinition* in = input();
     if (in->type() != MIRType_Float32)
         return;
 
     setResultType(MIRType_Float32);
 }
 
 bool
+MFilterTypeSet::canProduceFloat32() const
+{
+    // A FilterTypeSet should be a producer if the input is a producer too.
+    // Also, be overly conservative by marking as not float32 producer when the
+    // input is a phi, as phis can be cyclic (phiA -> FilterTypeSet -> phiB ->
+    // phiA) and FilterTypeSet doesn't belong in the Float32 phi analysis.
+    return !input()->isPhi() && input()->canProduceFloat32();
+}
+
+bool
 MFilterTypeSet::canConsumeFloat32(MUse* operand) const
 {
     MOZ_ASSERT(getUseFor(0) == operand);
-    return CheckUsesAreFloat32Consumers(this);
+    // A FilterTypeSet should be a consumer if all uses are consumer. See also
+    // comment below MFilterTypeSet::canProduceFloat32.
+    bool allConsumerUses = true;
+    for (MUseDefIterator use(this); allConsumerUses && use; use++)
+        allConsumerUses &= !use.def()->isPhi() && use.def()->canConsumeFloat32(use.use());
+    return allConsumerUses;
 }
 
 void
 MBinaryArithInstruction::trySpecializeFloat32(TempAllocator& alloc)
 {
     // Do not use Float32 if we can use int32.
     if (specialization_ == MIRType_Int32)
         return;
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -12366,17 +12366,17 @@ class MFilterTypeSet
         return AliasSet::None();
     }
     virtual bool neverHoist() const override {
         return resultTypeSet()->empty();
     }
     void computeRange(TempAllocator& alloc) override;
 
     bool isFloat32Commutative() const override { return true; }
-    bool canProduceFloat32() const override { return input()->canProduceFloat32(); }
+    bool canProduceFloat32() const override;
     bool canConsumeFloat32(MUse* operand) const override;
     void trySpecializeFloat32(TempAllocator& alloc) override;
 };
 
 // Given a value, guard that the value is in a particular TypeSet, then returns
 // that value.
 class MTypeBarrier
   : public MUnaryInstruction,