Commit 05749d87 authored by Ng Zhi An's avatar Ng Zhi An Committed by Commit Bot

[wasm-simd][scalar-lowering] Fix all_true lowering

all_true requires the input to be of the respective type, but the
final result is always a Int32x4 with a single node. So keep
the replacement type of all_true (and any_true) nodes to be Int32x4,
and use a helper method to decide what SimdType the input should
be replaced with.

Also split up any_true and all_true for readability.

Bug: v8:10507
Change-Id: I58ca50ffffcbca3ec77bbae1371ddd179925fc96
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2405803Reviewed-by: 's avatarBill Budge <bbudge@chromium.org>
Commit-Queue: Zhi An Ng <zhin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#69890}
parent 863c2cb4
...@@ -1171,6 +1171,28 @@ void SimdScalarLowering::LowerBitMaskOp(Node* node, SimdType rep_type, ...@@ -1171,6 +1171,28 @@ void SimdScalarLowering::LowerBitMaskOp(Node* node, SimdType rep_type,
ReplaceNode(node, rep_node, 1); ReplaceNode(node, rep_node, 1);
} }
void SimdScalarLowering::LowerAllTrueOp(Node* node, SimdType rep_type) {
// AllTrue ops require the input to be of a particular SimdType, but the op
// itself is always replaced by a Int32x4 with 1 node.
int num_lanes = NumLanes(rep_type);
DCHECK_EQ(1, node->InputCount());
Node** rep = GetReplacementsWithType(node->InputAt(0), rep_type);
Node** rep_node = zone()->NewArray<Node*>(num_lanes);
Node* zero = mcgraph_->Int32Constant(0);
Node* tmp_result = mcgraph_->Int32Constant(1);
for (int i = 0; i < num_lanes; ++i) {
Diamond d(graph(), common(),
graph()->NewNode(machine()->Word32Equal(), rep[i], zero));
tmp_result = d.Phi(MachineRepresentation::kWord32, zero, tmp_result);
}
rep_node[0] = tmp_result;
for (int i = 1; i < num_lanes; ++i) {
rep_node[i] = nullptr;
}
ReplaceNode(node, rep_node, num_lanes);
}
void SimdScalarLowering::LowerNode(Node* node) { void SimdScalarLowering::LowerNode(Node* node) {
SimdType rep_type = ReplacementType(node); SimdType rep_type = ReplacementType(node);
int num_lanes = NumLanes(rep_type); int num_lanes = NumLanes(rep_type);
...@@ -1981,45 +2003,22 @@ void SimdScalarLowering::LowerNode(Node* node) { ...@@ -1981,45 +2003,22 @@ void SimdScalarLowering::LowerNode(Node* node) {
break; break;
} }
case IrOpcode::kV32x4AnyTrue: case IrOpcode::kV32x4AnyTrue:
case IrOpcode::kV32x4AllTrue:
case IrOpcode::kV16x8AnyTrue: case IrOpcode::kV16x8AnyTrue:
case IrOpcode::kV16x8AllTrue: case IrOpcode::kV8x16AnyTrue: {
case IrOpcode::kV8x16AnyTrue:
case IrOpcode::kV8x16AllTrue: {
DCHECK_EQ(1, node->InputCount()); DCHECK_EQ(1, node->InputCount());
SimdType input_rep_type = ReplacementType(node->InputAt(0)); // AnyTrue always returns a I32x4, and can work with inputs of any shape,
Node** rep; // but we still need GetReplacementsWithType if input is float.
// If the input is a SIMD float, bitcast it to a SIMD int of the same DCHECK_EQ(ReplacementType(node), SimdType::kInt32x4);
// shape, because the comparisons below use Word32. Node** reps = GetReplacementsWithType(node->InputAt(0), rep_type);
if (input_rep_type == SimdType::kFloat32x4) {
// TODO(v8:9418): f64x2 lowering is not implemented yet.
rep = GetReplacementsWithType(node->InputAt(0), SimdType::kInt32x4);
} else {
rep = GetReplacements(node->InputAt(0));
}
int input_num_lanes = NumLanes(input_rep_type);
Node** rep_node = zone()->NewArray<Node*>(num_lanes); Node** rep_node = zone()->NewArray<Node*>(num_lanes);
Node* true_node = mcgraph_->Int32Constant(1); Node* true_node = mcgraph_->Int32Constant(1);
Node* false_node = mcgraph_->Int32Constant(0); Node* zero = mcgraph_->Int32Constant(0);
Node* tmp_result = false_node; Node* tmp_result = zero;
if (node->opcode() == IrOpcode::kV32x4AllTrue || for (int i = 0; i < num_lanes; ++i) {
node->opcode() == IrOpcode::kV16x8AllTrue || Diamond d(graph(), common(),
node->opcode() == IrOpcode::kV8x16AllTrue) { graph()->NewNode(machine()->Word32Equal(), reps[i], zero));
tmp_result = true_node; tmp_result =
} d.Phi(MachineRepresentation::kWord32, tmp_result, true_node);
for (int i = 0; i < input_num_lanes; ++i) {
Diamond is_false(
graph(), common(),
graph()->NewNode(machine()->Word32Equal(), rep[i], false_node));
if (node->opcode() == IrOpcode::kV32x4AllTrue ||
node->opcode() == IrOpcode::kV16x8AllTrue ||
node->opcode() == IrOpcode::kV8x16AllTrue) {
tmp_result = is_false.Phi(MachineRepresentation::kWord32, false_node,
tmp_result);
} else {
tmp_result = is_false.Phi(MachineRepresentation::kWord32, tmp_result,
true_node);
}
} }
rep_node[0] = tmp_result; rep_node[0] = tmp_result;
for (int i = 1; i < num_lanes; ++i) { for (int i = 1; i < num_lanes; ++i) {
...@@ -2028,6 +2027,18 @@ void SimdScalarLowering::LowerNode(Node* node) { ...@@ -2028,6 +2027,18 @@ void SimdScalarLowering::LowerNode(Node* node) {
ReplaceNode(node, rep_node, num_lanes); ReplaceNode(node, rep_node, num_lanes);
break; break;
} }
case IrOpcode::kV32x4AllTrue: {
LowerAllTrueOp(node, SimdType::kInt32x4);
break;
}
case IrOpcode::kV16x8AllTrue: {
LowerAllTrueOp(node, SimdType::kInt16x8);
break;
}
case IrOpcode::kV8x16AllTrue: {
LowerAllTrueOp(node, SimdType::kInt8x16);
break;
}
case IrOpcode::kI8x16BitMask: { case IrOpcode::kI8x16BitMask: {
LowerBitMaskOp(node, rep_type, 7); LowerBitMaskOp(node, rep_type, 7);
break; break;
......
...@@ -116,6 +116,7 @@ class SimdScalarLowering { ...@@ -116,6 +116,7 @@ class SimdScalarLowering {
void LowerNotEqual(Node* node, SimdType input_rep_type, const Operator* op); void LowerNotEqual(Node* node, SimdType input_rep_type, const Operator* op);
MachineType MachineTypeFrom(SimdType simdType); MachineType MachineTypeFrom(SimdType simdType);
void LowerBitMaskOp(Node* node, SimdType rep_type, int msb_index); void LowerBitMaskOp(Node* node, SimdType rep_type, int msb_index);
void LowerAllTrueOp(Node* node, SimdType rep_type);
MachineGraph* const mcgraph_; MachineGraph* const mcgraph_;
NodeMarker<State> state_; NodeMarker<State> state_;
......
...@@ -145,6 +145,48 @@ WASM_SIMD_TEST(F32x4_S128Const) { ...@@ -145,6 +145,48 @@ WASM_SIMD_TEST(F32x4_S128Const) {
CHECK_EQ(1.0, r.Call()); CHECK_EQ(1.0, r.Call());
} }
WASM_SIMD_TEST(AllTrue_DifferentShapes) {
// Test all_true lowring with splats of different shapes.
{
WasmRunner<int32_t, int32_t> r(execution_tier, lower_simd);
BUILD(r, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(0)),
WASM_SIMD_OP(kExprV8x16AllTrue));
CHECK_EQ(0, r.Call(0x00FF00FF));
}
{
WasmRunner<int32_t, int32_t> r(execution_tier, lower_simd);
BUILD(r, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(0)),
WASM_SIMD_OP(kExprV16x8AllTrue));
CHECK_EQ(0, r.Call(0x000000FF));
}
}
WASM_SIMD_TEST(AnyTrue_DifferentShapes) {
// Test any_true lowring with splats of different shapes.
{
WasmRunner<int32_t, int32_t> r(execution_tier, lower_simd);
BUILD(r, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(0)),
WASM_SIMD_OP(kExprV8x16AnyTrue));
CHECK_EQ(0, r.Call(0x00000000));
}
{
WasmRunner<int32_t, int32_t> r(execution_tier, lower_simd);
BUILD(r, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(0)),
WASM_SIMD_OP(kExprV16x8AnyTrue));
CHECK_EQ(1, r.Call(0x000000FF));
}
}
} // namespace test_run_wasm_simd } // namespace test_run_wasm_simd
} // namespace wasm } // namespace wasm
} // namespace internal } // namespace internal
......
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