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() {
V(Int32x4Splat) \
V(Int32x4ExtractLane) \
V(Int32x4ReplaceLane) \
V(Int32x4Neg) \
V(Simd128Not) \
V(Int32x4Add) \
V(Int32x4Sub) \
V(Int32x4Mul) \
......@@ -86,12 +88,16 @@ void SimdScalarLowering::LowerGraph() {
V(Float32x4Splat) \
V(Float32x4ExtractLane) \
V(Float32x4ReplaceLane) \
V(Float32x4Abs) \
V(Float32x4Neg) \
V(Float32x4Add) \
V(Float32x4Sub) \
V(Float32x4Mul) \
V(Float32x4Div) \
V(Float32x4Min) \
V(Float32x4Max)
V(Float32x4Max) \
V(Float32x4FromInt32x4) \
V(Float32x4FromUint32x4)
void SimdScalarLowering::SetLoweredType(Node* node, Node* output) {
switch (node->opcode()) {
......@@ -108,8 +114,14 @@ void SimdScalarLowering::SetLoweredType(Node* node, Node* output) {
break;
}
#undef CASE_STMT
default:
replacements_[node->id()].type = replacements_[output->id()].type;
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;
}
}
}
}
......@@ -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) {
DCHECK(node->InputCount() == 2);
Node** rep_left = GetReplacementsWithType(node->InputAt(0), rep_type);
Node** rep_right = GetReplacementsWithType(node->InputAt(1), rep_type);
Node** rep_left = GetReplacementsWithType(node->InputAt(0), input_rep_type);
Node** rep_right = GetReplacementsWithType(node->InputAt(1), input_rep_type);
Node* rep_node[kMaxLanes];
for (int i = 0; i < kMaxLanes; ++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,
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) {
SimdType rep_type = ReplacementType(node);
switch (node->opcode()) {
......@@ -399,6 +422,28 @@ void SimdScalarLowering::LowerNode(Node* node) {
I32X4_BINOP_CASE(kSimd128Or, Word32Or)
I32X4_BINOP_CASE(kSimd128Xor, Word32Xor)
#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) \
case IrOpcode::kFloat32x4##name: { \
LowerBinaryOp(node, rep_type, machine()->Float32##name()); \
......@@ -411,6 +456,23 @@ void SimdScalarLowering::LowerNode(Node* node) {
F32X4_BINOP_CASE(Min)
F32X4_BINOP_CASE(Max)
#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::kFloat32x4Splat: {
Node* rep_node[kMaxLanes];
......
......@@ -59,7 +59,8 @@ class SimdScalarLowering {
const Operator* load_op);
void LowerStoreOp(MachineRepresentation rep, Node* node,
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 {
Node* node;
......
......@@ -3383,6 +3383,8 @@ Node* WasmGraphBuilder::SimdOp(wasm::WasmOpcode opcode,
return graph()->NewNode(jsgraph()->machine()->Float32x4Abs(), inputs[0]);
case wasm::kExprF32x4Neg:
return graph()->NewNode(jsgraph()->machine()->Float32x4Neg(), inputs[0]);
case wasm::kExprF32x4Sqrt:
return graph()->NewNode(jsgraph()->machine()->Float32x4Sqrt(), inputs[0]);
case wasm::kExprF32x4Add:
return graph()->NewNode(jsgraph()->machine()->Float32x4Add(), inputs[0],
inputs[1]);
......
......@@ -212,6 +212,11 @@ T Not(T a) {
return ~a;
}
template <typename T>
T Sqrt(T a) {
return std::sqrt(a);
}
} // namespace
#if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_X64
......@@ -379,9 +384,7 @@ WASM_EXEC_COMPILED_TEST(F32x4ReplaceLane) {
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.
WASM_EXEC_COMPILED_TEST(F32x4FromInt32x4) {
FLAG_wasm_simd_prototype = true;
......@@ -417,13 +420,18 @@ void RunF32x4UnOpTest(WasmOpcode simd_op, FloatUnOp expected_op) {
FOR_FLOAT32_INPUTS(i) {
if (std::isnan(*i)) continue;
if (std::isnan(expected_op(*i))) continue;
CHECK_EQ(1, r.Call(*i, expected_op(*i)));
}
}
WASM_EXEC_COMPILED_TEST(F32x4Abs) { RunF32x4UnOpTest(kExprF32x4Abs, std::abs); }
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
void RunF32x4BinOpTest(WasmOpcode simd_op, FloatBinOp expected_op,
......@@ -808,7 +816,9 @@ WASM_EXEC_COMPILED_TEST(I32x4FromFloat32x4) {
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) {
FLAG_wasm_simd_prototype = true;
WasmRunner<int32_t, int32_t, int32_t> r(kExecuteCompiled);
......@@ -825,7 +835,7 @@ void RunI32x4UnOpTest(WasmOpcode simd_op, Int32UnOp expected_op) {
WASM_EXEC_COMPILED_TEST(I32x4Neg) { RunI32x4UnOpTest(kExprI32x4Neg, Negate); }
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) {
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