Commit e394b7d2 authored by Ng Zhi An's avatar Ng Zhi An Committed by Commit Bot

[wasm-simd][scalar-lowering] Enable F64x2 tests for scalar lowering

Add in f64x2 opcodes to simd scalar lowering, this allows us to enable
most of the f64x2 test cases with quite little changes - the significant
change is to make sure the comparisons return a Int64 node.

Bug: v8:10507
Change-Id: I8c8920d37c0cd0841dafcdb0310b6340b3c16189
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2399051Reviewed-by: 's avatarBill Budge <bbudge@chromium.org>
Commit-Queue: Zhi An Ng <zhin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#69757}
parent 33e6ac5d
...@@ -151,7 +151,19 @@ void SimdScalarLowering::LowerGraph() { ...@@ -151,7 +151,19 @@ void SimdScalarLowering::LowerGraph() {
V(V8x16AllTrue) \ V(V8x16AllTrue) \
V(I32x4BitMask) V(I32x4BitMask)
#define FOREACH_FLOAT64X2_OPCODE(V) V(F64x2Splat) #define FOREACH_FLOAT64X2_OPCODE(V) \
V(F64x2Splat) \
V(F64x2ExtractLane) \
V(F64x2ReplaceLane) \
V(F64x2Abs) \
V(F64x2Neg) \
V(F64x2Sqrt) \
V(F64x2Add) \
V(F64x2Sub) \
V(F64x2Mul) \
V(F64x2Div) \
V(F64x2Min) \
V(F64x2Max)
#define FOREACH_FLOAT32X4_OPCODE(V) \ #define FOREACH_FLOAT32X4_OPCODE(V) \
V(F32x4Splat) \ V(F32x4Splat) \
...@@ -172,6 +184,12 @@ void SimdScalarLowering::LowerGraph() { ...@@ -172,6 +184,12 @@ void SimdScalarLowering::LowerGraph() {
V(F32x4Min) \ V(F32x4Min) \
V(F32x4Max) V(F32x4Max)
#define FOREACH_FLOAT64x2_TO_INT64x2OPCODE(V) \
V(F64x2Eq) \
V(F64x2Ne) \
V(F64x2Lt) \
V(F64x2Le)
#define FOREACH_FLOAT32X4_TO_INT32X4OPCODE(V) \ #define FOREACH_FLOAT32X4_TO_INT32X4OPCODE(V) \
V(F32x4Eq) \ V(F32x4Eq) \
V(F32x4Ne) \ V(F32x4Ne) \
...@@ -303,6 +321,10 @@ void SimdScalarLowering::SetLoweredType(Node* node, Node* output) { ...@@ -303,6 +321,10 @@ void SimdScalarLowering::SetLoweredType(Node* node, Node* output) {
replacements_[node->id()].type = SimdType::kInt32x4; replacements_[node->id()].type = SimdType::kInt32x4;
break; break;
} }
FOREACH_FLOAT64x2_TO_INT64x2OPCODE(CASE_STMT) {
replacements_[node->id()].type = SimdType::kInt64x2;
break;
}
FOREACH_INT16X8_OPCODE(CASE_STMT) { FOREACH_INT16X8_OPCODE(CASE_STMT) {
replacements_[node->id()].type = SimdType::kInt16x8; replacements_[node->id()].type = SimdType::kInt16x8;
break; break;
...@@ -697,12 +719,7 @@ void SimdScalarLowering::LowerCompareOp(Node* node, SimdType input_rep_type, ...@@ -697,12 +719,7 @@ void SimdScalarLowering::LowerCompareOp(Node* node, SimdType input_rep_type,
cmp_result = graph()->NewNode(op, rep_left[i], rep_right[i]); cmp_result = graph()->NewNode(op, rep_left[i], rep_right[i]);
} }
Diamond d_cmp(graph(), common(), cmp_result); Diamond d_cmp(graph(), common(), cmp_result);
MachineRepresentation rep = rep_node[i] = ConstructPhiForComparison(d_cmp, input_rep_type, -1, 0);
(input_rep_type == SimdType::kFloat32x4)
? MachineRepresentation::kWord32
: MachineTypeFrom(input_rep_type).representation();
rep_node[i] =
d_cmp.Phi(rep, mcgraph_->Int32Constant(-1), mcgraph_->Int32Constant(0));
} }
ReplaceNode(node, rep_node, num_lanes); ReplaceNode(node, rep_node, num_lanes);
} }
...@@ -1033,6 +1050,26 @@ void SimdScalarLowering::LowerShiftOp(Node* node, SimdType type) { ...@@ -1033,6 +1050,26 @@ void SimdScalarLowering::LowerShiftOp(Node* node, SimdType type) {
ReplaceNode(node, rep_node, num_lanes); ReplaceNode(node, rep_node, num_lanes);
} }
Node* SimdScalarLowering::ConstructPhiForComparison(Diamond d,
SimdType rep_type,
int true_value,
int false_value) {
// Close the given Diamond d using a Phi node, taking care of constructing the
// right kind of constants (Int32 or Int64) based on rep_type.
if (rep_type == SimdType::kFloat64x2) {
MachineRepresentation rep = MachineRepresentation::kWord64;
return d.Phi(rep, mcgraph_->Int64Constant(true_value),
mcgraph_->Int64Constant(false_value));
} else {
MachineRepresentation rep =
(rep_type == SimdType::kFloat32x4)
? MachineRepresentation::kWord32
: MachineTypeFrom(rep_type).representation();
return d.Phi(rep, mcgraph_->Int32Constant(true_value),
mcgraph_->Int32Constant(false_value));
}
}
void SimdScalarLowering::LowerNotEqual(Node* node, SimdType input_rep_type, void SimdScalarLowering::LowerNotEqual(Node* node, SimdType input_rep_type,
const Operator* op) { const Operator* op) {
DCHECK_EQ(2, node->InputCount()); DCHECK_EQ(2, node->InputCount());
...@@ -1043,12 +1080,7 @@ void SimdScalarLowering::LowerNotEqual(Node* node, SimdType input_rep_type, ...@@ -1043,12 +1080,7 @@ void SimdScalarLowering::LowerNotEqual(Node* node, SimdType input_rep_type,
for (int i = 0; i < num_lanes; ++i) { for (int i = 0; i < num_lanes; ++i) {
Diamond d(graph(), common(), Diamond d(graph(), common(),
graph()->NewNode(op, rep_left[i], rep_right[i])); graph()->NewNode(op, rep_left[i], rep_right[i]));
MachineRepresentation rep = rep_node[i] = ConstructPhiForComparison(d, input_rep_type, 0, -1);
(input_rep_type == SimdType::kFloat32x4)
? MachineRepresentation::kWord32
: MachineTypeFrom(input_rep_type).representation();
rep_node[i] =
d.Phi(rep, mcgraph_->Int32Constant(0), mcgraph_->Int32Constant(-1));
} }
ReplaceNode(node, rep_node, num_lanes); ReplaceNode(node, rep_node, num_lanes);
} }
...@@ -1613,6 +1645,42 @@ void SimdScalarLowering::LowerNode(Node* node) { ...@@ -1613,6 +1645,42 @@ void SimdScalarLowering::LowerNode(Node* node) {
LowerUnaryOp(node, SimdType::kInt32x4, machine()->RoundUint32ToFloat32()); LowerUnaryOp(node, SimdType::kInt32x4, machine()->RoundUint32ToFloat32());
break; break;
} }
case IrOpcode::kF64x2Abs: {
LowerUnaryOp(node, rep_type, machine()->Float64Abs());
break;
}
case IrOpcode::kF64x2Neg: {
LowerUnaryOp(node, rep_type, machine()->Float64Neg());
break;
}
case IrOpcode::kF64x2Sqrt: {
LowerUnaryOp(node, rep_type, machine()->Float64Sqrt());
break;
}
case IrOpcode::kF64x2Add: {
LowerBinaryOp(node, rep_type, machine()->Float64Add());
break;
}
case IrOpcode::kF64x2Sub: {
LowerBinaryOp(node, rep_type, machine()->Float64Sub());
break;
}
case IrOpcode::kF64x2Mul: {
LowerBinaryOp(node, rep_type, machine()->Float64Mul());
break;
}
case IrOpcode::kF64x2Div: {
LowerBinaryOp(node, rep_type, machine()->Float64Div());
break;
}
case IrOpcode::kF64x2Min: {
LowerBinaryOp(node, rep_type, machine()->Float64Min());
break;
}
case IrOpcode::kF64x2Max: {
LowerBinaryOp(node, rep_type, machine()->Float64Max());
break;
}
case IrOpcode::kF64x2Splat: case IrOpcode::kF64x2Splat:
case IrOpcode::kF32x4Splat: case IrOpcode::kF32x4Splat:
case IrOpcode::kI64x2Splat: case IrOpcode::kI64x2Splat:
...@@ -1630,8 +1698,9 @@ void SimdScalarLowering::LowerNode(Node* node) { ...@@ -1630,8 +1698,9 @@ void SimdScalarLowering::LowerNode(Node* node) {
ReplaceNode(node, rep_node, num_lanes); ReplaceNode(node, rep_node, num_lanes);
break; break;
} }
case IrOpcode::kI32x4ExtractLane: case IrOpcode::kF64x2ExtractLane:
case IrOpcode::kF32x4ExtractLane: case IrOpcode::kF32x4ExtractLane:
case IrOpcode::kI32x4ExtractLane:
case IrOpcode::kI16x8ExtractLaneU: case IrOpcode::kI16x8ExtractLaneU:
case IrOpcode::kI16x8ExtractLaneS: case IrOpcode::kI16x8ExtractLaneS:
case IrOpcode::kI8x16ExtractLaneU: case IrOpcode::kI8x16ExtractLaneU:
...@@ -1645,8 +1714,9 @@ void SimdScalarLowering::LowerNode(Node* node) { ...@@ -1645,8 +1714,9 @@ void SimdScalarLowering::LowerNode(Node* node) {
ReplaceNode(node, rep_node, num_lanes); ReplaceNode(node, rep_node, num_lanes);
break; break;
} }
case IrOpcode::kI32x4ReplaceLane: case IrOpcode::kF64x2ReplaceLane:
case IrOpcode::kF32x4ReplaceLane: case IrOpcode::kF32x4ReplaceLane:
case IrOpcode::kI32x4ReplaceLane:
case IrOpcode::kI16x8ReplaceLane: case IrOpcode::kI16x8ReplaceLane:
case IrOpcode::kI8x16ReplaceLane: { case IrOpcode::kI8x16ReplaceLane: {
DCHECK_EQ(2, node->InputCount()); DCHECK_EQ(2, node->InputCount());
...@@ -1670,6 +1740,9 @@ void SimdScalarLowering::LowerNode(Node* node) { ...@@ -1670,6 +1740,9 @@ void SimdScalarLowering::LowerNode(Node* node) {
LowerCompareOp(node, SimdType::k##type, machine()->lowering_op(), invert); \ LowerCompareOp(node, SimdType::k##type, machine()->lowering_op(), invert); \
break; \ break; \
} }
COMPARISON_CASE(Float64x2, kF64x2Eq, Float64Equal, false)
COMPARISON_CASE(Float64x2, kF64x2Lt, Float64LessThan, false)
COMPARISON_CASE(Float64x2, kF64x2Le, Float64LessThanOrEqual, false)
COMPARISON_CASE(Float32x4, kF32x4Eq, Float32Equal, false) COMPARISON_CASE(Float32x4, kF32x4Eq, Float32Equal, false)
COMPARISON_CASE(Float32x4, kF32x4Lt, Float32LessThan, false) COMPARISON_CASE(Float32x4, kF32x4Lt, Float32LessThan, false)
COMPARISON_CASE(Float32x4, kF32x4Le, Float32LessThanOrEqual, false) COMPARISON_CASE(Float32x4, kF32x4Le, Float32LessThanOrEqual, false)
...@@ -1703,6 +1776,10 @@ void SimdScalarLowering::LowerNode(Node* node) { ...@@ -1703,6 +1776,10 @@ void SimdScalarLowering::LowerNode(Node* node) {
COMPARISON_CASE(Int8x16, kI8x16GtU, Uint32LessThan, true) COMPARISON_CASE(Int8x16, kI8x16GtU, Uint32LessThan, true)
COMPARISON_CASE(Int8x16, kI8x16GeU, Uint32LessThanOrEqual, true) COMPARISON_CASE(Int8x16, kI8x16GeU, Uint32LessThanOrEqual, true)
#undef COMPARISON_CASE #undef COMPARISON_CASE
case IrOpcode::kF64x2Ne: {
LowerNotEqual(node, SimdType::kFloat64x2, machine()->Float64Equal());
break;
}
case IrOpcode::kF32x4Ne: { case IrOpcode::kF32x4Ne: {
LowerNotEqual(node, SimdType::kFloat32x4, machine()->Float32Equal()); LowerNotEqual(node, SimdType::kFloat32x4, machine()->Float32Equal());
break; break;
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define V8_COMPILER_SIMD_SCALAR_LOWERING_H_ #define V8_COMPILER_SIMD_SCALAR_LOWERING_H_
#include "src/compiler/common-operator.h" #include "src/compiler/common-operator.h"
#include "src/compiler/diamond.h"
#include "src/compiler/graph.h" #include "src/compiler/graph.h"
#include "src/compiler/machine-graph.h" #include "src/compiler/machine-graph.h"
#include "src/compiler/machine-operator.h" #include "src/compiler/machine-operator.h"
...@@ -89,6 +90,8 @@ class SimdScalarLowering { ...@@ -89,6 +90,8 @@ class SimdScalarLowering {
void LowerStoreOp(Node* node); void LowerStoreOp(Node* node);
void LowerBinaryOp(Node* node, SimdType input_rep_type, const Operator* op, void LowerBinaryOp(Node* node, SimdType input_rep_type, const Operator* op,
bool not_horizontal = true); bool not_horizontal = true);
Node* ConstructPhiForComparison(Diamond d, SimdType rep_type, int true_value,
int false_value);
void LowerCompareOp(Node* node, SimdType input_rep_type, const Operator* op, void LowerCompareOp(Node* node, SimdType input_rep_type, const Operator* op,
bool invert_inputs = false); bool invert_inputs = false);
Node* FixUpperBits(Node* input, int32_t shift); Node* FixUpperBits(Node* input, int32_t shift);
......
...@@ -1103,7 +1103,7 @@ WASM_SIMD_TEST_NO_LOWERING(I64x2GeU) { ...@@ -1103,7 +1103,7 @@ WASM_SIMD_TEST_NO_LOWERING(I64x2GeU) {
} }
#endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_S390X #endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_S390X
WASM_SIMD_TEST_NO_LOWERING(F64x2Splat) { WASM_SIMD_TEST(F64x2Splat) {
WasmRunner<int32_t, double> r(execution_tier, lower_simd); WasmRunner<int32_t, double> r(execution_tier, lower_simd);
// Set up a global to hold output vector. // Set up a global to hold output vector.
double* g = r.builder().AddGlobal<double>(kWasmS128); double* g = r.builder().AddGlobal<double>(kWasmS128);
...@@ -1125,7 +1125,7 @@ WASM_SIMD_TEST_NO_LOWERING(F64x2Splat) { ...@@ -1125,7 +1125,7 @@ WASM_SIMD_TEST_NO_LOWERING(F64x2Splat) {
} }
} }
WASM_SIMD_TEST_NO_LOWERING(F64x2ExtractLane) { WASM_SIMD_TEST(F64x2ExtractLane) {
WasmRunner<double, double> r(execution_tier, lower_simd); WasmRunner<double, double> r(execution_tier, lower_simd);
byte param1 = 0; byte param1 = 0;
byte temp1 = r.AllocateLocal(kWasmF64); byte temp1 = r.AllocateLocal(kWasmF64);
...@@ -1147,7 +1147,7 @@ WASM_SIMD_TEST_NO_LOWERING(F64x2ExtractLane) { ...@@ -1147,7 +1147,7 @@ WASM_SIMD_TEST_NO_LOWERING(F64x2ExtractLane) {
} }
} }
WASM_SIMD_TEST_NO_LOWERING(F64x2ReplaceLane) { WASM_SIMD_TEST(F64x2ReplaceLane) {
WasmRunner<int32_t> r(execution_tier, lower_simd); WasmRunner<int32_t> r(execution_tier, lower_simd);
// Set up globals to hold input/output vector. // Set up globals to hold input/output vector.
double* g0 = r.builder().AddGlobal<double>(kWasmS128); double* g0 = r.builder().AddGlobal<double>(kWasmS128);
...@@ -1308,15 +1308,15 @@ void RunF64x2UnOpTest(TestExecutionTier execution_tier, LowerSimd lower_simd, ...@@ -1308,15 +1308,15 @@ void RunF64x2UnOpTest(TestExecutionTier execution_tier, LowerSimd lower_simd,
} }
} }
WASM_SIMD_TEST_NO_LOWERING(F64x2Abs) { WASM_SIMD_TEST(F64x2Abs) {
RunF64x2UnOpTest(execution_tier, lower_simd, kExprF64x2Abs, std::abs); RunF64x2UnOpTest(execution_tier, lower_simd, kExprF64x2Abs, std::abs);
} }
WASM_SIMD_TEST_NO_LOWERING(F64x2Neg) { WASM_SIMD_TEST(F64x2Neg) {
RunF64x2UnOpTest(execution_tier, lower_simd, kExprF64x2Neg, Negate); RunF64x2UnOpTest(execution_tier, lower_simd, kExprF64x2Neg, Negate);
} }
WASM_SIMD_TEST_NO_LOWERING(F64x2Sqrt) { WASM_SIMD_TEST(F64x2Sqrt) {
RunF64x2UnOpTest(execution_tier, lower_simd, kExprF64x2Sqrt, Sqrt); RunF64x2UnOpTest(execution_tier, lower_simd, kExprF64x2Sqrt, Sqrt);
} }
...@@ -1393,19 +1393,19 @@ void RunF64x2BinOpTest(TestExecutionTier execution_tier, LowerSimd lower_simd, ...@@ -1393,19 +1393,19 @@ void RunF64x2BinOpTest(TestExecutionTier execution_tier, LowerSimd lower_simd,
#undef FOR_FLOAT64_NAN_INPUTS #undef FOR_FLOAT64_NAN_INPUTS
WASM_SIMD_TEST_NO_LOWERING(F64x2Add) { WASM_SIMD_TEST(F64x2Add) {
RunF64x2BinOpTest(execution_tier, lower_simd, kExprF64x2Add, Add); RunF64x2BinOpTest(execution_tier, lower_simd, kExprF64x2Add, Add);
} }
WASM_SIMD_TEST_NO_LOWERING(F64x2Sub) { WASM_SIMD_TEST(F64x2Sub) {
RunF64x2BinOpTest(execution_tier, lower_simd, kExprF64x2Sub, Sub); RunF64x2BinOpTest(execution_tier, lower_simd, kExprF64x2Sub, Sub);
} }
WASM_SIMD_TEST_NO_LOWERING(F64x2Mul) { WASM_SIMD_TEST(F64x2Mul) {
RunF64x2BinOpTest(execution_tier, lower_simd, kExprF64x2Mul, Mul); RunF64x2BinOpTest(execution_tier, lower_simd, kExprF64x2Mul, Mul);
} }
WASM_SIMD_TEST_NO_LOWERING(F64x2Div) { WASM_SIMD_TEST(F64x2Div) {
RunF64x2BinOpTest(execution_tier, lower_simd, kExprF64x2Div, Div); RunF64x2BinOpTest(execution_tier, lower_simd, kExprF64x2Div, Div);
} }
...@@ -1462,35 +1462,35 @@ void RunF64x2CompareOpTest(TestExecutionTier execution_tier, ...@@ -1462,35 +1462,35 @@ void RunF64x2CompareOpTest(TestExecutionTier execution_tier,
} }
} }
WASM_SIMD_TEST_NO_LOWERING(F64x2Eq) { WASM_SIMD_TEST(F64x2Eq) {
RunF64x2CompareOpTest(execution_tier, lower_simd, kExprF64x2Eq, Equal); RunF64x2CompareOpTest(execution_tier, lower_simd, kExprF64x2Eq, Equal);
} }
WASM_SIMD_TEST_NO_LOWERING(F64x2Ne) { WASM_SIMD_TEST(F64x2Ne) {
RunF64x2CompareOpTest(execution_tier, lower_simd, kExprF64x2Ne, NotEqual); RunF64x2CompareOpTest(execution_tier, lower_simd, kExprF64x2Ne, NotEqual);
} }
WASM_SIMD_TEST_NO_LOWERING(F64x2Gt) { WASM_SIMD_TEST(F64x2Gt) {
RunF64x2CompareOpTest(execution_tier, lower_simd, kExprF64x2Gt, Greater); RunF64x2CompareOpTest(execution_tier, lower_simd, kExprF64x2Gt, Greater);
} }
WASM_SIMD_TEST_NO_LOWERING(F64x2Ge) { WASM_SIMD_TEST(F64x2Ge) {
RunF64x2CompareOpTest(execution_tier, lower_simd, kExprF64x2Ge, GreaterEqual); RunF64x2CompareOpTest(execution_tier, lower_simd, kExprF64x2Ge, GreaterEqual);
} }
WASM_SIMD_TEST_NO_LOWERING(F64x2Lt) { WASM_SIMD_TEST(F64x2Lt) {
RunF64x2CompareOpTest(execution_tier, lower_simd, kExprF64x2Lt, Less); RunF64x2CompareOpTest(execution_tier, lower_simd, kExprF64x2Lt, Less);
} }
WASM_SIMD_TEST_NO_LOWERING(F64x2Le) { WASM_SIMD_TEST(F64x2Le) {
RunF64x2CompareOpTest(execution_tier, lower_simd, kExprF64x2Le, LessEqual); RunF64x2CompareOpTest(execution_tier, lower_simd, kExprF64x2Le, LessEqual);
} }
WASM_SIMD_TEST_NO_LOWERING(F64x2Min) { WASM_SIMD_TEST(F64x2Min) {
RunF64x2BinOpTest(execution_tier, lower_simd, kExprF64x2Min, JSMin); RunF64x2BinOpTest(execution_tier, lower_simd, kExprF64x2Min, JSMin);
} }
WASM_SIMD_TEST_NO_LOWERING(F64x2Max) { WASM_SIMD_TEST(F64x2Max) {
RunF64x2BinOpTest(execution_tier, lower_simd, kExprF64x2Max, JSMax); RunF64x2BinOpTest(execution_tier, lower_simd, kExprF64x2Max, JSMax);
} }
......
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