Closed Bug 1246800 Opened 9 years ago Closed 9 years ago

SIMD: Implement and test masked shift-by-scalar amounts

Categories

(Core :: JavaScript Engine, defect)

defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla47
Tracking Status
firefox47 --- fixed

People

(Reporter: jolesen, Assigned: jolesen)

Details

Attachments

(1 file, 1 obsolete file)

The SIMD.js functions for shifting a vector by a scalar are now masking the scalar to the size if the vector lanes: https://github.com/tc39/ecmascript_simd/pull/320 Make sure that we implement these semantics, and that we have tests.
Attached patch Masked shift-by-scalar amounts. (obsolete) — Splinter Review
Modulo-reduce SIMD shift amounts by the size of the lane instead of saturating shift amounts larger than the number of bits in a lane.
Attachment #8721047 - Flags: review?(sunfish)
Assignee: nobody → jolesen
Comment on attachment 8721047 [details] [diff] [review] Masked shift-by-scalar amounts. Review of attachment 8721047 [details] [diff] [review]: ----------------------------------------------------------------- Looks good! ::: js/src/builtin/SIMD.cpp @@ +718,5 @@ > template<typename T> > struct ShiftLeft { > static T apply(T v, int32_t bits) { > + uint32_t maskedBits = uint32_t(bits) % (sizeof(T) * 8); > + return v << maskedBits; nit: extra space after `return`. Also, C++'s left shift on signed types has a bunch of undefined behavior, so this should cast v to MakeUnsigned<T>::Type before doing the shift. @@ +733,5 @@ > template<typename T> > struct ShiftRightLogical { > static T apply(T v, int32_t bits) { > + uint32_t maskedBits = uint32_t(bits) % (sizeof(T) * 8); > + return uint32_t(v) >> maskedBits; For consistency, and correctness if this code ever gets used for 64-bit shifts, it'd be good to use MakeUnsigned<T>::Type instead of uint32_t for this shift too.
Attachment #8721047 - Flags: review?(sunfish) → review+
Ugh, there is no ScratchRegisterScope on 32-bit x86. I'll need to insert that masking `and` instruction before register allocation. I guess LIRGenerator::visitSimdShift() can do it.
(In reply to Jakob Stoklund Olesen [:jolesen] from comment #4) > Ugh, there is no ScratchRegisterScope on 32-bit x86. I'll need to insert > that masking `and` instruction before register allocation. I guess > LIRGenerator::visitSimdShift() can do it. Just curious, we can't add a temp register to LSimdShift (and LDefinition::BogusTemp() when we know we don't need it)?
Dan, would you mind giving this one a second look? I used MakeUnsigned<T> as you suggested to avoid undefined behavior in the left-shifting function. I added a temp register to LSimdShift as Jan suggested. It seems to work fine, but please double-check. Everything else is unchanged.
Attachment #8721366 - Flags: review?(sunfish)
Attachment #8721047 - Attachment is obsolete: true
Attachment #8721366 - Flags: review?(sunfish) → review+
Status: NEW → RESOLVED
Closed: 9 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla47
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: