Closed
Bug 1331346
Opened 9 years ago
Closed 5 years ago
Add support for unsigned division and comparison
Categories
(Core :: JavaScript Engine: JIT, defect, P3)
Core
JavaScript Engine: JIT
Tracking
()
RESOLVED
WONTFIX
People
(Reporter: sandervv, Assigned: sandervv)
References
(Blocks 1 open bug)
Details
(Keywords: perf)
Attachments
(1 file, 2 obsolete files)
|
10.29 KB,
patch
|
sunfish
:
review+
nbp
:
review-
|
Details | Diff | Splinter Review |
Use unsigned division and unsigned comparison when the operands are uint32.
| Assignee | ||
Updated•9 years ago
|
Assignee: nobody → sandervv
| Assignee | ||
Comment 1•9 years ago
|
||
Comment on attachment 8827105 [details] [diff] [review]
support-unsigned-division-and-comparison.patch
Since this patch touches range analysis, I'll ask for two reviews.
Attachment #8827105 -
Flags: review?(nicolas.b.pierron)
Attachment #8827105 -
Flags: review?(jdemooij)
Comment 2•9 years ago
|
||
Comment on attachment 8827105 [details] [diff] [review]
support-unsigned-division-and-comparison.patch
Review of attachment 8827105 [details] [diff] [review]:
-----------------------------------------------------------------
::: js/src/jit/MIR.cpp
@@ +2841,5 @@
> + hasOnlyUnsignedUses = false;
> + break;
> + }
> +
> + if (hasOnlyUnsignedUses)
nit: consider removed uses as not having only unsigned uses. This is also true for observable slots.
Updated•9 years ago
|
Comment 3•9 years ago
|
||
Comment on attachment 8827105 [details] [diff] [review]
support-unsigned-division-and-comparison.patch
Review of attachment 8827105 [details] [diff] [review]:
-----------------------------------------------------------------
Add tests cases, and fix the following comments.
::: js/src/jit/RangeAnalysis.cpp
@@ +1683,5 @@
> +
> + // Unsigned division by a non-zero rhs will return a uint32 value.
> + // If the RHS is zero, a bailout will happen and the result becomes
> + // a double value.
> + unsigned_ = true;
This should be moved to MDiv::collectRangeInfoPreTrunc.
@@ +1684,5 @@
> + // Unsigned division by a non-zero rhs will return a uint32 value.
> + // If the RHS is zero, a bailout will happen and the result becomes
> + // a double value.
> + unsigned_ = true;
> + setRange(Range::NewUInt32Range(alloc, 0, UINT32_MAX));
Not having an early return here means that if the range of lhs nor rhs are wrapped around, then we will attempt to call setRange twice, which will assert.
Add a test case to catch this issue, and add an early return to fix it.
Attachment #8827105 -
Flags: review?(nicolas.b.pierron)
Attachment #8827105 -
Flags: review-
Attachment #8827105 -
Flags: feedback+
Updated•9 years ago
|
Attachment #8827105 -
Flags: review?(jdemooij)
| Assignee | ||
Comment 4•9 years ago
|
||
I've moved |unsigned_ = true| to |MDiv::collectRangeInfoPreTrunc|.
I've added the early return. Without the early return and with |MOZ_ASSERT(!range())| before the following setRange() calls in |MDiv::computeRange()|, I've verified that the test |jit-test/tests/asm.js/testExpressions.js| covers the path where two setRange calls are performed. With the early return, this test does not fail anymore. The test did not fail before because there was no assertion that verified that setRange() should only be called once.
I think that adding |MOZ_ASSERT(!range())| to |setRange()| is useful to prevent allocating more memory than necessary, but it is better to do it in a separate bug because it is unrelated to udiv and ucmp. Therefore, I've removed the |MOZ_ASSERT(!range())| lines from this patch, to avoid asserting this twice.
Attachment #8827105 -
Attachment is obsolete: true
Attachment #8834455 -
Flags: review?(nicolas.b.pierron)
| Assignee | ||
Updated•9 years ago
|
Attachment #8834455 -
Flags: review?(jdemooij)
Comment 5•9 years ago
|
||
Comment on attachment 8834455 [details] [diff] [review]
support-unsigned-division-and-comparison.patch
Review of attachment 8834455 [details] [diff] [review]:
-----------------------------------------------------------------
sunfish and nbp are probably better reviewers for this patch.
(I'm also wondering if at some point it would be better to add MIRType::Uint32 instead of working around it.)
Attachment #8834455 -
Flags: review?(jdemooij) → review?(sunfish)
Comment 6•9 years ago
|
||
Comment on attachment 8834455 [details] [diff] [review]
support-unsigned-division-and-comparison.patch
Review of attachment 8834455 [details] [diff] [review]:
-----------------------------------------------------------------
I agree that adding a MIRType::Uint32 is an appealing direction to head in, as the current system with IsUint32Type and friends is difficult to reason about.
::: js/src/jit/IonAnalysis.cpp
@@ +573,5 @@
> if (def->type() != MIRType::Int32)
> return false;
>
> + if (def->isConstant())
> + return def->toConstant()->toInt32() >= 0;
Changing IsUint32Type is a little tricky, because it's also used in subtle ways in MTruncateToInt32::foldsTo and MToInt32::foldsTo. It looks like this change would mean that MTruncateToInt32::foldsTo wouldn't fold when the operand is a non-negative constant, which would seem to be unintended. Is that true?
::: js/src/jit/MIR.cpp
@@ +1779,5 @@
> + case Compare_DoubleMaybeCoerceRHS:
> + out.printf(" [double]");
> + break;
> + case Compare_Float32:
> + out.printf(" [float]");
For consistency with SM's naming and avoidance of ambiguity, this should say "float32".
Attachment #8834455 -
Flags: review?(sunfish)
| Assignee | ||
Comment 7•9 years ago
|
||
Removed changes to IsUint32Type(), and used 'float32' instead.
Attachment #8834455 -
Attachment is obsolete: true
Attachment #8834455 -
Flags: review?(nicolas.b.pierron)
Attachment #8844156 -
Flags: review?(sunfish)
Attachment #8844156 -
Flags: review?(nicolas.b.pierron)
Comment 8•9 years ago
|
||
FWIW, there's a discussion going on over in bug 1343007 that is somewhat related to this. The conclusion there is *probably* going to be that MMod, which now has the single 'isUnsigned' flag that has slightly unclear semantics, will acquire two new flags called something like 'alwaysSigned' and 'alwaysUnsigned', which will be required to support WebAssembly properly without introducing new nodes for Div and Mod just for that purpose. If MDiv acquires the same optimization as MMod around sniffing unsignedness of the operand, it will need a similar fix.
Comment 9•9 years ago
|
||
Comment on attachment 8844156 [details] [diff] [review]
support-unsigned-division-and-comparison.patch
Review of attachment 8844156 [details] [diff] [review]:
-----------------------------------------------------------------
Looks good to me.
Attachment #8844156 -
Flags: review?(sunfish) → review+
Comment 10•5 years ago
|
||
Comment on attachment 8844156 [details] [diff] [review]
support-unsigned-division-and-comparison.patch
Review of attachment 8844156 [details] [diff] [review]:
-----------------------------------------------------------------
Sorry for the late reply.
UInt types provided by range analysis is ok-ish but the lack of consistency in the rest of the engine already caused us issues in the past.
For safety and performance reasons, I prefer to decline this work unless there is a good performance win in some actual website. In which case I should probably re-evaluate this issue.
::: js/src/jit/RangeAnalysis.cpp
@@ +1690,5 @@
> +
> + // Unsigned division by a non-zero rhs will return a uint32 value.
> + // If the RHS is zero, a bailout will happen and the result becomes
> + // a double value.
> + setRange(Range::NewUInt32Range(alloc, 0, UINT32_MAX));
`3/2` is composed of 2 unsigned integers, but would not result in an unsigned result.
It sounds to me that this a greedy optimization which is more likely to backfire by addings tons of bailout (at the time), and cause a recompilation without much guarantees that this would not be the case.
Attachment #8844156 -
Flags: review?(nicolas.b.pierron) → review-
Updated•5 years ago
|
Status: NEW → RESOLVED
Closed: 5 years ago
Resolution: --- → WONTFIX
You need to log in
before you can comment on or make changes to this bug.
Description
•