[wasm-simd][scalar-lowering] Fix sign extend/masks of lanes

For replacing lanes (i8x16 and i16x8) the replacement value is stored in
a word32. Simply storing it will cause us to have the wrong value, we
need to mask (for overflow) and extend appropriately.

Same for extracting, the values are stored in sign-extended form,
unsigned extracts should zero the top bits.

Bug: v8:10507
Change-Id: If5ed79f5b6bdb64f900a54b9e148b2d96a74f312
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2436612
Reviewed-by: Bill Budge <bbudge@chromium.org>
Commit-Queue: Zhi An Ng <zhin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70210}
This commit is contained in:
Ng Zhi An 2020-09-29 11:18:32 -07:00 committed by Commit Bot
parent 582de025d8
commit d8a36591ed
2 changed files with 21 additions and 5 deletions

View File

@ -1215,9 +1215,8 @@ void SimdScalarLowering::LowerNode(Node* node) {
case SimdType::kInt8x16: {
for (int i = 0; i < num_lanes; ++i) {
Address data_address = reinterpret_cast<Address>(params.data() + i);
rep_node[i] = mcgraph_->Int32Constant(
static_cast<int32_t>(static_cast<int8_t>(
base::ReadLittleEndianValue<int8_t>(data_address))));
rep_node[i] = mcgraph_->Int32Constant(static_cast<int32_t>(
base::ReadLittleEndianValue<int8_t>(data_address)));
}
break;
}
@ -1864,6 +1863,14 @@ void SimdScalarLowering::LowerNode(Node* node) {
int32_t lane = OpParameter<int32_t>(node->op());
Node** rep_node = zone()->NewArray<Node*>(num_lanes);
rep_node[0] = GetReplacementsWithType(node->InputAt(0), rep_type)[lane];
// If unsigned, mask the top bits.
if (node->opcode() == IrOpcode::kI16x8ExtractLaneU) {
rep_node[0] = Mask(rep_node[0], kMask16);
} else if (node->opcode() == IrOpcode::kI8x16ExtractLaneU) {
rep_node[0] = Mask(rep_node[0], kMask8);
}
for (int i = 1; i < num_lanes; ++i) {
rep_node[i] = nullptr;
}
@ -1890,6 +1897,17 @@ void SimdScalarLowering::LowerNode(Node* node) {
} else {
rep_node[lane] = repNode;
}
// The replacement nodes for these opcodes are in Word32, and we always
// store nodes in sign extended form (and mask to account for overflows.)
if (node->opcode() == IrOpcode::kI16x8ReplaceLane) {
rep_node[lane] = graph()->NewNode(machine()->SignExtendWord16ToInt32(),
Mask(rep_node[lane], kMask16));
} else if (node->opcode() == IrOpcode::kI8x16ReplaceLane) {
rep_node[lane] = graph()->NewNode(machine()->SignExtendWord8ToInt32(),
Mask(rep_node[lane], kMask8));
}
ReplaceNode(node, rep_node, num_lanes);
break;
}

View File

@ -41,8 +41,6 @@
# Scalar lowering is incomplete, we skip these and selectively enable as
# we finish the implementation, see v8:10507.
'proposals/simd/simd_conversions' : [PASS, FAIL],
'proposals/simd/simd_lane' : [PASS, FAIL],
}], # ALWAYS
['arch == arm and not simulator_run', {