Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(777)

Unified Diff: src/compiler/simd-scalar-lowering.cc

Issue 2718323003: [wasm]implement simd lowering for f32x4->i32x4, i32x4 min/max and shift instructions (Closed)
Patch Set: comments Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/simd-scalar-lowering.h ('k') | test/cctest/wasm/test-run-wasm-simd.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/simd-scalar-lowering.cc
diff --git a/src/compiler/simd-scalar-lowering.cc b/src/compiler/simd-scalar-lowering.cc
index cfa46c3cafe817c92ee61c462928a8aa67fddbff..8e1bf81917713df13fe64db136c2b014119a15dc 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) \
@@ -115,11 +121,20 @@ void SimdScalarLowering::SetLoweredType(Node* node, Node* output) {
}
#undef CASE_STMT
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;
+ switch (output->opcode()) {
+ case IrOpcode::kFloat32x4FromInt32x4:
+ case IrOpcode::kFloat32x4FromUint32x4: {
+ replacements_[node->id()].type = SimdType::kInt32;
+ break;
+ }
+ case IrOpcode::kInt32x4FromFloat32x4:
+ case IrOpcode::kUint32x4FromFloat32x4: {
+ replacements_[node->id()].type = SimdType::kFloat32;
+ break;
+ }
+ default: {
+ replacements_[node->id()].type = replacements_[output->id()].type;
+ }
}
}
}
@@ -264,6 +279,75 @@ 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));
+ 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 +506,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);
@@ -444,6 +544,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()); \
« no previous file with comments | « src/compiler/simd-scalar-lowering.h ('k') | test/cctest/wasm/test-run-wasm-simd.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698