Chromium Code Reviews| Index: src/compiler/simd-scalar-lowering.cc |
| diff --git a/src/compiler/simd-scalar-lowering.cc b/src/compiler/simd-scalar-lowering.cc |
| index 3a1970318e02377757f98805f4f72c701e082cc2..5895952340d6a3f1bc11938ce38a295991b0e66b 100644 |
| --- a/src/compiler/simd-scalar-lowering.cc |
| +++ b/src/compiler/simd-scalar-lowering.cc |
| @@ -80,9 +80,15 @@ void SimdScalarLowering::LowerGraph() { |
| V(Int32x4Add) \ |
| V(Int32x4Sub) \ |
| V(Int32x4Mul) \ |
| + V(Int32x4Min) \ |
| + V(Int32x4Max) \ |
| + V(Uint32x4Min) \ |
| + V(Uint32x4Max) \ |
| V(Simd128And) \ |
| V(Simd128Or) \ |
| - V(Simd128Xor) |
| + V(Simd128Xor) \ |
| + V(Int32x4FromFloat32x4) \ |
| + V(Uint32x4FromFloat32x4) |
| #define FOREACH_FLOAT32X4_OPCODE(V) \ |
| V(Float32x4Splat) \ |
| @@ -118,6 +124,9 @@ void SimdScalarLowering::SetLoweredType(Node* node, Node* output) { |
| if (output->opcode() == IrOpcode::kFloat32x4FromInt32x4 || |
| output->opcode() == IrOpcode::kFloat32x4FromUint32x4) { |
| replacements_[node->id()].type = SimdType::kInt32; |
| + } else if (output->opcode() == IrOpcode::kInt32x4FromFloat32x4 || |
| + output->opcode() == IrOpcode::kUint32x4FromFloat32x4) { |
| + replacements_[node->id()].type = SimdType::kFloat32; |
| } else { |
| replacements_[node->id()].type = replacements_[output->id()].type; |
| } |
| @@ -264,6 +273,80 @@ void SimdScalarLowering::LowerUnaryOp(Node* node, SimdType input_rep_type, |
| ReplaceNode(node, rep_node); |
| } |
| +void SimdScalarLowering::LowerIntMinMax(Node* node, const Operator* op, |
| + bool is_max) { |
| + DCHECK(node->InputCount() == 2); |
| + Node** rep_left = GetReplacementsWithType(node->InputAt(0), SimdType::kInt32); |
| + Node** rep_right = |
| + GetReplacementsWithType(node->InputAt(1), SimdType::kInt32); |
| + Node* rep_node[kMaxLanes]; |
| + for (int i = 0; i < kMaxLanes; ++i) { |
| + Diamond d(graph(), common(), |
| + graph()->NewNode(op, rep_left[i], rep_right[i])); |
| + if (is_max) { |
| + rep_node[i] = |
| + d.Phi(MachineRepresentation::kWord32, rep_right[i], rep_left[i]); |
| + } else { |
| + rep_node[i] = |
| + d.Phi(MachineRepresentation::kWord32, rep_left[i], rep_right[i]); |
| + } |
| + } |
| + ReplaceNode(node, rep_node); |
| +} |
| + |
| +void SimdScalarLowering::LowerConvertFromFloat(Node* node, bool is_signed) { |
| + DCHECK(node->InputCount() == 1); |
| + Node** rep = GetReplacementsWithType(node->InputAt(0), SimdType::kFloat32); |
| + Node* rep_node[kMaxLanes]; |
| + Node* double_zero = graph()->NewNode(common()->Float64Constant(0.0)); |
| + Node* min = graph()->NewNode( |
| + common()->Float64Constant(static_cast<double>(is_signed ? kMinInt : 0))); |
| + Node* max = graph()->NewNode(common()->Float64Constant( |
| + static_cast<double>(is_signed ? kMaxInt : 0xffffffffu))); |
| + for (int i = 0; i < kMaxLanes; ++i) { |
| + Node* double_rep = |
| + graph()->NewNode(machine()->ChangeFloat32ToFloat64(), rep[i]); |
| + Diamond nan_d(graph(), common(), graph()->NewNode(machine()->Float64Equal(), |
| + double_rep, double_rep)); |
| + Node* temp = |
| + nan_d.Phi(MachineRepresentation::kFloat64, double_rep, double_zero); |
| + Diamond min_d(graph(), common(), |
| + graph()->NewNode(machine()->Float64LessThan(), temp, min)); |
| + temp = min_d.Phi(MachineRepresentation::kFloat64, min, temp); |
| + Diamond max_d(graph(), common(), |
| + graph()->NewNode(machine()->Float64LessThan(), max, temp)); |
| + // if (!machine()->Float32RoundTruncate().IsSupported()) { |
|
titzer
2017/03/01 09:40:28
Is this code ncessary? if not, then please remove
aseemgarg
2017/03/01 10:55:16
Removed. All bots are passing with this commented
|
| + // trunc = BuildF32Trunc(input); |
| + // } else { |
| + // trunc = |
| + // } |
| + temp = max_d.Phi(MachineRepresentation::kFloat64, max, temp); |
| + Node* trunc = |
| + graph()->NewNode(machine()->Float64RoundTruncate().op(), temp); |
| + if (is_signed) { |
| + rep_node[i] = graph()->NewNode(machine()->ChangeFloat64ToInt32(), trunc); |
| + } else { |
| + rep_node[i] = |
| + graph()->NewNode(machine()->TruncateFloat64ToUint32(), trunc); |
| + } |
| + } |
| + ReplaceNode(node, rep_node); |
| +} |
| + |
| +void SimdScalarLowering::LowerShiftOp(Node* node, const Operator* op) { |
| + static int32_t shift_mask = 0x1f; |
| + DCHECK_EQ(1, node->InputCount()); |
| + int32_t shift_amount = OpParameter<int32_t>(node); |
| + Node* shift_node = |
| + graph()->NewNode(common()->Int32Constant(shift_amount & shift_mask)); |
| + Node** rep = GetReplacementsWithType(node->InputAt(0), SimdType::kInt32); |
| + Node* rep_node[kMaxLanes]; |
| + for (int i = 0; i < kMaxLanes; ++i) { |
| + rep_node[i] = graph()->NewNode(op, rep[i], shift_node); |
| + } |
| + ReplaceNode(node, rep_node); |
| +} |
| + |
| void SimdScalarLowering::LowerNode(Node* node) { |
| SimdType rep_type = ReplacementType(node); |
| switch (node->opcode()) { |
| @@ -422,6 +505,22 @@ void SimdScalarLowering::LowerNode(Node* node) { |
| I32X4_BINOP_CASE(kSimd128Or, Word32Or) |
| I32X4_BINOP_CASE(kSimd128Xor, Word32Xor) |
| #undef I32X4_BINOP_CASE |
| + case IrOpcode::kInt32x4Max: { |
| + LowerIntMinMax(node, machine()->Int32LessThan(), true); |
| + break; |
| + } |
| + case IrOpcode::kInt32x4Min: { |
| + LowerIntMinMax(node, machine()->Int32LessThan(), false); |
| + break; |
| + } |
| + case IrOpcode::kUint32x4Max: { |
| + LowerIntMinMax(node, machine()->Uint32LessThan(), true); |
| + break; |
| + } |
| + case IrOpcode::kUint32x4Min: { |
| + LowerIntMinMax(node, machine()->Uint32LessThan(), false); |
| + break; |
| + } |
| case IrOpcode::kInt32x4Neg: { |
| DCHECK(node->InputCount() == 1); |
| Node** rep = GetReplacementsWithType(node->InputAt(0), rep_type); |
| @@ -446,6 +545,26 @@ void SimdScalarLowering::LowerNode(Node* node) { |
| ReplaceNode(node, rep_node); |
| break; |
| } |
| + case IrOpcode::kInt32x4FromFloat32x4: { |
| + LowerConvertFromFloat(node, true); |
| + break; |
| + } |
| + case IrOpcode::kUint32x4FromFloat32x4: { |
| + LowerConvertFromFloat(node, false); |
| + break; |
| + } |
| + case IrOpcode::kInt32x4ShiftLeftByScalar: { |
| + LowerShiftOp(node, machine()->Word32Shl()); |
| + break; |
| + } |
| + case IrOpcode::kInt32x4ShiftRightByScalar: { |
| + LowerShiftOp(node, machine()->Word32Sar()); |
| + break; |
| + } |
| + case IrOpcode::kUint32x4ShiftRightByScalar: { |
| + LowerShiftOp(node, machine()->Word32Shr()); |
| + break; |
| + } |
| #define F32X4_BINOP_CASE(name) \ |
| case IrOpcode::kFloat32x4##name: { \ |
| LowerBinaryOp(node, rep_type, machine()->Float32##name()); \ |