[INFER] Fix jsop_neg() when operand is integer and result is double, bug 618863.
authorBrian Hackett <bhackett1024@gmail.com>
Mon, 20 Dec 2010 10:56:50 -0800
changeset 74675 f86f3107b697e3af8790df69553957f01bc0135b
parent 74674 3d1614793bd2cf058584ce9b45ea5e5800d30b39
child 74676 5b1c3bece05b9742d4ede73373d3c394903abd53
push id2
push userbsmedberg@mozilla.com
push dateFri, 19 Aug 2011 14:38:13 +0000
bugs618863
milestone2.0b8pre
[INFER] Fix jsop_neg() when operand is integer and result is double, bug 618863.
js/src/jit-test/tests/jaeger/bug618863.js
js/src/methodjit/FastArithmetic.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/jaeger/bug618863.js
@@ -0,0 +1,23 @@
+function f() {
+  for(var i=0; i<3; i++) {
+    var x = -i / 100;
+    assertEq(x * -100, i);
+  }
+}
+f();
+
+function g() {
+  for (var i = 0; i < 2; i++) {
+    var a = i ? true : false;
+    var x = -a / 100;
+    assertEq(x * -100, i);
+  }
+}
+g();
+
+function h() {
+  for (var i = 0; i < 20; i++)
+    var x = (0x7ffffff4 + i) / 100;
+  assertEq(x, 21474836.55);
+}
+h();
--- a/js/src/methodjit/FastArithmetic.cpp
+++ b/js/src/methodjit/FastArithmetic.cpp
@@ -761,27 +761,31 @@ mjit::Compiler::jsop_binary_full(FrameEn
 
     stubcc.rejoin(Changes(1));
 }
 
 void
 mjit::Compiler::jsop_neg()
 {
     FrameEntry *fe = frame.peek(-1);
+    JSValueType type = knownPushedType(0);
 
     if (fe->isTypeKnown() && fe->getKnownType() > JSVAL_UPPER_INCL_TYPE_OF_NUMBER_SET) {
         prepareStubCall(Uses(1));
         INLINE_STUBCALL(stubs::Neg);
         frame.pop();
-        frame.pushSynced(knownPushedType(0));
+        frame.pushSynced(type);
         return;
     }
 
     JS_ASSERT(!fe->isConstant());
 
+    if (type == JSVAL_TYPE_DOUBLE)
+        frame.ensureDouble(fe);
+
     if (fe->isType(JSVAL_TYPE_DOUBLE)) {
         FPRegisterID fpreg = frame.tempFPRegForData(fe);
         FPRegisterID res = frame.allocFPReg();
         masm.moveDouble(fpreg, res);
         masm.negateDouble(res);
 
         frame.pop();
         frame.pushDouble(res);
@@ -847,17 +851,17 @@ mjit::Compiler::jsop_neg()
     frame.freeReg(reg);
     if (feTypeReg.isSet())
         frame.unpinReg(feTypeReg.reg());
 
     stubcc.leave();
     OOL_STUBCALL(stubs::Neg);
 
     frame.pop();
-    frame.pushSynced(knownPushedType(0));
+    frame.pushSynced(type);
 
     /* Link jumps. */
     if (jmpNotDbl.isSet())
         stubcc.linkExitDirect(jmpNotDbl.getJump(), lblIntPath);
 
     if (jmpNotInt.isSet())
         jmpNotInt.getJump().linkTo(feSyncTarget, &stubcc.masm);
     if (jmpIntZero.isSet())