Commit 238489c6 authored by Ng Zhi An's avatar Ng Zhi An Committed by Commit Bot

Implement F64x2Div for x64

This is a reland of
https://chromium-review.googlesource.com/c/v8/v8/+/1749712 with a fix in
test-run-wasm-simd.cc to use base::Divide to work around C++ undefined
behavior when the denominator is 0.

Bug: v8:8460
Change-Id: Ia0a4ff621cccc6d9b7528717bf3fa7c79e42ba1a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1745819
Commit-Queue: Zhi An Ng <zhin@chromium.org>
Reviewed-by: 's avatarDeepti Gandluri <gdeepti@chromium.org>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63198}
parent f4583702
......@@ -1334,7 +1334,7 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
AVX_S_3(vadd, 0x58)
AVX_S_3(vsub, 0x5c)
AVX_S_3(vmul, 0x59)
AVX_SP_3(vdiv, 0x5e)
AVX_S_3(vdiv, 0x5e)
AVX_S_3(vmin, 0x5d)
AVX_S_3(vmax, 0x5f)
AVX_P_3(vand, 0x54)
......
......@@ -13,6 +13,7 @@
V(subpd, 66, 0F, 5C) \
V(minpd, 66, 0F, 5D) \
V(maxpd, 66, 0F, 5F) \
V(divpd, 66, 0F, 5E) \
V(punpcklbw, 66, 0F, 60) \
V(punpcklwd, 66, 0F, 61) \
V(punpckldq, 66, 0F, 62) \
......
......@@ -1859,6 +1859,8 @@ void InstructionSelector::VisitNode(Node* node) {
return MarkAsSimd128(node), VisitF64x2Sub(node);
case IrOpcode::kF64x2Mul:
return MarkAsSimd128(node), VisitF64x2Mul(node);
case IrOpcode::kF64x2Div:
return MarkAsSimd128(node), VisitF64x2Div(node);
case IrOpcode::kF64x2Min:
return MarkAsSimd128(node), VisitF64x2Min(node);
case IrOpcode::kF64x2Max:
......@@ -2606,6 +2608,7 @@ void InstructionSelector::VisitF64x2Neg(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF64x2Add(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF64x2Sub(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF64x2Mul(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF64x2Div(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF64x2Min(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF64x2Max(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF64x2Eq(Node* node) { UNIMPLEMENTED(); }
......
......@@ -2310,6 +2310,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
ASSEMBLE_SSE_BINOP(mulpd);
break;
}
case kX64F64x2Div: {
ASSEMBLE_SSE_BINOP(divpd);
break;
}
case kX64F64x2Min: {
XMMRegister src1 = i.InputSimd128Register(1),
dst = i.OutputSimd128Register();
......
......@@ -166,6 +166,7 @@ namespace compiler {
V(X64F64x2Add) \
V(X64F64x2Sub) \
V(X64F64x2Mul) \
V(X64F64x2Div) \
V(X64F64x2Min) \
V(X64F64x2Max) \
V(X64F64x2Eq) \
......
......@@ -132,6 +132,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kX64F64x2Add:
case kX64F64x2Sub:
case kX64F64x2Mul:
case kX64F64x2Div:
case kX64F64x2Min:
case kX64F64x2Max:
case kX64F64x2Eq:
......
......@@ -2599,6 +2599,7 @@ VISIT_ATOMIC_BINOP(Xor)
V(F64x2Add) \
V(F64x2Sub) \
V(F64x2Mul) \
V(F64x2Div) \
V(F64x2Min) \
V(F64x2Max) \
V(F64x2Eq) \
......
......@@ -258,6 +258,7 @@ MachineType AtomicOpType(Operator const* op) {
V(F64x2Add, Operator::kCommutative, 2, 0, 1) \
V(F64x2Sub, Operator::kNoProperties, 2, 0, 1) \
V(F64x2Mul, Operator::kCommutative, 2, 0, 1) \
V(F64x2Div, Operator::kNoProperties, 2, 0, 1) \
V(F64x2Min, Operator::kCommutative, 2, 0, 1) \
V(F64x2Max, Operator::kCommutative, 2, 0, 1) \
V(F64x2Eq, Operator::kCommutative, 2, 0, 1) \
......
......@@ -480,6 +480,7 @@ class V8_EXPORT_PRIVATE MachineOperatorBuilder final
const Operator* F64x2Add();
const Operator* F64x2Sub();
const Operator* F64x2Mul();
const Operator* F64x2Div();
const Operator* F64x2ExtractLane(int32_t);
const Operator* F64x2Min();
const Operator* F64x2Max();
......
......@@ -752,6 +752,7 @@
V(F64x2Add) \
V(F64x2Sub) \
V(F64x2Mul) \
V(F64x2Div) \
V(F64x2Min) \
V(F64x2Max) \
V(F64x2Eq) \
......
......@@ -4008,6 +4008,9 @@ Node* WasmGraphBuilder::SimdOp(wasm::WasmOpcode opcode, Node* const* inputs) {
case wasm::kExprF64x2Mul:
return graph()->NewNode(mcgraph()->machine()->F64x2Mul(), inputs[0],
inputs[1]);
case wasm::kExprF64x2Div:
return graph()->NewNode(mcgraph()->machine()->F64x2Div(), inputs[0],
inputs[1]);
case wasm::kExprF64x2Min:
return graph()->NewNode(mcgraph()->machine()->F64x2Min(), inputs[0],
inputs[1]);
......
......@@ -1863,6 +1863,8 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) {
mnemonic = "subpd";
} else if (opcode == 0x5D) {
mnemonic = "minpd";
} else if (opcode == 0x5E) {
mnemonic = "divpd";
} else if (opcode == 0x5F) {
mnemonic = "maxpd";
} else if (opcode == 0x60) {
......
......@@ -2244,6 +2244,7 @@ class ThreadImpl {
BINOP_CASE(F64x2Add, f64x2, float2, 2, a + b)
BINOP_CASE(F64x2Sub, f64x2, float2, 2, a - b)
BINOP_CASE(F64x2Mul, f64x2, float2, 2, a * b)
BINOP_CASE(F64x2Div, f64x2, float2, 2, base::Divide(a, b))
BINOP_CASE(F64x2Min, f64x2, float2, 2, JSMin(a, b))
BINOP_CASE(F64x2Max, f64x2, float2, 2, JSMax(a, b))
BINOP_CASE(F32x4Add, f32x4, float4, 4, a + b)
......
......@@ -238,6 +238,7 @@ const char* WasmOpcodes::OpcodeName(WasmOpcode opcode) {
CASE_SIMD_OP(Mul, "mul")
CASE_F64x2_OP(Mul, "mul")
CASE_I64x2_OP(Mul, "mul")
CASE_F64x2_OP(Div, "div")
CASE_F64x2_OP(Splat, "splat")
CASE_F64x2_OP(Lt, "lt")
CASE_F64x2_OP(Le, "le")
......
......@@ -408,6 +408,7 @@ bool IsJSCompatibleSignature(const FunctionSig* sig, const WasmFeatures&);
V(F64x2Add, 0xfda5, s_ss) \
V(F64x2Sub, 0xfda6, s_ss) \
V(F64x2Mul, 0xfda7, s_ss) \
V(F64x2Div, 0xfda8, s_ss) \
V(F64x2Min, 0xfda9, s_ss) \
V(F64x2Max, 0xfdaa, s_ss) \
V(I32x4SConvertF32x4, 0xfdab, s_s) \
......
......@@ -86,6 +86,13 @@ T Mul(T a, T b) {
return a * b;
}
template <typename T, typename = typename std::enable_if<
std::is_floating_point<T>::value>::type>
T Div(T a, T b) {
// Workaround C++ undefined behavior when b is 0.
return base::Divide(a, b);
}
template <typename T>
T Minimum(T a, T b) {
return a <= b ? a : b;
......@@ -1217,6 +1224,10 @@ WASM_SIMD_TEST_NO_LOWERING(F64x2Mul) {
RunF64x2BinOpTest(execution_tier, lower_simd, kExprF64x2Mul, Mul);
}
WASM_SIMD_TEST_NO_LOWERING(F64x2Div) {
RunF64x2BinOpTest(execution_tier, lower_simd, kExprF64x2Div, Div);
}
WASM_SIMD_TEST_NO_LOWERING(F64x2Min) {
RunF64x2BinOpTest(execution_tier, lower_simd, kExprF64x2Min, JSMin);
}
......
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