Commit a727f9e8 authored by aseemgarg's avatar aseemgarg Committed by Commit bot

[wasm]implement simd lowering for simple F32x4 and I32x4 unops

BUG=v8:4124
R=bradnelson@chromium.org,bbudge@chromium.org,gdeepti@chromium.org,mtrofin@chromium.org,titzer@chromium.org

Review-Url: https://codereview.chromium.org/2726453003
Cr-Commit-Position: refs/heads/master@{#43509}
parent bff95642
...@@ -75,6 +75,8 @@ void SimdScalarLowering::LowerGraph() { ...@@ -75,6 +75,8 @@ void SimdScalarLowering::LowerGraph() {
V(Int32x4Splat) \ V(Int32x4Splat) \
V(Int32x4ExtractLane) \ V(Int32x4ExtractLane) \
V(Int32x4ReplaceLane) \ V(Int32x4ReplaceLane) \
V(Int32x4Neg) \
V(Simd128Not) \
V(Int32x4Add) \ V(Int32x4Add) \
V(Int32x4Sub) \ V(Int32x4Sub) \
V(Int32x4Mul) \ V(Int32x4Mul) \
...@@ -86,12 +88,16 @@ void SimdScalarLowering::LowerGraph() { ...@@ -86,12 +88,16 @@ void SimdScalarLowering::LowerGraph() {
V(Float32x4Splat) \ V(Float32x4Splat) \
V(Float32x4ExtractLane) \ V(Float32x4ExtractLane) \
V(Float32x4ReplaceLane) \ V(Float32x4ReplaceLane) \
V(Float32x4Abs) \
V(Float32x4Neg) \
V(Float32x4Add) \ V(Float32x4Add) \
V(Float32x4Sub) \ V(Float32x4Sub) \
V(Float32x4Mul) \ V(Float32x4Mul) \
V(Float32x4Div) \ V(Float32x4Div) \
V(Float32x4Min) \ V(Float32x4Min) \
V(Float32x4Max) V(Float32x4Max) \
V(Float32x4FromInt32x4) \
V(Float32x4FromUint32x4)
void SimdScalarLowering::SetLoweredType(Node* node, Node* output) { void SimdScalarLowering::SetLoweredType(Node* node, Node* output) {
switch (node->opcode()) { switch (node->opcode()) {
...@@ -108,9 +114,15 @@ void SimdScalarLowering::SetLoweredType(Node* node, Node* output) { ...@@ -108,9 +114,15 @@ void SimdScalarLowering::SetLoweredType(Node* node, Node* output) {
break; break;
} }
#undef CASE_STMT #undef CASE_STMT
default: default: {
if (output->opcode() == IrOpcode::kFloat32x4FromInt32x4 ||
output->opcode() == IrOpcode::kFloat32x4FromUint32x4) {
replacements_[node->id()].type = SimdType::kInt32;
} else {
replacements_[node->id()].type = replacements_[output->id()].type; replacements_[node->id()].type = replacements_[output->id()].type;
} }
}
}
} }
static int GetParameterIndexAfterLowering( static int GetParameterIndexAfterLowering(
...@@ -229,11 +241,11 @@ void SimdScalarLowering::LowerStoreOp(MachineRepresentation rep, Node* node, ...@@ -229,11 +241,11 @@ void SimdScalarLowering::LowerStoreOp(MachineRepresentation rep, Node* node,
} }
} }
void SimdScalarLowering::LowerBinaryOp(Node* node, SimdType rep_type, void SimdScalarLowering::LowerBinaryOp(Node* node, SimdType input_rep_type,
const Operator* op) { const Operator* op) {
DCHECK(node->InputCount() == 2); DCHECK(node->InputCount() == 2);
Node** rep_left = GetReplacementsWithType(node->InputAt(0), rep_type); Node** rep_left = GetReplacementsWithType(node->InputAt(0), input_rep_type);
Node** rep_right = GetReplacementsWithType(node->InputAt(1), rep_type); Node** rep_right = GetReplacementsWithType(node->InputAt(1), input_rep_type);
Node* rep_node[kMaxLanes]; Node* rep_node[kMaxLanes];
for (int i = 0; i < kMaxLanes; ++i) { for (int i = 0; i < kMaxLanes; ++i) {
rep_node[i] = graph()->NewNode(op, rep_left[i], rep_right[i]); rep_node[i] = graph()->NewNode(op, rep_left[i], rep_right[i]);
...@@ -241,6 +253,17 @@ void SimdScalarLowering::LowerBinaryOp(Node* node, SimdType rep_type, ...@@ -241,6 +253,17 @@ void SimdScalarLowering::LowerBinaryOp(Node* node, SimdType rep_type,
ReplaceNode(node, rep_node); ReplaceNode(node, rep_node);
} }
void SimdScalarLowering::LowerUnaryOp(Node* node, SimdType input_rep_type,
const Operator* op) {
DCHECK(node->InputCount() == 1);
Node** rep = GetReplacementsWithType(node->InputAt(0), input_rep_type);
Node* rep_node[kMaxLanes];
for (int i = 0; i < kMaxLanes; ++i) {
rep_node[i] = graph()->NewNode(op, rep[i]);
}
ReplaceNode(node, rep_node);
}
void SimdScalarLowering::LowerNode(Node* node) { void SimdScalarLowering::LowerNode(Node* node) {
SimdType rep_type = ReplacementType(node); SimdType rep_type = ReplacementType(node);
switch (node->opcode()) { switch (node->opcode()) {
...@@ -399,6 +422,28 @@ void SimdScalarLowering::LowerNode(Node* node) { ...@@ -399,6 +422,28 @@ void SimdScalarLowering::LowerNode(Node* node) {
I32X4_BINOP_CASE(kSimd128Or, Word32Or) I32X4_BINOP_CASE(kSimd128Or, Word32Or)
I32X4_BINOP_CASE(kSimd128Xor, Word32Xor) I32X4_BINOP_CASE(kSimd128Xor, Word32Xor)
#undef I32X4_BINOP_CASE #undef I32X4_BINOP_CASE
case IrOpcode::kInt32x4Neg: {
DCHECK(node->InputCount() == 1);
Node** rep = GetReplacementsWithType(node->InputAt(0), rep_type);
Node* rep_node[kMaxLanes];
Node* zero = graph()->NewNode(common()->Int32Constant(0));
for (int i = 0; i < kMaxLanes; ++i) {
rep_node[i] = graph()->NewNode(machine()->Int32Sub(), zero, rep[i]);
}
ReplaceNode(node, rep_node);
break;
}
case IrOpcode::kSimd128Not: {
DCHECK(node->InputCount() == 1);
Node** rep = GetReplacementsWithType(node->InputAt(0), rep_type);
Node* rep_node[kMaxLanes];
Node* mask = graph()->NewNode(common()->Int32Constant(0xffffffff));
for (int i = 0; i < kMaxLanes; ++i) {
rep_node[i] = graph()->NewNode(machine()->Word32Xor(), rep[i], mask);
}
ReplaceNode(node, rep_node);
break;
}
#define F32X4_BINOP_CASE(name) \ #define F32X4_BINOP_CASE(name) \
case IrOpcode::kFloat32x4##name: { \ case IrOpcode::kFloat32x4##name: { \
LowerBinaryOp(node, rep_type, machine()->Float32##name()); \ LowerBinaryOp(node, rep_type, machine()->Float32##name()); \
...@@ -411,6 +456,23 @@ void SimdScalarLowering::LowerNode(Node* node) { ...@@ -411,6 +456,23 @@ void SimdScalarLowering::LowerNode(Node* node) {
F32X4_BINOP_CASE(Min) F32X4_BINOP_CASE(Min)
F32X4_BINOP_CASE(Max) F32X4_BINOP_CASE(Max)
#undef F32X4_BINOP_CASE #undef F32X4_BINOP_CASE
#define F32X4_UNOP_CASE(name) \
case IrOpcode::kFloat32x4##name: { \
LowerUnaryOp(node, rep_type, machine()->Float32##name()); \
break; \
}
F32X4_UNOP_CASE(Abs)
F32X4_UNOP_CASE(Neg)
F32X4_UNOP_CASE(Sqrt)
#undef F32x4_UNOP_CASE
case IrOpcode::kFloat32x4FromInt32x4: {
LowerUnaryOp(node, SimdType::kInt32, machine()->RoundInt32ToFloat32());
break;
}
case IrOpcode::kFloat32x4FromUint32x4: {
LowerUnaryOp(node, SimdType::kInt32, machine()->RoundUint32ToFloat32());
break;
}
case IrOpcode::kInt32x4Splat: case IrOpcode::kInt32x4Splat:
case IrOpcode::kFloat32x4Splat: { case IrOpcode::kFloat32x4Splat: {
Node* rep_node[kMaxLanes]; Node* rep_node[kMaxLanes];
......
...@@ -59,7 +59,8 @@ class SimdScalarLowering { ...@@ -59,7 +59,8 @@ class SimdScalarLowering {
const Operator* load_op); const Operator* load_op);
void LowerStoreOp(MachineRepresentation rep, Node* node, void LowerStoreOp(MachineRepresentation rep, Node* node,
const Operator* store_op, SimdType rep_type); const Operator* store_op, SimdType rep_type);
void LowerBinaryOp(Node* node, SimdType rep_type, const Operator* op); void LowerBinaryOp(Node* node, SimdType input_rep_type, const Operator* op);
void LowerUnaryOp(Node* node, SimdType input_rep_type, const Operator* op);
struct NodeState { struct NodeState {
Node* node; Node* node;
......
...@@ -3383,6 +3383,8 @@ Node* WasmGraphBuilder::SimdOp(wasm::WasmOpcode opcode, ...@@ -3383,6 +3383,8 @@ Node* WasmGraphBuilder::SimdOp(wasm::WasmOpcode opcode,
return graph()->NewNode(jsgraph()->machine()->Float32x4Abs(), inputs[0]); return graph()->NewNode(jsgraph()->machine()->Float32x4Abs(), inputs[0]);
case wasm::kExprF32x4Neg: case wasm::kExprF32x4Neg:
return graph()->NewNode(jsgraph()->machine()->Float32x4Neg(), inputs[0]); return graph()->NewNode(jsgraph()->machine()->Float32x4Neg(), inputs[0]);
case wasm::kExprF32x4Sqrt:
return graph()->NewNode(jsgraph()->machine()->Float32x4Sqrt(), inputs[0]);
case wasm::kExprF32x4Add: case wasm::kExprF32x4Add:
return graph()->NewNode(jsgraph()->machine()->Float32x4Add(), inputs[0], return graph()->NewNode(jsgraph()->machine()->Float32x4Add(), inputs[0],
inputs[1]); inputs[1]);
......
...@@ -212,6 +212,11 @@ T Not(T a) { ...@@ -212,6 +212,11 @@ T Not(T a) {
return ~a; return ~a;
} }
template <typename T>
T Sqrt(T a) {
return std::sqrt(a);
}
} // namespace } // namespace
#if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_X64 #if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_X64
...@@ -379,9 +384,7 @@ WASM_EXEC_COMPILED_TEST(F32x4ReplaceLane) { ...@@ -379,9 +384,7 @@ WASM_EXEC_COMPILED_TEST(F32x4ReplaceLane) {
CHECK_EQ(1, r.Call(3.14159f, -1.5f)); CHECK_EQ(1, r.Call(3.14159f, -1.5f));
} }
#endif // V8_TARGET_ARCH_ARM || SIMD_LOWERING_TARGET
#if V8_TARGET_ARCH_ARM
// Tests both signed and unsigned conversion. // Tests both signed and unsigned conversion.
WASM_EXEC_COMPILED_TEST(F32x4FromInt32x4) { WASM_EXEC_COMPILED_TEST(F32x4FromInt32x4) {
FLAG_wasm_simd_prototype = true; FLAG_wasm_simd_prototype = true;
...@@ -417,13 +420,18 @@ void RunF32x4UnOpTest(WasmOpcode simd_op, FloatUnOp expected_op) { ...@@ -417,13 +420,18 @@ void RunF32x4UnOpTest(WasmOpcode simd_op, FloatUnOp expected_op) {
FOR_FLOAT32_INPUTS(i) { FOR_FLOAT32_INPUTS(i) {
if (std::isnan(*i)) continue; if (std::isnan(*i)) continue;
if (std::isnan(expected_op(*i))) continue;
CHECK_EQ(1, r.Call(*i, expected_op(*i))); CHECK_EQ(1, r.Call(*i, expected_op(*i)));
} }
} }
WASM_EXEC_COMPILED_TEST(F32x4Abs) { RunF32x4UnOpTest(kExprF32x4Abs, std::abs); } WASM_EXEC_COMPILED_TEST(F32x4Abs) { RunF32x4UnOpTest(kExprF32x4Abs, std::abs); }
WASM_EXEC_COMPILED_TEST(F32x4Neg) { RunF32x4UnOpTest(kExprF32x4Neg, Negate); } WASM_EXEC_COMPILED_TEST(F32x4Neg) { RunF32x4UnOpTest(kExprF32x4Neg, Negate); }
#endif // V8_TARGET_ARCH_ARM #endif // V8_TARGET_ARCH_ARM || SIMD_LOWERING_TARGET
#if SIMD_LOWERING_TARGET
WASM_EXEC_COMPILED_TEST(F32x4Sqrt) { RunF32x4UnOpTest(kExprF32x4Sqrt, Sqrt); }
#endif // SIMD_LOWERING_TARGET
#if V8_TARGET_ARCH_ARM || SIMD_LOWERING_TARGET #if V8_TARGET_ARCH_ARM || SIMD_LOWERING_TARGET
void RunF32x4BinOpTest(WasmOpcode simd_op, FloatBinOp expected_op, void RunF32x4BinOpTest(WasmOpcode simd_op, FloatBinOp expected_op,
...@@ -808,7 +816,9 @@ WASM_EXEC_COMPILED_TEST(I32x4FromFloat32x4) { ...@@ -808,7 +816,9 @@ WASM_EXEC_COMPILED_TEST(I32x4FromFloat32x4) {
CHECK_EQ(1, r.Call(*i, signed_value, unsigned_value)); CHECK_EQ(1, r.Call(*i, signed_value, unsigned_value));
} }
} }
#endif // V8_TARGET_ARCH_ARM
#if V8_TARGET_ARCH_ARM || SIMD_LOWERING_TARGET
void RunI32x4UnOpTest(WasmOpcode simd_op, Int32UnOp expected_op) { void RunI32x4UnOpTest(WasmOpcode simd_op, Int32UnOp expected_op) {
FLAG_wasm_simd_prototype = true; FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t, int32_t, int32_t> r(kExecuteCompiled); WasmRunner<int32_t, int32_t, int32_t> r(kExecuteCompiled);
...@@ -825,7 +835,7 @@ void RunI32x4UnOpTest(WasmOpcode simd_op, Int32UnOp expected_op) { ...@@ -825,7 +835,7 @@ void RunI32x4UnOpTest(WasmOpcode simd_op, Int32UnOp expected_op) {
WASM_EXEC_COMPILED_TEST(I32x4Neg) { RunI32x4UnOpTest(kExprI32x4Neg, Negate); } WASM_EXEC_COMPILED_TEST(I32x4Neg) { RunI32x4UnOpTest(kExprI32x4Neg, Negate); }
WASM_EXEC_COMPILED_TEST(S128Not) { RunI32x4UnOpTest(kExprS128Not, Not); } WASM_EXEC_COMPILED_TEST(S128Not) { RunI32x4UnOpTest(kExprS128Not, Not); }
#endif // V8_TARGET_ARCH_ARM #endif // V8_TARGET_ARCH_ARM || SIMD_LOWERING_TARGET
void RunI32x4BinOpTest(WasmOpcode simd_op, Int32BinOp expected_op) { void RunI32x4BinOpTest(WasmOpcode simd_op, Int32BinOp expected_op) {
FLAG_wasm_simd_prototype = true; FLAG_wasm_simd_prototype = true;
......
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