Closed
Bug 1497955
Opened 6 years ago
Closed 6 years ago
Fix wasm saturating conversions on x86 et al.
Categories
(Core :: JavaScript: WebAssembly, defect)
Core
JavaScript: WebAssembly
Tracking
()
RESOLVED
FIXED
mozilla64
Tracking | Status | |
---|---|---|
firefox64 | --- | fixed |
People
(Reporter: bbouvier, Assigned: bbouvier)
References
Details
Attachments
(2 files, 3 obsolete files)
3.21 KB,
patch
|
bbouvier
:
review+
|
Details | Diff | Splinter Review |
11.63 KB,
patch
|
sunfish
:
review+
|
Details | Diff | Splinter Review |
No description provided.
Assignee | ||
Comment 1•6 years ago
|
||
This code is a bit hard to read and reason about, so it's actually quite easy to make mistakes. The OOL paths have totally different behavior for the non-saturating case (just check the inputs and trap in this case) vs the saturating case (compute the actual result in the unsigned case, fix up the truncated result in the signed case). I've ran out of time for today, will investigate other platforms tomorrow.
Assignee | ||
Comment 2•6 years ago
|
||
Well, it was an incorrect comparison in the callout for ARM and ARM64; with this patch, all the test pass on all platforms, with Luke's patch applied.
Attachment #9015988 -
Attachment is obsolete: true
Attachment #9015988 -
Flags: review?(sunfish)
Attachment #9015992 -
Flags: review?(sunfish)
Comment 3•6 years ago
|
||
Comment on attachment 9015992 [details] [diff] [review] fix.patch Review of attachment 9015992 [details] [diff] [review]: ----------------------------------------------------------------- I thought this code had been tested on other platforms, but apparently I was wrong :-/. ::: js/src/jit/x86-shared/MacroAssembler-x86-shared.cpp @@ +982,5 @@ > // Negative overflow and NaN both are converted to 0, and the only other case > // is positive overflow which is converted to UINT64_MAX. > Label nonNegative; > loadConstantDouble(0.0, ScratchDoubleReg); > + branchDouble(Assembler::DoubleGreaterThan, input, ScratchDoubleReg, &nonNegative); Ah, this is quite subtle. branchDoubleNotInUInt64Range considers -0 an out-of-range case, even though in some sense it is in range. ::: js/src/jit/x86/MacroAssembler-x86.cpp @@ +1000,5 @@ > bind(&fail); > + if (isSaturating) { > + // The OOL path fixes up issues after we've done the conversion. > + truncateDoubleToInt64(Address(esp, 0), Address(esp, 0), temp); > + load64(Address(esp, 0), output); Are these two lines needed? The ool handler code appears to read from input and write to output, so we don't need to precompute output for it. @@ +1002,5 @@ > + // The OOL path fixes up issues after we've done the conversion. > + truncateDoubleToInt64(Address(esp, 0), Address(esp, 0), temp); > + load64(Address(esp, 0), output); > + freeStack(2 * sizeof(int32_t)); > + jump(oolEntry); And if not, these two lines can be factored out with the else body below. (And ditto for the other instances of this code below).
Comment 4•6 years ago
|
||
Thanks Benjamin!
Assignee | ||
Comment 5•6 years ago
|
||
(In reply to Dan Gohman [:sunfish] from comment #3) > Comment on attachment 9015992 [details] [diff] [review] > fix.patch > > Review of attachment 9015992 [details] [diff] [review]: > ----------------------------------------------------------------- > > I thought this code had been tested on other platforms, but apparently I was > wrong :-/. We had tests, but testing only the very edge cases and simple values (I decided to just keep the spec tests, and not duplicate them into our test suite): https://searchfox.org/mozilla-central/source/js/src/jit-test/tests/wasm/conversion.js#243-298 > ::: js/src/jit/x86/MacroAssembler-x86.cpp > @@ +1000,5 @@ > > bind(&fail); > > + if (isSaturating) { > > + // The OOL path fixes up issues after we've done the conversion. > > + truncateDoubleToInt64(Address(esp, 0), Address(esp, 0), temp); > > + load64(Address(esp, 0), output); > > Are these two lines needed? The ool handler code appears to read from input > and write to output, so we don't need to precompute output for it. Yes, they are needed, in a case of a positive overflow we adjust the output value: https://searchfox.org/mozilla-central/source/js/src/jit/x86-shared/MacroAssembler-x86-shared.cpp#1063 Maybe the OOL functions could be split, for clarity. Maybe the OOL path could even contain this second truncate.
Comment 6•6 years ago
|
||
Comment on attachment 9015992 [details] [diff] [review] fix.patch Review of attachment 9015992 [details] [diff] [review]: ----------------------------------------------------------------- ::: js/src/jit/x86-shared/MacroAssembler-x86-shared.cpp @@ +995,5 @@ > Label notNaN; > branchDouble(Assembler::DoubleOrdered, input, input, ¬NaN); > move64(Imm64(0), output); > jump(rejoin); > + Please make this same newline change in the *ToI32 versions of these functions.
Comment 7•6 years ago
|
||
Fwiw, here's a patch that simplifies the x86 *ToInt64 functions. This makes the x86 versions of these routines work essentially the same way their x64 counterparts do, which makes the codebase simpler, since they already share the OOL path. It also reduces the overall code size for both saturating and non-saturating cases, though it does make the non-saturating case do two load+conditional branches rather than one in the fast path.
Assignee | ||
Comment 8•6 years ago
|
||
Ah, much better, thanks! I've rejiggered the commits locally to apply yours first (since it was undoing changes I've added), and rebased mine onto yours. Consider r=me for your changes ;)
Attachment #9016103 -
Attachment is obsolete: true
Attachment #9016222 -
Flags: review+
Assignee | ||
Comment 9•6 years ago
|
||
Remaining changes on top of your commit.
Attachment #9015992 -
Attachment is obsolete: true
Attachment #9015992 -
Flags: review?(sunfish)
Attachment #9016223 -
Flags: review?(sunfish)
Comment 10•6 years ago
|
||
Comment on attachment 9016223 [details] [diff] [review] 2.bbouvier-fix.patch Review of attachment 9016223 [details] [diff] [review]: ----------------------------------------------------------------- Looks good! ::: js/src/jit/x86-shared/MacroAssembler-x86-shared.cpp @@ +979,5 @@ > > if (isSaturating) { > if (isUnsigned) { > // Negative overflow and NaN both are converted to 0, and the only other case > // is positive overflow which is converted to UINT64_MAX. Please line-wrap this comment to be consistent with the F32 version. @@ +982,5 @@ > // Negative overflow and NaN both are converted to 0, and the only other case > // is positive overflow which is converted to UINT64_MAX. > Label nonNegative; > loadConstantDouble(0.0, ScratchDoubleReg); > + branchDouble(Assembler::DoubleGreaterThan, input, ScratchDoubleReg, &nonNegative); One last nitpick: the name "nonNegative" for this label corresponded to testing `>= 0`. Now that we're using `> 0` we should call the label "positive" (here and in the F32 version).
Attachment #9016223 -
Flags: review?(sunfish) → review+
Comment 11•6 years ago
|
||
Pushed by bbouvier@mozilla.com: https://hg.mozilla.org/integration/mozilla-inbound/rev/d9951c225add Simplify code generation for wasm truncations to int64 on x86; r=bbouvier https://hg.mozilla.org/integration/mozilla-inbound/rev/ee4f12cc7136 Fix wasm saturating conversions codegen; r=sunfish
Comment 12•6 years ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/d9951c225add https://hg.mozilla.org/mozilla-central/rev/ee4f12cc7136
Status: ASSIGNED → RESOLVED
Closed: 6 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla64
You need to log in
before you can comment on or make changes to this bug.
Description
•