Commit 51a76689 authored by Ng Zhi An's avatar Ng Zhi An Committed by Commit Bot

[wasm-simd] Scalar lowering for load splat (s8x16, s16x8, s32x4)

We lower each op into num_lanes loads, and connecting up the effects in
a chain.

s64x2 is not implemented since we lowering for 64x2 generally doesn't
work anyway.

Load extends are a bit more complicated, so we'll do that in a separate
change.

Bug: v8:9886
Change-Id: I80096827bf8e8e0db1ef0ad1b76759ed1797ca5e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2031893
Commit-Queue: Zhi An Ng <zhin@chromium.org>
Reviewed-by: 's avatarDeepti Gandluri <gdeepti@chromium.org>
Cr-Commit-Position: refs/heads/master@{#66183}
parent e5e4ea96
......@@ -6,6 +6,7 @@
#include "src/compiler/diamond.h"
#include "src/compiler/linkage.h"
#include "src/compiler/machine-operator.h"
#include "src/compiler/node-matchers.h"
#include "src/compiler/node-properties.h"
#include "src/compiler/node.h"
......@@ -270,6 +271,23 @@ void SimdScalarLowering::SetLoweredType(Node* node, Node* output) {
replacements_[node->id()].type = SimdType::kInt8x16;
break;
}
case IrOpcode::kLoadTransform: {
LoadTransformParameters params = LoadTransformParametersOf(node->op());
switch (params.transformation) {
case LoadTransformation::kS8x16LoadSplat:
replacements_[node->id()].type = SimdType::kInt8x16;
break;
case LoadTransformation::kS16x8LoadSplat:
replacements_[node->id()].type = SimdType::kInt16x8;
break;
case LoadTransformation::kS32x4LoadSplat:
replacements_[node->id()].type = SimdType::kInt32x4;
break;
default:
UNIMPLEMENTED();
}
break;
}
default: {
switch (output->opcode()) {
case IrOpcode::kF32x4SConvertI32x4:
......@@ -428,6 +446,52 @@ void SimdScalarLowering::LowerLoadOp(Node* node, SimdType type) {
}
}
void SimdScalarLowering::LowerLoadTransformOp(Node* node, SimdType type) {
LoadTransformParameters params = LoadTransformParametersOf(node->op());
switch (params.transformation) {
// Lowering for s64x2 is not implemented since lowering for 64x2 operations
// doesn't work properly yet.
case LoadTransformation::kS8x16LoadSplat:
case LoadTransformation::kS16x8LoadSplat:
case LoadTransformation::kS32x4LoadSplat:
break;
default:
UNIMPLEMENTED();
}
const Operator* load_op;
switch (params.kind) {
case LoadKind::kNormal:
load_op = machine()->Load(MachineTypeFrom(type));
break;
case LoadKind::kUnaligned:
load_op = machine()->UnalignedLoad(MachineTypeFrom(type));
break;
case LoadKind::kProtected:
load_op = machine()->ProtectedLoad(MachineTypeFrom(type));
break;
default:
UNREACHABLE();
}
Node* base = node->InputAt(0);
Node* index = node->InputAt(1);
int num_lanes = NumLanes(type);
Node** rep_nodes = zone()->NewArray<Node*>(num_lanes);
rep_nodes[0] = node;
NodeProperties::ChangeOp(rep_nodes[0], load_op);
Node* effect_input = node->InputAt(2);
Node* control_input = node->InputAt(3);
for (int i = num_lanes - 1; i > 0; --i) {
rep_nodes[i] =
graph()->NewNode(load_op, base, index, effect_input, control_input);
effect_input = rep_nodes[i];
}
rep_nodes[0]->ReplaceInput(2, rep_nodes[1]);
ReplaceNode(node, rep_nodes, num_lanes);
}
void SimdScalarLowering::LowerStoreOp(Node* node) {
// For store operation, use replacement type of its input instead of the
// one of its effected node.
......@@ -975,6 +1039,10 @@ void SimdScalarLowering::LowerNode(Node* node) {
LowerLoadOp(node, rep_type);
break;
}
case IrOpcode::kLoadTransform: {
LowerLoadTransformOp(node, rep_type);
break;
}
case IrOpcode::kStore:
case IrOpcode::kUnalignedStore:
case IrOpcode::kProtectedStore: {
......
......@@ -85,6 +85,7 @@ class SimdScalarLowering {
void SetLoweredType(Node* node, Node* output);
void GetIndexNodes(Node* index, Node** new_indices, SimdType type);
void LowerLoadOp(Node* node, SimdType type);
void LowerLoadTransformOp(Node* node, SimdType type);
void LowerStoreOp(Node* node);
void LowerBinaryOp(Node* node, SimdType input_rep_type, const Operator* op,
bool not_horizontal = true);
......
......@@ -3328,15 +3328,15 @@ void RunLoadSplatTest(ExecutionTier execution_tier, LowerSimd lower_simd,
}
}
WASM_SIMD_TEST_NO_LOWERING(S8x16LoadSplat) {
WASM_SIMD_TEST(S8x16LoadSplat) {
RunLoadSplatTest<int8_t>(execution_tier, lower_simd, kExprS8x16LoadSplat);
}
WASM_SIMD_TEST_NO_LOWERING(S16x8LoadSplat) {
WASM_SIMD_TEST(S16x8LoadSplat) {
RunLoadSplatTest<int16_t>(execution_tier, lower_simd, kExprS16x8LoadSplat);
}
WASM_SIMD_TEST_NO_LOWERING(S32x4LoadSplat) {
WASM_SIMD_TEST(S32x4LoadSplat) {
RunLoadSplatTest<int32_t>(execution_tier, lower_simd, kExprS32x4LoadSplat);
}
......
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