Closed Bug 584770 Opened 14 years ago Closed 14 years ago

JM: binary operators should check for negative zero

Categories

(Core :: JavaScript Engine, defect)

defect
Not set
normal

Tracking

()

RESOLVED FIXED
Tracking Status
blocking2.0 --- beta5+

People

(Reporter: jandem, Assigned: jandem)

References

Details

(Keywords: regression)

Attachments

(1 file, 2 obsolete files)

User-Agent:       Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.5 (KHTML, like Gecko) Chrome/6.0.486.0 Safari/534.5
Build Identifier: 

JM tip fails the following test case:
----------
function mul(x, y) { return x * y; }

var a = mul(-5, 0);
var b = Infinity / a;
print(b < 0 ? 'PASS' : 'FAIL');
----------
This may also apply to other binary operators.

Reproducible: Always
I thought we had trace-tests for this too...
Status: UNCONFIRMED → NEW
blocking2.0: --- → ?
Ever confirmed: true
Keywords: regression
(In reply to comment #1)
> I thought we had trace-tests for this too...

It works correctly when the mul is constant folded:
--------
function f() { 
  var a = -5;
  var b = 0;
  print(Infinity / (a * b));
}
--------
Maybe that's happening to the trace-tests...
blocking2.0: ? → beta5+
Taking this, will attach a patch tomorrow.
Status: NEW → ASSIGNED
Assignee: general → jandemooij
Attached patch patch v1 (WIP) (obsolete) (deleted) — Splinter Review
This patch adds a number of tests and passes all of them, except the last one. I haven't found the reason yet but I think the FrameState is messed up somehow.

This line:
  masm.loadPayload(frame.addressOf(regs.resultHasRhs ? rhs : lhs), regs.result);

is supposed to load the original operand from memory. Looking at the asm reveals that it loads another value from the stack, which is weird.
The problem is defninitely with this line: 
  masm.loadPayload(frame.addressOf(regs.resultHasRhs ? rhs : lhs), regs.result);

I think that in my testcase the operands are arguments and only stored in registers. Reloading them like this won't work.

Some help here would be appreciated.
Attached patch patch v2 (WIP) (obsolete) (deleted) — Splinter Review
This fixes the constant-zero operand (x * 0) case, with tests.

The last test still fails, otherwise this is close.
Attachment #465978 - Attachment is obsolete: true
Attached patch Patch v3 (deleted) — Splinter Review
This moves more negative-zero code to stubcc, to make the inline path more concise and readable, may also help branch prediction a tiny tiny bit. 

For the constant-0 operand case we could do a xor and skip the mul like in patch v2. This is rare though and complicates the rest of the code (have to check if overflow jump is set, etc.), so this patch just does an imul to keep it simple.

Passes trace-tests and attached tests. Let's hope SS/V8 are not too much affected.
Attachment #466235 - Attachment is obsolete: true
Attachment #466264 - Flags: review?(dvander)
Comment on attachment 466264 [details] [diff] [review]
Patch v3

Looks great, thanks for catching & taking this, Jan. Also thanks for the tests, kind of shocking that we weren't failing anything already.
Attachment #466264 - Flags: review?(dvander) → review+
http://hg.mozilla.org/projects/jaegermonkey/rev/fe75f7100230
Status: ASSIGNED → RESOLVED
Closed: 14 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: