Commit 7603a303 authored by Ng Zhi An's avatar Ng Zhi An Committed by Commit Bot

[wasm-simd][scalar-lowering] Bitmask

Scalar lowering for i8x16, i16x8, i32x4 bitmask.

Depending on which lane we are lowering, we can either shift the MSB
into the correct final bit position, then do a big OR of all the nodes.

Bug: v8:10308
Change-Id: Iddf6c077b5a8658a487cef59f2e3bbae3c8bd98d
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2219327Reviewed-by: 's avatarDeepti Gandluri <gdeepti@chromium.org>
Commit-Queue: Zhi An Ng <zhin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68491}
parent bf9d6afb
......@@ -147,7 +147,8 @@ void SimdScalarLowering::LowerGraph() {
V(V16x8AnyTrue) \
V(V16x8AllTrue) \
V(V8x16AnyTrue) \
V(V8x16AllTrue)
V(V8x16AllTrue) \
V(I32x4BitMask)
#define FOREACH_FLOAT64X2_OPCODE(V) V(F64x2Splat)
......@@ -212,7 +213,8 @@ void SimdScalarLowering::LowerGraph() {
V(I16x8LtU) \
V(I16x8LeU) \
V(I16x8RoundingAverageU) \
V(I16x8Abs)
V(I16x8Abs) \
V(I16x8BitMask)
#define FOREACH_INT8X16_OPCODE(V) \
V(I8x16Splat) \
......@@ -245,7 +247,8 @@ void SimdScalarLowering::LowerGraph() {
V(S8x16Swizzle) \
V(S8x16Shuffle) \
V(I8x16RoundingAverageU) \
V(I8x16Abs)
V(I8x16Abs) \
V(I8x16BitMask)
MachineType SimdScalarLowering::MachineTypeFrom(SimdType simdType) {
switch (simdType) {
......@@ -1025,6 +1028,44 @@ void SimdScalarLowering::LowerNotEqual(Node* node, SimdType input_rep_type,
ReplaceNode(node, rep_node, num_lanes);
}
void SimdScalarLowering::LowerBitMaskOp(Node* node, SimdType rep_type,
int msb_index) {
Node** reps = GetReplacementsWithType(node->InputAt(0), rep_type);
int num_lanes = NumLanes(rep_type);
Node** rep_node = zone()->NewArray<Node*>(1);
Node* result = mcgraph_->Int32Constant(0);
uint32_t mask = 1 << msb_index;
for (int i = 0; i < num_lanes; ++i) {
// Lane i should end up at bit i in the final result.
// +-----------------------------------------------------------------+
// | | msb_index | (i < msb_index) | (i > msb_index) |
// +-------+-----------+----------------------+----------------------+
// | i8x16 | 7 | msb >> (msb_index-i) | msb << (i-msb_index) |
// | i16x8 | 15 | msb >> (msb_index-i) | n/a |
// | i32x4 | 31 | msb >> (msb_index-i) | n/a |
// +-------+-----------+----------------------+----------------------+
Node* msb = Mask(reps[i], mask);
if (i < msb_index) {
int shift = msb_index - i;
Node* shifted = graph()->NewNode(machine()->Word32Shr(), msb,
mcgraph_->Int32Constant(shift));
result = graph()->NewNode(machine()->Word32Or(), shifted, result);
} else if (i > msb_index) {
int shift = i - msb_index;
Node* shifted = graph()->NewNode(machine()->Word32Shl(), msb,
mcgraph_->Int32Constant(shift));
result = graph()->NewNode(machine()->Word32Or(), shifted, result);
} else {
result = graph()->NewNode(machine()->Word32Or(), msb, result);
}
}
rep_node[0] = result;
ReplaceNode(node, rep_node, 1);
}
void SimdScalarLowering::LowerNode(Node* node) {
SimdType rep_type = ReplacementType(node);
int num_lanes = NumLanes(rep_type);
......@@ -1675,6 +1716,18 @@ void SimdScalarLowering::LowerNode(Node* node) {
ReplaceNode(node, rep_node, num_lanes);
break;
}
case IrOpcode::kI8x16BitMask: {
LowerBitMaskOp(node, rep_type, 7);
break;
}
case IrOpcode::kI16x8BitMask: {
LowerBitMaskOp(node, rep_type, 15);
break;
}
case IrOpcode::kI32x4BitMask: {
LowerBitMaskOp(node, rep_type, 31);
break;
}
case IrOpcode::kI8x16RoundingAverageU:
case IrOpcode::kI16x8RoundingAverageU: {
DCHECK_EQ(2, node->InputCount());
......@@ -1707,7 +1760,7 @@ bool SimdScalarLowering::DefaultLowering(Node* node) {
something_changed = true;
node->ReplaceInput(i, GetReplacements(input)[0]);
}
if (HasReplacement(1, input)) {
if (ReplacementCount(input) > 1 && HasReplacement(1, input)) {
something_changed = true;
for (int j = 1; j < ReplacementCount(input); ++j) {
node->InsertInput(zone(), i + j, GetReplacements(input)[j]);
......
......@@ -110,6 +110,7 @@ class SimdScalarLowering {
Node* BuildF64Trunc(Node* input);
void LowerNotEqual(Node* node, SimdType input_rep_type, const Operator* op);
MachineType MachineTypeFrom(SimdType simdType);
void LowerBitMaskOp(Node* node, SimdType rep_type, int msb_index);
MachineGraph* const mcgraph_;
NodeMarker<State> state_;
......
......@@ -1681,7 +1681,7 @@ WASM_SIMD_TEST(I16x8ReplaceLane) {
#if V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_IA32 || \
V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
WASM_SIMD_TEST_NO_LOWERING(I8x16BitMask) {
WASM_SIMD_TEST(I8x16BitMask) {
FLAG_SCOPE(wasm_simd_post_mvp);
WasmRunner<int32_t, int32_t> r(execution_tier, lower_simd);
byte value1 = r.AllocateLocal(kWasmS128);
......@@ -1701,7 +1701,7 @@ WASM_SIMD_TEST_NO_LOWERING(I8x16BitMask) {
}
}
WASM_SIMD_TEST_NO_LOWERING(I16x8BitMask) {
WASM_SIMD_TEST(I16x8BitMask) {
FLAG_SCOPE(wasm_simd_post_mvp);
WasmRunner<int32_t, int32_t> r(execution_tier, lower_simd);
byte value1 = r.AllocateLocal(kWasmS128);
......@@ -1721,7 +1721,7 @@ WASM_SIMD_TEST_NO_LOWERING(I16x8BitMask) {
}
}
WASM_SIMD_TEST_NO_LOWERING(I32x4BitMask) {
WASM_SIMD_TEST(I32x4BitMask) {
FLAG_SCOPE(wasm_simd_post_mvp);
WasmRunner<int32_t, int32_t> r(execution_tier, lower_simd);
byte value1 = r.AllocateLocal(kWasmS128);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment