Commit 9151e2bc authored by Ng Zhi An's avatar Ng Zhi An Committed by V8 LUCI CQ

[wasm-relaxed-simd][arm64] Implement relaxed lane select

We move the mask to be the first input of the node in wasm-compiler.cc,
this matches the order for S128Select, which makes code-gen for
arm/arm64 simpler (directly lower to BSL with no more shuffle of
inputs). This requires tweaking of input indices in the instruction
selector for ia32/x64, but no change in codegen.

Bug: v8:12284
Change-Id: I1f6f1a9fe0869509be77f77b6f54a0c636a0f92d
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3272640
Commit-Queue: Zhi An Ng <zhin@chromium.org>
Reviewed-by: 's avatarDeepti Gandluri <gdeepti@chromium.org>
Cr-Commit-Position: refs/heads/main@{#77958}
parent 7187ae47
......@@ -4005,6 +4005,22 @@ void InstructionSelector::VisitS128Select(Node* node) {
g.UseRegister(node->InputAt(2)));
}
void InstructionSelector::VisitI8x16RelaxedLaneSelect(Node* node) {
VisitS128Select(node);
}
void InstructionSelector::VisitI16x8RelaxedLaneSelect(Node* node) {
VisitS128Select(node);
}
void InstructionSelector::VisitI32x4RelaxedLaneSelect(Node* node) {
VisitS128Select(node);
}
void InstructionSelector::VisitI64x2RelaxedLaneSelect(Node* node) {
VisitS128Select(node);
}
#define VISIT_SIMD_QFMOP(op) \
void InstructionSelector::Visit##op(Node* node) { \
Arm64OperandGenerator g(this); \
......
......@@ -3251,17 +3251,18 @@ namespace {
void VisitRelaxedLaneSelect(InstructionSelector* selector, Node* node) {
IA32OperandGenerator g(selector);
// pblendvb copies src2 when mask is set, opposite from Wasm semantics.
// node's inputs are: mask, lhs, rhs (determined in wasm-compiler.cc).
if (selector->IsSupported(AVX)) {
selector->Emit(kIA32Pblendvb, g.DefineAsRegister(node),
g.UseRegister(node->InputAt(2)),
g.UseRegister(node->InputAt(1)),
g.UseRegister(node->InputAt(0)),
g.UseRegister(node->InputAt(2)));
g.UseRegister(node->InputAt(0)));
} else {
// SSE4.1 pblendvb requires xmm0 to hold the mask as an implicit operand.
selector->Emit(kIA32Pblendvb, g.DefineSameAsFirst(node),
g.UseRegister(node->InputAt(2)),
g.UseRegister(node->InputAt(1)),
g.UseRegister(node->InputAt(0)),
g.UseFixed(node->InputAt(2), xmm0));
g.UseFixed(node->InputAt(0), xmm0));
}
}
} // namespace
......
......@@ -2794,7 +2794,7 @@ void InstructionSelector::VisitF32x4Qfms(Node* node) { UNIMPLEMENTED(); }
#endif // !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_IA32
#endif // !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_S390X && !V8_TARGET_ARCH_PPC64
#if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_IA32
#if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_IA32 && !V8_TARGET_ARCH_ARM64
void InstructionSelector::VisitI8x16RelaxedLaneSelect(Node* node) {
UNIMPLEMENTED();
}
......@@ -2807,6 +2807,9 @@ void InstructionSelector::VisitI32x4RelaxedLaneSelect(Node* node) {
void InstructionSelector::VisitI64x2RelaxedLaneSelect(Node* node) {
UNIMPLEMENTED();
}
#endif // !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_IA32 && !V8_TARGET_ARCH_ARM64
#if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_IA32
void InstructionSelector::VisitF32x4RelaxedMin(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF32x4RelaxedMax(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF64x2RelaxedMin(Node* node) { UNIMPLEMENTED(); }
......
......@@ -3726,16 +3726,17 @@ namespace {
void VisitRelaxedLaneSelect(InstructionSelector* selector, Node* node) {
X64OperandGenerator g(selector);
// pblendvb copies src2 when mask is set, opposite from Wasm semantics.
// node's inputs are: mask, lhs, rhs (determined in wasm-compiler.cc).
if (selector->IsSupported(AVX)) {
selector->Emit(
kX64Pblendvb, g.DefineAsRegister(node), g.UseRegister(node->InputAt(1)),
g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(2)));
kX64Pblendvb, g.DefineAsRegister(node), g.UseRegister(node->InputAt(2)),
g.UseRegister(node->InputAt(1)), g.UseRegister(node->InputAt(0)));
} else {
// SSE4.1 pblendvb requires xmm0 to hold the mask as an implicit operand.
selector->Emit(kX64Pblendvb, g.DefineSameAsFirst(node),
g.UseRegister(node->InputAt(2)),
g.UseRegister(node->InputAt(1)),
g.UseRegister(node->InputAt(0)),
g.UseFixed(node->InputAt(2), xmm0));
g.UseFixed(node->InputAt(0), xmm0));
}
}
} // namespace
......
......@@ -5147,17 +5147,18 @@ Node* WasmGraphBuilder::SimdOp(wasm::WasmOpcode opcode, Node* const* inputs) {
return graph()->NewNode(mcgraph()->machine()->I8x16Swizzle(true),
inputs[0], inputs[1]);
case wasm::kExprI8x16RelaxedLaneSelect:
// Relaxed lane select puts the mask as first input (same as S128Select).
return graph()->NewNode(mcgraph()->machine()->I8x16RelaxedLaneSelect(),
inputs[0], inputs[1], inputs[2]);
inputs[2], inputs[0], inputs[1]);
case wasm::kExprI16x8RelaxedLaneSelect:
return graph()->NewNode(mcgraph()->machine()->I16x8RelaxedLaneSelect(),
inputs[0], inputs[1], inputs[2]);
inputs[2], inputs[0], inputs[1]);
case wasm::kExprI32x4RelaxedLaneSelect:
return graph()->NewNode(mcgraph()->machine()->I32x4RelaxedLaneSelect(),
inputs[0], inputs[1], inputs[2]);
inputs[2], inputs[0], inputs[1]);
case wasm::kExprI64x2RelaxedLaneSelect:
return graph()->NewNode(mcgraph()->machine()->I64x2RelaxedLaneSelect(),
inputs[0], inputs[1], inputs[2]);
inputs[2], inputs[0], inputs[1]);
case wasm::kExprF32x4RelaxedMin:
return graph()->NewNode(mcgraph()->machine()->F32x4RelaxedMin(),
inputs[0], inputs[1]);
......
......@@ -234,7 +234,7 @@ WASM_RELAXED_SIMD_TEST(F32x4RecipSqrtApprox) {
false /* !exact */);
}
#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_IA32
#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM64
namespace {
// Helper to convert an array of T into an array of uint8_t to be used a v128
// constants.
......@@ -313,7 +313,9 @@ WASM_RELAXED_SIMD_TEST(I64x2RelaxedLaneSelect) {
RelaxedLaneSelectTest<uint64_t, kElems>(execution_tier, v1, v2, s, expected,
kExprI64x2RelaxedLaneSelect);
}
#endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM64
#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_IA32
WASM_RELAXED_SIMD_TEST(F32x4RelaxedMin) {
RunF32x4BinOpTest(execution_tier, kExprF32x4RelaxedMin, Minimum);
}
......
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