Added: trunk/LayoutTests/fast/js/dfg-int32-to-double-on-known-number-expected.txt (0 => 119299)
--- trunk/LayoutTests/fast/js/dfg-int32-to-double-on-known-number-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/js/dfg-int32-to-double-on-known-number-expected.txt 2012-06-01 23:18:59 UTC (rev 119299)
@@ -0,0 +1,209 @@
+Tests that we don't emit unnecessary speculation checks when performing an int32 to double conversion on a value that is proved to be a number, predicted to be an int32, but not proved to be an int32.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS foo({f:5}, 42.5) is 52.5
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (119298 => 119299)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2012-06-01 23:18:21 UTC (rev 119298)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2012-06-01 23:18:59 UTC (rev 119299)
@@ -1850,9 +1850,11 @@
JITCompiler::Jump isInteger = m_jit.branchPtr(
MacroAssembler::AboveOrEqual, op1GPR, GPRInfo::tagTypeNumberRegister);
- speculationCheck(
- BadType, JSValueRegs(op1GPR), node.child1(),
- m_jit.branchTestPtr(MacroAssembler::Zero, op1GPR, GPRInfo::tagTypeNumberRegister));
+ if (!isNumberPrediction(m_state.forNode(node.child1()).m_type)) {
+ speculationCheck(
+ BadType, JSValueRegs(op1GPR), node.child1(),
+ m_jit.branchTestPtr(MacroAssembler::Zero, op1GPR, GPRInfo::tagTypeNumberRegister));
+ }
m_jit.move(op1GPR, tempGPR);
unboxDouble(tempGPR, resultFPR);
@@ -1872,9 +1874,11 @@
JITCompiler::Jump isInteger = m_jit.branch32(
MacroAssembler::Equal, op1TagGPR, TrustedImm32(JSValue::Int32Tag));
- speculationCheck(
- BadType, JSValueRegs(op1TagGPR, op1PayloadGPR), node.child1(),
- m_jit.branch32(MacroAssembler::AboveOrEqual, op1TagGPR, TrustedImm32(JSValue::LowestTag)));
+ if (!isNumberPrediction(m_state.forNode(node.child1()).m_type)) {
+ speculationCheck(
+ BadType, JSValueRegs(op1TagGPR, op1PayloadGPR), node.child1(),
+ m_jit.branch32(MacroAssembler::AboveOrEqual, op1TagGPR, TrustedImm32(JSValue::LowestTag)));
+ }
unboxDouble(op1TagGPR, op1PayloadGPR, resultFPR, tempFPR);
JITCompiler::Jump done = m_jit.jump();