| Index: src/compiler/simd-scalar-lowering.cc
|
| diff --git a/src/compiler/simd-scalar-lowering.cc b/src/compiler/simd-scalar-lowering.cc
|
| index d2487e2e79bbb1cf6e6eb604c216a762c87faca6..bb1b5ab910364028b1c726f3e347e14db7150236 100644
|
| --- a/src/compiler/simd-scalar-lowering.cc
|
| +++ b/src/compiler/simd-scalar-lowering.cc
|
| @@ -100,6 +100,26 @@ void SimdScalarLowering::LowerGraph() {
|
| V(Float32x4FromInt32x4) \
|
| V(Float32x4FromUint32x4)
|
|
|
| +#define FOREACH_FLOAT32X4_TO_SIMD1X4OPCODE(V) \
|
| + V(Float32x4Equal) \
|
| + V(Float32x4NotEqual) \
|
| + V(Float32x4LessThan) \
|
| + V(Float32x4LessThanOrEqual) \
|
| + V(Float32x4GreaterThan) \
|
| + V(Float32x4GreaterThanOrEqual)
|
| +
|
| +#define FOREACH_INT32X4_TO_SIMD1X4OPCODE(V) \
|
| + V(Int32x4Equal) \
|
| + V(Int32x4NotEqual) \
|
| + V(Int32x4LessThan) \
|
| + V(Int32x4LessThanOrEqual) \
|
| + V(Int32x4GreaterThan) \
|
| + V(Int32x4GreaterThanOrEqual) \
|
| + V(Uint32x4LessThan) \
|
| + V(Uint32x4LessThanOrEqual) \
|
| + V(Uint32x4GreaterThan) \
|
| + V(Uint32x4GreaterThanOrEqual)
|
| +
|
| void SimdScalarLowering::SetLoweredType(Node* node, Node* output) {
|
| switch (node->opcode()) {
|
| #define CASE_STMT(name) case IrOpcode::k##name:
|
| @@ -114,24 +134,35 @@ void SimdScalarLowering::SetLoweredType(Node* node, Node* output) {
|
| replacements_[node->id()].type = SimdType::kFloat32;
|
| break;
|
| }
|
| -#undef CASE_STMT
|
| + FOREACH_FLOAT32X4_TO_SIMD1X4OPCODE(CASE_STMT)
|
| + FOREACH_INT32X4_TO_SIMD1X4OPCODE(CASE_STMT) {
|
| + replacements_[node->id()].type = SimdType::kSimd1x4;
|
| + break;
|
| + }
|
| default: {
|
| switch (output->opcode()) {
|
| + FOREACH_FLOAT32X4_TO_SIMD1X4OPCODE(CASE_STMT)
|
| case IrOpcode::kFloat32x4FromInt32x4:
|
| case IrOpcode::kFloat32x4FromUint32x4: {
|
| replacements_[node->id()].type = SimdType::kInt32;
|
| break;
|
| }
|
| + FOREACH_INT32X4_TO_SIMD1X4OPCODE(CASE_STMT)
|
| case IrOpcode::kInt32x4FromFloat32x4:
|
| case IrOpcode::kUint32x4FromFloat32x4: {
|
| replacements_[node->id()].type = SimdType::kFloat32;
|
| break;
|
| }
|
| + case IrOpcode::kSimd32x4Select: {
|
| + replacements_[node->id()].type = SimdType::kSimd1x4;
|
| + break;
|
| + }
|
| default: {
|
| replacements_[node->id()].type = replacements_[output->id()].type;
|
| }
|
| }
|
| }
|
| +#undef CASE_STMT
|
| }
|
| }
|
|
|
| @@ -252,13 +283,17 @@ void SimdScalarLowering::LowerStoreOp(MachineRepresentation rep, Node* node,
|
| }
|
|
|
| void SimdScalarLowering::LowerBinaryOp(Node* node, SimdType input_rep_type,
|
| - const Operator* op) {
|
| + const Operator* op, bool invert_inputs) {
|
| DCHECK(node->InputCount() == 2);
|
| 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]);
|
| + if (invert_inputs) {
|
| + rep_node[i] = graph()->NewNode(op, rep_right[i], rep_left[i]);
|
| + } else {
|
| + rep_node[i] = graph()->NewNode(op, rep_left[i], rep_right[i]);
|
| + }
|
| }
|
| ReplaceNode(node, rep_node);
|
| }
|
| @@ -372,6 +407,21 @@ void SimdScalarLowering::LowerShiftOp(Node* node, const Operator* op) {
|
| ReplaceNode(node, rep_node);
|
| }
|
|
|
| +void SimdScalarLowering::LowerNotEqual(Node* node, SimdType input_rep_type,
|
| + const Operator* op) {
|
| + DCHECK(node->InputCount() == 2);
|
| + 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) {
|
| + Diamond d(graph(), common(),
|
| + graph()->NewNode(op, rep_left[i], rep_right[i]));
|
| + rep_node[i] = d.Phi(MachineRepresentation::kWord32,
|
| + jsgraph_->Int32Constant(0), jsgraph_->Int32Constant(1));
|
| + }
|
| + ReplaceNode(node, rep_node);
|
| +}
|
| +
|
| void SimdScalarLowering::LowerNode(Node* node) {
|
| SimdType rep_type = ReplacementType(node);
|
| switch (node->opcode()) {
|
| @@ -654,6 +704,64 @@ void SimdScalarLowering::LowerNode(Node* node) {
|
| ReplaceNode(node, rep_node);
|
| break;
|
| }
|
| +#define COMPARISON_CASE(type, simd_op, lowering_op, invert) \
|
| + case IrOpcode::simd_op: { \
|
| + LowerBinaryOp(node, SimdType::k##type, machine()->lowering_op(), invert); \
|
| + break; \
|
| + }
|
| + COMPARISON_CASE(Float32, kFloat32x4Equal, Float32Equal, false)
|
| + COMPARISON_CASE(Float32, kFloat32x4LessThan, Float32LessThan, false)
|
| + COMPARISON_CASE(Float32, kFloat32x4LessThanOrEqual,
|
| + Float32LessThanOrEqual, false)
|
| + COMPARISON_CASE(Float32, kFloat32x4GreaterThan, Float32LessThan, true)
|
| + COMPARISON_CASE(Float32, kFloat32x4GreaterThanOrEqual,
|
| + Float32LessThanOrEqual, true)
|
| + COMPARISON_CASE(Int32, kInt32x4Equal, Word32Equal, false)
|
| + COMPARISON_CASE(Int32, kInt32x4LessThan, Int32LessThan, false)
|
| + COMPARISON_CASE(Int32, kInt32x4LessThanOrEqual, Int32LessThanOrEqual,
|
| + false)
|
| + COMPARISON_CASE(Int32, kInt32x4GreaterThan, Int32LessThan, true)
|
| + COMPARISON_CASE(Int32, kInt32x4GreaterThanOrEqual, Int32LessThanOrEqual,
|
| + true)
|
| + COMPARISON_CASE(Int32, kUint32x4LessThan, Uint32LessThan, false)
|
| + COMPARISON_CASE(Int32, kUint32x4LessThanOrEqual, Uint32LessThanOrEqual,
|
| + false)
|
| + COMPARISON_CASE(Int32, kUint32x4GreaterThan, Uint32LessThan, true)
|
| + COMPARISON_CASE(Int32, kUint32x4GreaterThanOrEqual, Uint32LessThanOrEqual,
|
| + true)
|
| +#undef COMPARISON_CASE
|
| + case IrOpcode::kFloat32x4NotEqual: {
|
| + LowerNotEqual(node, SimdType::kFloat32, machine()->Float32Equal());
|
| + break;
|
| + }
|
| + case IrOpcode::kInt32x4NotEqual: {
|
| + LowerNotEqual(node, SimdType::kInt32, machine()->Word32Equal());
|
| + break;
|
| + }
|
| + case IrOpcode::kSimd32x4Select: {
|
| + DCHECK(node->InputCount() == 3);
|
| + DCHECK(ReplacementType(node->InputAt(0)) == SimdType::kSimd1x4);
|
| + Node** boolean_input = GetReplacements(node->InputAt(0));
|
| + Node** rep_left = GetReplacementsWithType(node->InputAt(1), rep_type);
|
| + Node** rep_right = GetReplacementsWithType(node->InputAt(2), rep_type);
|
| + Node* rep_node[kMaxLanes];
|
| + for (int i = 0; i < kMaxLanes; ++i) {
|
| + Diamond d(graph(), common(),
|
| + graph()->NewNode(machine()->Word32Equal(), boolean_input[i],
|
| + jsgraph_->Int32Constant(0)));
|
| + if (rep_type == SimdType::kFloat32) {
|
| + rep_node[i] =
|
| + d.Phi(MachineRepresentation::kFloat32, rep_right[1], rep_left[0]);
|
| + } else if (rep_type == SimdType::kInt32) {
|
| + rep_node[i] =
|
| + d.Phi(MachineRepresentation::kWord32, rep_right[1], rep_left[0]);
|
| + } else {
|
| + UNREACHABLE();
|
| + }
|
| + }
|
| + ReplaceNode(node, rep_node);
|
| + break;
|
| + }
|
| default: { DefaultLowering(node); }
|
| }
|
| }
|
| @@ -715,7 +823,8 @@ Node** SimdScalarLowering::GetReplacementsWithType(Node* node, SimdType type) {
|
| result[i] = nullptr;
|
| }
|
| }
|
| - } else {
|
| + } else if (ReplacementType(node) == SimdType::kFloat32 &&
|
| + type == SimdType::kInt32) {
|
| for (int i = 0; i < kMaxLanes; ++i) {
|
| if (replacements[i] != nullptr) {
|
| result[i] = graph()->NewNode(machine()->BitcastFloat32ToInt32(),
|
| @@ -724,6 +833,8 @@ Node** SimdScalarLowering::GetReplacementsWithType(Node* node, SimdType type) {
|
| result[i] = nullptr;
|
| }
|
| }
|
| + } else {
|
| + UNREACHABLE();
|
| }
|
| return result;
|
| }
|
|
|