Title: [149152] trunk
Revision
149152
Author
[email protected]
Date
2013-04-25 15:52:34 -0700 (Thu, 25 Apr 2013)

Log Message

Source/_javascript_Core: Fix problems with processing negative zero on DFG.
https://bugs.webkit.org/show_bug.cgi?id=113862

Patch by Roman Zhuykov <[email protected]> on 2013-04-25
Reviewed by Filip Pizlo.

Fix NodeNeedsNegZero flag propagation in BackwardPropagationPhase.
Function arithNodeFlags should not mask NodeNeedsNegZero flag for ArithNegate and DoubleAsInt32
nodes and this flag should be always used to decide where we need to generate nezative-zero checks.
Remove unnecessary negative-zero checks from integer ArithDiv on ARM.
Also remove such checks from integer ArithMod on ARM and X86, and make them always to
check not only "modulo_result == 0" but also "dividend < 0".
Generate faster code for case when ArithMod operation divisor is constant power of 2 on ARMv7
in the same way as on ARMv7s, and add negative-zero checks into this code when needed.
Change speculationCheck ExitKind from Overflow to NegativeZero where applicable.

This shows 30% speedup of math-spectral-norm, and 5% speedup
on SunSpider overall on ARMv7 Linux.

* assembler/MacroAssemblerARM.h:
(JSC::MacroAssemblerARM::branchConvertDoubleToInt32):
* assembler/MacroAssemblerARMv7.h:
(JSC::MacroAssemblerARMv7::branchConvertDoubleToInt32):
* assembler/MacroAssemblerMIPS.h:
(JSC::MacroAssemblerMIPS::branchConvertDoubleToInt32):
* assembler/MacroAssemblerSH4.h:
(JSC::MacroAssemblerSH4::branchConvertDoubleToInt32):
* assembler/MacroAssemblerX86Common.h:
(JSC::MacroAssemblerX86Common::branchConvertDoubleToInt32):
* dfg/DFGBackwardsPropagationPhase.cpp:
(JSC::DFG::BackwardsPropagationPhase::isNotNegZero):
(JSC::DFG::BackwardsPropagationPhase::isNotPosZero):
(JSC::DFG::BackwardsPropagationPhase::propagate):
* dfg/DFGNode.h:
(JSC::DFG::Node::arithNodeFlags):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileDoubleAsInt32):
(JSC::DFG::SpeculativeJIT::compileSoftModulo):
(JSC::DFG::SpeculativeJIT::compileArithNegate):

LayoutTests: Arithmetic operations with negative zero should be optimized correclty.
https://bugs.webkit.org/show_bug.cgi?id=113862

Patch by Roman Zhuykov <[email protected]> on 2013-04-25
Reviewed by Filip Pizlo.
* fast/js/regress/negative-zero-divide-expected.txt: Added.
* fast/js/regress/negative-zero-divide.html: Added.
* fast/js/regress/negative-zero-modulo-expected.txt: Added.
* fast/js/regress/negative-zero-modulo.html: Added.
* fast/js/regress/negative-zero-negate-expected.txt: Added.
* fast/js/regress/negative-zero-negate.html: Added.
* fast/js/regress/script-tests/negative-zero-divide.js: Added.
(foo):
* fast/js/regress/script-tests/negative-zero-modulo.js: Added.
(foo):
* fast/js/regress/script-tests/negative-zero-negate.js: Added.
(foo):

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (149151 => 149152)


--- trunk/LayoutTests/ChangeLog	2013-04-25 22:51:08 UTC (rev 149151)
+++ trunk/LayoutTests/ChangeLog	2013-04-25 22:52:34 UTC (rev 149152)
@@ -1,3 +1,22 @@
+2013-04-25  Roman Zhuykov  <[email protected]>
+
+        Arithmetic operations with negative zero should be optimized correclty.
+        https://bugs.webkit.org/show_bug.cgi?id=113862
+
+        Reviewed by Filip Pizlo.
+        * fast/js/regress/negative-zero-divide-expected.txt: Added.
+        * fast/js/regress/negative-zero-divide.html: Added.
+        * fast/js/regress/negative-zero-modulo-expected.txt: Added.
+        * fast/js/regress/negative-zero-modulo.html: Added.
+        * fast/js/regress/negative-zero-negate-expected.txt: Added.
+        * fast/js/regress/negative-zero-negate.html: Added.
+        * fast/js/regress/script-tests/negative-zero-divide.js: Added.
+        (foo):
+        * fast/js/regress/script-tests/negative-zero-modulo.js: Added.
+        (foo):
+        * fast/js/regress/script-tests/negative-zero-negate.js: Added.
+        (foo):
+
 2013-04-25  Kent Tamura  <[email protected]>
 
         Ignore invalid regular expressions for input[pattern].

Added: trunk/LayoutTests/fast/js/regress/negative-zero-divide-expected.txt (0 => 149152)


--- trunk/LayoutTests/fast/js/regress/negative-zero-divide-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/js/regress/negative-zero-divide-expected.txt	2013-04-25 22:52:34 UTC (rev 149152)
@@ -0,0 +1,10 @@
+JSRegress/negative-zero-divide
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/js/regress/negative-zero-divide.html (0 => 149152)


--- trunk/LayoutTests/fast/js/regress/negative-zero-divide.html	                        (rev 0)
+++ trunk/LayoutTests/fast/js/regress/negative-zero-divide.html	2013-04-25 22:52:34 UTC (rev 149152)
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+<script src=""
+<script src=""
+</body>
+</html>

Added: trunk/LayoutTests/fast/js/regress/negative-zero-modulo-expected.txt (0 => 149152)


--- trunk/LayoutTests/fast/js/regress/negative-zero-modulo-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/js/regress/negative-zero-modulo-expected.txt	2013-04-25 22:52:34 UTC (rev 149152)
@@ -0,0 +1,10 @@
+JSRegress/negative-zero-modulo
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/js/regress/negative-zero-modulo.html (0 => 149152)


--- trunk/LayoutTests/fast/js/regress/negative-zero-modulo.html	                        (rev 0)
+++ trunk/LayoutTests/fast/js/regress/negative-zero-modulo.html	2013-04-25 22:52:34 UTC (rev 149152)
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+<script src=""
+<script src=""
+</body>
+</html>

Added: trunk/LayoutTests/fast/js/regress/negative-zero-negate-expected.txt (0 => 149152)


--- trunk/LayoutTests/fast/js/regress/negative-zero-negate-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/js/regress/negative-zero-negate-expected.txt	2013-04-25 22:52:34 UTC (rev 149152)
@@ -0,0 +1,10 @@
+JSRegress/negative-zero-negate
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/js/regress/negative-zero-negate.html (0 => 149152)


--- trunk/LayoutTests/fast/js/regress/negative-zero-negate.html	                        (rev 0)
+++ trunk/LayoutTests/fast/js/regress/negative-zero-negate.html	2013-04-25 22:52:34 UTC (rev 149152)
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+<script src=""
+<script src=""
+</body>
+</html>

Added: trunk/LayoutTests/fast/js/regress/script-tests/negative-zero-divide.js (0 => 149152)


--- trunk/LayoutTests/fast/js/regress/script-tests/negative-zero-divide.js	                        (rev 0)
+++ trunk/LayoutTests/fast/js/regress/script-tests/negative-zero-divide.js	2013-04-25 22:52:34 UTC (rev 149152)
@@ -0,0 +1,19 @@
+function foo() {
+  var x = 1;
+  var y = -1;
+  var s;
+  var i;
+  for (i = 0; i < 2001; i++) {
+    if (i == 2000)
+      x = 0;
+    s = 1/(x/y+(-0));
+  }
+  return s;
+}
+
+var x = (1/(0/-1+(-0))).toString();
+var y = foo().toString();
+
+if (x != y)
+    throw "Error: bad result: " + y;
+

Added: trunk/LayoutTests/fast/js/regress/script-tests/negative-zero-modulo.js (0 => 149152)


--- trunk/LayoutTests/fast/js/regress/script-tests/negative-zero-modulo.js	                        (rev 0)
+++ trunk/LayoutTests/fast/js/regress/script-tests/negative-zero-modulo.js	2013-04-25 22:52:34 UTC (rev 149152)
@@ -0,0 +1,18 @@
+function foo() {
+  var x = 4;
+  var s;
+  var i;
+  for (i = 0; i < 2001; i++) {
+    if (i == 2000)
+      x = -4;
+    s = 1/(x%4);
+  }
+  return s;
+}
+
+var x = (1/((-4)%4)).toString();
+var y = foo().toString();
+
+if (x != y)
+    throw "Error: bad result: " + y;
+

Added: trunk/LayoutTests/fast/js/regress/script-tests/negative-zero-negate.js (0 => 149152)


--- trunk/LayoutTests/fast/js/regress/script-tests/negative-zero-negate.js	                        (rev 0)
+++ trunk/LayoutTests/fast/js/regress/script-tests/negative-zero-negate.js	2013-04-25 22:52:34 UTC (rev 149152)
@@ -0,0 +1,18 @@
+function foo() {
+  var x = 1;
+  var s;
+  var i;
+  for (i = 0; i < 2001; i++) {
+    if (i == 2000)
+      x = 0;
+    s = 1/(-x);
+  }
+  return s;
+}
+
+var x = (1/(-0)).toString();
+var y = foo().toString();
+
+if (x != y)
+    throw "Error: bad result: " + y;
+

Modified: trunk/Source/_javascript_Core/ChangeLog (149151 => 149152)


--- trunk/Source/_javascript_Core/ChangeLog	2013-04-25 22:51:08 UTC (rev 149151)
+++ trunk/Source/_javascript_Core/ChangeLog	2013-04-25 22:52:34 UTC (rev 149152)
@@ -1,3 +1,44 @@
+2013-04-25  Roman Zhuykov  <[email protected]>
+
+        Fix problems with processing negative zero on DFG.
+        https://bugs.webkit.org/show_bug.cgi?id=113862
+
+        Reviewed by Filip Pizlo.
+
+        Fix NodeNeedsNegZero flag propagation in BackwardPropagationPhase.
+        Function arithNodeFlags should not mask NodeNeedsNegZero flag for ArithNegate and DoubleAsInt32
+        nodes and this flag should be always used to decide where we need to generate nezative-zero checks.
+        Remove unnecessary negative-zero checks from integer ArithDiv on ARM.
+        Also remove such checks from integer ArithMod on ARM and X86, and make them always to
+        check not only "modulo_result == 0" but also "dividend < 0".
+        Generate faster code for case when ArithMod operation divisor is constant power of 2 on ARMv7
+        in the same way as on ARMv7s, and add negative-zero checks into this code when needed.
+        Change speculationCheck ExitKind from Overflow to NegativeZero where applicable.
+ 
+        This shows 30% speedup of math-spectral-norm, and 5% speedup
+        on SunSpider overall on ARMv7 Linux.
+
+        * assembler/MacroAssemblerARM.h:
+        (JSC::MacroAssemblerARM::branchConvertDoubleToInt32):
+        * assembler/MacroAssemblerARMv7.h:
+        (JSC::MacroAssemblerARMv7::branchConvertDoubleToInt32):
+        * assembler/MacroAssemblerMIPS.h:
+        (JSC::MacroAssemblerMIPS::branchConvertDoubleToInt32):
+        * assembler/MacroAssemblerSH4.h:
+        (JSC::MacroAssemblerSH4::branchConvertDoubleToInt32):
+        * assembler/MacroAssemblerX86Common.h:
+        (JSC::MacroAssemblerX86Common::branchConvertDoubleToInt32):
+        * dfg/DFGBackwardsPropagationPhase.cpp:
+        (JSC::DFG::BackwardsPropagationPhase::isNotNegZero):
+        (JSC::DFG::BackwardsPropagationPhase::isNotPosZero):
+        (JSC::DFG::BackwardsPropagationPhase::propagate):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::arithNodeFlags):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileDoubleAsInt32):
+        (JSC::DFG::SpeculativeJIT::compileSoftModulo):
+        (JSC::DFG::SpeculativeJIT::compileArithNegate):
+
 2013-04-25  Oliver Hunt  <[email protected]>
 
         Stack guards are too conservative

Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerARM.h (149151 => 149152)


--- trunk/Source/_javascript_Core/assembler/MacroAssemblerARM.h	2013-04-25 22:51:08 UTC (rev 149151)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerARM.h	2013-04-25 22:52:34 UTC (rev 149152)
@@ -1244,7 +1244,7 @@
     // If the result is not representable as a 32 bit value, branch.
     // May also branch for some values that are representable in 32 bits
     // (specifically, in this case, 0).
-    void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID)
+    void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID, bool negZeroCheck = true)
     {
         m_assembler.vcvt_s32_f64(ARMRegisters::SD0 << 1, src);
         m_assembler.vmov_arm32(dest, ARMRegisters::SD0 << 1);
@@ -1254,7 +1254,8 @@
         failureCases.append(branchDouble(DoubleNotEqualOrUnordered, src, ARMRegisters::SD0));
 
         // If the result is zero, it might have been -0.0, and 0.0 equals to -0.0
-        failureCases.append(branchTest32(Zero, dest));
+        if (negZeroCheck)
+            failureCases.append(branchTest32(Zero, dest));
     }
 
     Jump branchDoubleNonZero(FPRegisterID reg, FPRegisterID scratch)

Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerARMv7.h (149151 => 149152)


--- trunk/Source/_javascript_Core/assembler/MacroAssemblerARMv7.h	2013-04-25 22:51:08 UTC (rev 149151)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerARMv7.h	2013-04-25 22:52:34 UTC (rev 149152)
@@ -1104,7 +1104,7 @@
     // If the result is not representable as a 32 bit value, branch.
     // May also branch for some values that are representable in 32 bits
     // (specifically, in this case, 0).
-    void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID)
+    void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID, bool negZeroCheck = true)
     {
         m_assembler.vcvt_floatingPointToSigned(fpTempRegisterAsSingle(), src);
         m_assembler.vmov(dest, fpTempRegisterAsSingle());
@@ -1114,7 +1114,8 @@
         failureCases.append(branchDouble(DoubleNotEqualOrUnordered, src, fpTempRegister));
 
         // If the result is zero, it might have been -0.0, and the double comparison won't catch this!
-        failureCases.append(branchTest32(Zero, dest));
+        if (negZeroCheck)
+            failureCases.append(branchTest32(Zero, dest));
     }
 
     Jump branchDoubleNonZero(FPRegisterID reg, FPRegisterID)

Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerMIPS.h (149151 => 149152)


--- trunk/Source/_javascript_Core/assembler/MacroAssemblerMIPS.h	2013-04-25 22:51:08 UTC (rev 149151)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerMIPS.h	2013-04-25 22:52:34 UTC (rev 149152)
@@ -2629,13 +2629,14 @@
     // If the result is not representable as a 32 bit value, branch.
     // May also branch for some values that are representable in 32 bits
     // (specifically, in this case, 0).
-    void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID fpTemp)
+    void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID fpTemp, bool negZeroCheck = true)
     {
         m_assembler.cvtwd(fpTempRegister, src);
         m_assembler.mfc1(dest, fpTempRegister);
 
         // If the result is zero, it might have been -0.0, and the double comparison won't catch this!
-        failureCases.append(branch32(Equal, dest, MIPSRegisters::zero));
+        if (negZeroCheck)
+            failureCases.append(branch32(Equal, dest, MIPSRegisters::zero));
 
         // Convert the integer result back to float & compare to the original value - if not equal or unordered (NaN) then jump.
         convertInt32ToDouble(dest, fpTemp);

Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerSH4.h (149151 => 149152)


--- trunk/Source/_javascript_Core/assembler/MacroAssemblerSH4.h	2013-04-25 22:51:08 UTC (rev 149151)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerSH4.h	2013-04-25 22:52:34 UTC (rev 149152)
@@ -2036,20 +2036,22 @@
         return branchTrue();
     }
 
-    void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID fpTemp)
+    void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID fpTemp, bool negZeroCheck = true)
     {
         m_assembler.ftrcdrmfpul(src);
         m_assembler.stsfpulReg(dest);
         convertInt32ToDouble(dest, fscratch);
         failureCases.append(branchDouble(DoubleNotEqualOrUnordered, fscratch, src));
 
-        if (dest == SH4Registers::r0)
-            m_assembler.cmpEqImmR0(0, dest);
-        else {
-            m_assembler.movImm8(0, scratchReg3);
-            m_assembler.cmplRegReg(scratchReg3, dest, SH4Condition(Equal));
+        if (negZeroCheck) {
+            if (dest == SH4Registers::r0)
+                m_assembler.cmpEqImmR0(0, dest);
+            else {
+                m_assembler.movImm8(0, scratchReg3);
+                m_assembler.cmplRegReg(scratchReg3, dest, SH4Condition(Equal));
+            }
+            failureCases.append(branchTrue());
         }
-        failureCases.append(branchTrue());
     }
 
     void neg32(RegisterID dst)

Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerX86Common.h (149151 => 149152)


--- trunk/Source/_javascript_Core/assembler/MacroAssemblerX86Common.h	2013-04-25 22:51:08 UTC (rev 149151)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerX86Common.h	2013-04-25 22:52:34 UTC (rev 149152)
@@ -885,13 +885,14 @@
     // If the result is not representable as a 32 bit value, branch.
     // May also branch for some values that are representable in 32 bits
     // (specifically, in this case, 0).
-    void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID fpTemp)
+    void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID fpTemp, bool negZeroCheck = true)
     {
         ASSERT(isSSE2Present());
         m_assembler.cvttsd2si_rr(src, dest);
 
         // If the result is zero, it might have been -0.0, and the double comparison won't catch this!
-        failureCases.append(branchTest32(Zero, dest));
+        if (negZeroCheck)
+            failureCases.append(branchTest32(Zero, dest));
 
         // Convert the integer result back to float & compare to the original value - if not equal or unordered (NaN) then jump.
         convertInt32ToDouble(dest, fpTemp);

Modified: trunk/Source/_javascript_Core/dfg/DFGBackwardsPropagationPhase.cpp (149151 => 149152)


--- trunk/Source/_javascript_Core/dfg/DFGBackwardsPropagationPhase.cpp	2013-04-25 22:51:08 UTC (rev 149151)
+++ trunk/Source/_javascript_Core/dfg/DFGBackwardsPropagationPhase.cpp	2013-04-25 22:52:34 UTC (rev 149152)
@@ -66,14 +66,15 @@
         if (!m_graph.isNumberConstant(node))
             return false;
         double value = m_graph.valueOfNumberConstant(node);
-        return !value && 1.0 / value < 0.0;
+        return (value || 1.0 / value > 0.0);
     }
     
-    bool isNotZero(Node* node)
+    bool isNotPosZero(Node* node)
     {
         if (!m_graph.isNumberConstant(node))
             return false;
-        return !!m_graph.valueOfNumberConstant(node);
+        double value = m_graph.valueOfNumberConstant(node);
+        return (value || 1.0 / value < 0.0);
     }
 
     // Tests if the absolute value is strictly less than the power of two.
@@ -247,7 +248,7 @@
         }
             
         case ArithSub: {
-            if (isNotZero(node->child1().node()) || isNotZero(node->child2().node()))
+            if (isNotNegZero(node->child1().node()) || isNotPosZero(node->child2().node()))
                 flags &= ~NodeNeedsNegZero;
             if (!isWithinPowerOfTwo<32>(node->child1()) && !isWithinPowerOfTwo<32>(node->child2()))
                 flags |= NodeUsedAsNumber;

Modified: trunk/Source/_javascript_Core/dfg/DFGNode.h (149151 => 149152)


--- trunk/Source/_javascript_Core/dfg/DFGNode.h	2013-04-25 22:51:08 UTC (rev 149151)
+++ trunk/Source/_javascript_Core/dfg/DFGNode.h	2013-04-25 22:52:34 UTC (rev 149152)
@@ -522,7 +522,7 @@
     NodeFlags arithNodeFlags()
     {
         NodeFlags result = m_flags & NodeArithFlagsMask;
-        if (op() == ArithMul || op() == ArithDiv || op() == ArithMod)
+        if (op() == ArithMul || op() == ArithDiv || op() == ArithMod || op() == ArithNegate || op() == DoubleAsInt32)
             return result;
         return result & ~NodeNeedsNegZero;
     }

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (149151 => 149152)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2013-04-25 22:51:08 UTC (rev 149151)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2013-04-25 22:52:34 UTC (rev 149152)
@@ -2395,7 +2395,8 @@
     GPRReg resultGPR = result.gpr();
 
     JITCompiler::JumpList failureCases;
-    m_jit.branchConvertDoubleToInt32(valueFPR, resultGPR, failureCases, scratchFPR);
+    bool negZeroCheck = !nodeCanIgnoreNegativeZero(node->arithNodeFlags());
+    m_jit.branchConvertDoubleToInt32(valueFPR, resultGPR, failureCases, scratchFPR, negZeroCheck);
     forwardSpeculationCheck(Overflow, JSValueRegs(), 0, failureCases, ValueRecovery::inFPR(valueFPR));
 
     integerResult(resultGPR, node);
@@ -2908,12 +2909,12 @@
                 speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branch32(JITCompiler::Equal, eax.gpr(), TrustedImm32(-2147483647-1)));
             m_jit.assembler().cdq();
             m_jit.assembler().idivl_r(scratchGPR);
-            // Check that we're not about to create negative zero.
-            // FIXME: if the node use doesn't care about neg zero, we can do this more easily.
-            JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, op1SaveGPR, TrustedImm32(0));
-            speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, edx.gpr()));
-            numeratorPositive.link(&m_jit);
-            
+            if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
+                // Check that we're not about to create negative zero.
+                JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, op1SaveGPR, TrustedImm32(0));
+                speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, edx.gpr()));
+                numeratorPositive.link(&m_jit);
+            }
             if (op1SaveGPR != op1Gpr)
                 unlock(op1SaveGPR);
 
@@ -2921,7 +2922,7 @@
             return;
         }
     }
-#elif CPU(APPLE_ARMV7S)
+#elif CPU(APPLE_ARMV7S) || CPU(ARM_THUMB2)
     if (isInt32Constant(node->child2().node())) {
         int32_t divisor = valueOfInt32Constant(node->child2().node());
         if (divisor > 0 && hasOneBitSet(divisor)) { // If power of 2 then just mask
@@ -2937,6 +2938,12 @@
             m_jit.assembler().it(ARMv7Assembler::ConditionLT);
             m_jit.assembler().neg(resultGPR, resultGPR);
 
+            if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
+                // Check that we're not about to create negative zero.
+                JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, dividendGPR, TrustedImm32(0));
+                speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, resultGPR));
+                numeratorPositive.link(&m_jit);
+            }
             integerResult(resultGPR, node);
             return;
         }
@@ -3000,11 +3007,12 @@
     if (op2TempGPR != InvalidGPRReg)
         unlock(op2TempGPR);
 
-    // Check that we're not about to create negative zero.
-    // FIXME: if the node use doesn't care about neg zero, we can do this more easily.
-    JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, op1SaveGPR, TrustedImm32(0));
-    speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, edx.gpr()));
-    numeratorPositive.link(&m_jit);
+    if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
+        // Check that we're not about to create negative zero.
+        JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, op1SaveGPR, TrustedImm32(0));
+        speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, edx.gpr()));
+        numeratorPositive.link(&m_jit);
+    }
     
     if (op1SaveGPR != op1GPR)
         unlock(op1SaveGPR);
@@ -3029,7 +3037,7 @@
     if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
         // Check that we're not about to create negative zero.
         JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, dividendGPR, TrustedImm32(0));
-        speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, quotientThenRemainderGPR));
+        speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, quotientThenRemainderGPR));
         numeratorPositive.link(&m_jit);
     }
 
@@ -3048,8 +3056,14 @@
     FPRTemporary scratch(this);
     GPRTemporary intResult(this);
     JITCompiler::JumpList failureCases;
-    m_jit.branchConvertDoubleToInt32(result.fpr(), intResult.gpr(), failureCases, scratch.fpr());
+    m_jit.branchConvertDoubleToInt32(result.fpr(), intResult.gpr(), failureCases, scratch.fpr(), false);
     speculationCheck(Overflow, JSValueRegs(), 0, failureCases);
+    if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
+        // Check that we're not about to create negative zero.
+        JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, op1GPR, TrustedImm32(0));
+        speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, intResult.gpr()));
+        numeratorPositive.link(&m_jit);
+    }
     
     integerResult(intResult.gpr(), node);
 #endif // CPU(X86) || CPU(X86_64)
@@ -3296,7 +3310,7 @@
         else {
             speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchNeg32(MacroAssembler::Overflow, result.gpr()));
             if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags()))
-                speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(MacroAssembler::Zero, result.gpr()));
+                speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branchTest32(MacroAssembler::Zero, result.gpr()));
         }
 
         integerResult(result.gpr(), node);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to