Changeset 149152 in webkit
- Timestamp:
- Apr 25, 2013 3:52:34 PM (11 years ago)
- Location:
- trunk
- Files:
-
- 9 added
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r149151 r149152 1 2013-04-25 Roman Zhuykov <zhroma@ispras.ru> 2 3 Arithmetic operations with negative zero should be optimized correclty. 4 https://bugs.webkit.org/show_bug.cgi?id=113862 5 6 Reviewed by Filip Pizlo. 7 * fast/js/regress/negative-zero-divide-expected.txt: Added. 8 * fast/js/regress/negative-zero-divide.html: Added. 9 * fast/js/regress/negative-zero-modulo-expected.txt: Added. 10 * fast/js/regress/negative-zero-modulo.html: Added. 11 * fast/js/regress/negative-zero-negate-expected.txt: Added. 12 * fast/js/regress/negative-zero-negate.html: Added. 13 * fast/js/regress/script-tests/negative-zero-divide.js: Added. 14 (foo): 15 * fast/js/regress/script-tests/negative-zero-modulo.js: Added. 16 (foo): 17 * fast/js/regress/script-tests/negative-zero-negate.js: Added. 18 (foo): 19 1 20 2013-04-25 Kent Tamura <tkent@chromium.org> 2 21 -
trunk/Source/JavaScriptCore/ChangeLog
r149146 r149152 1 2013-04-25 Roman Zhuykov <zhroma@ispras.ru> 2 3 Fix problems with processing negative zero on DFG. 4 https://bugs.webkit.org/show_bug.cgi?id=113862 5 6 Reviewed by Filip Pizlo. 7 8 Fix NodeNeedsNegZero flag propagation in BackwardPropagationPhase. 9 Function arithNodeFlags should not mask NodeNeedsNegZero flag for ArithNegate and DoubleAsInt32 10 nodes and this flag should be always used to decide where we need to generate nezative-zero checks. 11 Remove unnecessary negative-zero checks from integer ArithDiv on ARM. 12 Also remove such checks from integer ArithMod on ARM and X86, and make them always to 13 check not only "modulo_result == 0" but also "dividend < 0". 14 Generate faster code for case when ArithMod operation divisor is constant power of 2 on ARMv7 15 in the same way as on ARMv7s, and add negative-zero checks into this code when needed. 16 Change speculationCheck ExitKind from Overflow to NegativeZero where applicable. 17 18 This shows 30% speedup of math-spectral-norm, and 5% speedup 19 on SunSpider overall on ARMv7 Linux. 20 21 * assembler/MacroAssemblerARM.h: 22 (JSC::MacroAssemblerARM::branchConvertDoubleToInt32): 23 * assembler/MacroAssemblerARMv7.h: 24 (JSC::MacroAssemblerARMv7::branchConvertDoubleToInt32): 25 * assembler/MacroAssemblerMIPS.h: 26 (JSC::MacroAssemblerMIPS::branchConvertDoubleToInt32): 27 * assembler/MacroAssemblerSH4.h: 28 (JSC::MacroAssemblerSH4::branchConvertDoubleToInt32): 29 * assembler/MacroAssemblerX86Common.h: 30 (JSC::MacroAssemblerX86Common::branchConvertDoubleToInt32): 31 * dfg/DFGBackwardsPropagationPhase.cpp: 32 (JSC::DFG::BackwardsPropagationPhase::isNotNegZero): 33 (JSC::DFG::BackwardsPropagationPhase::isNotPosZero): 34 (JSC::DFG::BackwardsPropagationPhase::propagate): 35 * dfg/DFGNode.h: 36 (JSC::DFG::Node::arithNodeFlags): 37 * dfg/DFGSpeculativeJIT.cpp: 38 (JSC::DFG::SpeculativeJIT::compileDoubleAsInt32): 39 (JSC::DFG::SpeculativeJIT::compileSoftModulo): 40 (JSC::DFG::SpeculativeJIT::compileArithNegate): 41 1 42 2013-04-25 Oliver Hunt <oliver@apple.com> 2 43 -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerARM.h
r148893 r149152 1245 1245 // May also branch for some values that are representable in 32 bits 1246 1246 // (specifically, in this case, 0). 1247 void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID )1247 void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID, bool negZeroCheck = true) 1248 1248 { 1249 1249 m_assembler.vcvt_s32_f64(ARMRegisters::SD0 << 1, src); … … 1255 1255 1256 1256 // If the result is zero, it might have been -0.0, and 0.0 equals to -0.0 1257 failureCases.append(branchTest32(Zero, dest)); 1257 if (negZeroCheck) 1258 failureCases.append(branchTest32(Zero, dest)); 1258 1259 } 1259 1260 -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
r148942 r149152 1105 1105 // May also branch for some values that are representable in 32 bits 1106 1106 // (specifically, in this case, 0). 1107 void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID )1107 void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID, bool negZeroCheck = true) 1108 1108 { 1109 1109 m_assembler.vcvt_floatingPointToSigned(fpTempRegisterAsSingle(), src); … … 1115 1115 1116 1116 // If the result is zero, it might have been -0.0, and the double comparison won't catch this! 1117 failureCases.append(branchTest32(Zero, dest)); 1117 if (negZeroCheck) 1118 failureCases.append(branchTest32(Zero, dest)); 1118 1119 } 1119 1120 -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
r148893 r149152 2630 2630 // May also branch for some values that are representable in 32 bits 2631 2631 // (specifically, in this case, 0). 2632 void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID fpTemp )2632 void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID fpTemp, bool negZeroCheck = true) 2633 2633 { 2634 2634 m_assembler.cvtwd(fpTempRegister, src); … … 2636 2636 2637 2637 // If the result is zero, it might have been -0.0, and the double comparison won't catch this! 2638 failureCases.append(branch32(Equal, dest, MIPSRegisters::zero)); 2638 if (negZeroCheck) 2639 failureCases.append(branch32(Equal, dest, MIPSRegisters::zero)); 2639 2640 2640 2641 // Convert the integer result back to float & compare to the original value - if not equal or unordered (NaN) then jump. -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h
r149078 r149152 2037 2037 } 2038 2038 2039 void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID fpTemp )2039 void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID fpTemp, bool negZeroCheck = true) 2040 2040 { 2041 2041 m_assembler.ftrcdrmfpul(src); … … 2044 2044 failureCases.append(branchDouble(DoubleNotEqualOrUnordered, fscratch, src)); 2045 2045 2046 if (dest == SH4Registers::r0) 2047 m_assembler.cmpEqImmR0(0, dest); 2048 else { 2049 m_assembler.movImm8(0, scratchReg3); 2050 m_assembler.cmplRegReg(scratchReg3, dest, SH4Condition(Equal)); 2051 } 2052 failureCases.append(branchTrue()); 2046 if (negZeroCheck) { 2047 if (dest == SH4Registers::r0) 2048 m_assembler.cmpEqImmR0(0, dest); 2049 else { 2050 m_assembler.movImm8(0, scratchReg3); 2051 m_assembler.cmplRegReg(scratchReg3, dest, SH4Condition(Equal)); 2052 } 2053 failureCases.append(branchTrue()); 2054 } 2053 2055 } 2054 2056 -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h
r148893 r149152 886 886 // May also branch for some values that are representable in 32 bits 887 887 // (specifically, in this case, 0). 888 void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID fpTemp )888 void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID fpTemp, bool negZeroCheck = true) 889 889 { 890 890 ASSERT(isSSE2Present()); … … 892 892 893 893 // If the result is zero, it might have been -0.0, and the double comparison won't catch this! 894 failureCases.append(branchTest32(Zero, dest)); 894 if (negZeroCheck) 895 failureCases.append(branchTest32(Zero, dest)); 895 896 896 897 // Convert the integer result back to float & compare to the original value - if not equal or unordered (NaN) then jump. -
trunk/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp
r146382 r149152 67 67 return false; 68 68 double value = m_graph.valueOfNumberConstant(node); 69 return !value && 1.0 / value < 0.0;70 } 71 72 bool isNot Zero(Node* node)69 return (value || 1.0 / value > 0.0); 70 } 71 72 bool isNotPosZero(Node* node) 73 73 { 74 74 if (!m_graph.isNumberConstant(node)) 75 75 return false; 76 return !!m_graph.valueOfNumberConstant(node); 76 double value = m_graph.valueOfNumberConstant(node); 77 return (value || 1.0 / value < 0.0); 77 78 } 78 79 … … 248 249 249 250 case ArithSub: { 250 if (isNot Zero(node->child1().node()) || isNotZero(node->child2().node()))251 if (isNotNegZero(node->child1().node()) || isNotPosZero(node->child2().node())) 251 252 flags &= ~NodeNeedsNegZero; 252 253 if (!isWithinPowerOfTwo<32>(node->child1()) && !isWithinPowerOfTwo<32>(node->child2())) -
trunk/Source/JavaScriptCore/dfg/DFGNode.h
r149041 r149152 523 523 { 524 524 NodeFlags result = m_flags & NodeArithFlagsMask; 525 if (op() == ArithMul || op() == ArithDiv || op() == ArithMod )525 if (op() == ArithMul || op() == ArithDiv || op() == ArithMod || op() == ArithNegate || op() == DoubleAsInt32) 526 526 return result; 527 527 return result & ~NodeNeedsNegZero; -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r149050 r149152 2396 2396 2397 2397 JITCompiler::JumpList failureCases; 2398 m_jit.branchConvertDoubleToInt32(valueFPR, resultGPR, failureCases, scratchFPR); 2398 bool negZeroCheck = !nodeCanIgnoreNegativeZero(node->arithNodeFlags()); 2399 m_jit.branchConvertDoubleToInt32(valueFPR, resultGPR, failureCases, scratchFPR, negZeroCheck); 2399 2400 forwardSpeculationCheck(Overflow, JSValueRegs(), 0, failureCases, ValueRecovery::inFPR(valueFPR)); 2400 2401 … … 2909 2910 m_jit.assembler().cdq(); 2910 2911 m_jit.assembler().idivl_r(scratchGPR); 2911 // Check that we're not about to create negative zero.2912 // FIXME: if the node use doesn't care about neg zero, we can do this more easily.2913 JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, op1SaveGPR, TrustedImm32(0));2914 speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, edx.gpr()));2915 numeratorPositive.link(&m_jit);2916 2912 if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags())) { 2913 // Check that we're not about to create negative zero. 2914 JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, op1SaveGPR, TrustedImm32(0)); 2915 speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, edx.gpr())); 2916 numeratorPositive.link(&m_jit); 2917 } 2917 2918 if (op1SaveGPR != op1Gpr) 2918 2919 unlock(op1SaveGPR); … … 2922 2923 } 2923 2924 } 2924 #elif CPU(APPLE_ARMV7S) 2925 #elif CPU(APPLE_ARMV7S) || CPU(ARM_THUMB2) 2925 2926 if (isInt32Constant(node->child2().node())) { 2926 2927 int32_t divisor = valueOfInt32Constant(node->child2().node()); … … 2938 2939 m_jit.assembler().neg(resultGPR, resultGPR); 2939 2940 2941 if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags())) { 2942 // Check that we're not about to create negative zero. 2943 JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, dividendGPR, TrustedImm32(0)); 2944 speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, resultGPR)); 2945 numeratorPositive.link(&m_jit); 2946 } 2940 2947 integerResult(resultGPR, node); 2941 2948 return; … … 3001 3008 unlock(op2TempGPR); 3002 3009 3003 // Check that we're not about to create negative zero. 3004 // FIXME: if the node use doesn't care about neg zero, we can do this more easily. 3005 JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, op1SaveGPR, TrustedImm32(0)); 3006 speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, edx.gpr())); 3007 numeratorPositive.link(&m_jit); 3010 if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags())) { 3011 // Check that we're not about to create negative zero. 3012 JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, op1SaveGPR, TrustedImm32(0)); 3013 speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, edx.gpr())); 3014 numeratorPositive.link(&m_jit); 3015 } 3008 3016 3009 3017 if (op1SaveGPR != op1GPR) … … 3030 3038 // Check that we're not about to create negative zero. 3031 3039 JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, dividendGPR, TrustedImm32(0)); 3032 speculationCheck( Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, quotientThenRemainderGPR));3040 speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, quotientThenRemainderGPR)); 3033 3041 numeratorPositive.link(&m_jit); 3034 3042 } … … 3049 3057 GPRTemporary intResult(this); 3050 3058 JITCompiler::JumpList failureCases; 3051 m_jit.branchConvertDoubleToInt32(result.fpr(), intResult.gpr(), failureCases, scratch.fpr() );3059 m_jit.branchConvertDoubleToInt32(result.fpr(), intResult.gpr(), failureCases, scratch.fpr(), false); 3052 3060 speculationCheck(Overflow, JSValueRegs(), 0, failureCases); 3061 if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags())) { 3062 // Check that we're not about to create negative zero. 3063 JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, op1GPR, TrustedImm32(0)); 3064 speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, intResult.gpr())); 3065 numeratorPositive.link(&m_jit); 3066 } 3053 3067 3054 3068 integerResult(intResult.gpr(), node); … … 3297 3311 speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchNeg32(MacroAssembler::Overflow, result.gpr())); 3298 3312 if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags())) 3299 speculationCheck( Overflow, JSValueRegs(), 0, m_jit.branchTest32(MacroAssembler::Zero, result.gpr()));3313 speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branchTest32(MacroAssembler::Zero, result.gpr())); 3300 3314 } 3301 3315
Note: See TracChangeset
for help on using the changeset viewer.