Reviewers: ulan, Benedikt Meurer,

Message:
This currently brings a little performance on the Jetstream gcc-loops benchmark, and seems like a cheap optimisation to make, but it may go away when benchmarks
are recompiled with better support for Float32 ops.

Description:
[turbofan] Reduce Float64 comparison to Float32

Reduce Float64 comparison to Float32 when both inputs are conversions from
Float32.

BUG=

Please review this at https://codereview.chromium.org/1235663002/

Base URL: https://chromium.googlesource.com/v8/v8.git@master

Affected files (+94, -0 lines):
  M src/compiler/machine-operator-reducer.h
  M src/compiler/machine-operator-reducer.cc
  M test/unittests/compiler/machine-operator-reducer-unittest.cc
  M test/unittests/compiler/node-test-utils.h
  M test/unittests/compiler/node-test-utils.cc


Index: src/compiler/machine-operator-reducer.cc
diff --git a/src/compiler/machine-operator-reducer.cc b/src/compiler/machine-operator-reducer.cc index 3ce59733ebaea08485912703ea8b498e84e56686..86e677d8ee69e501218eee8f24a5806e590db84b 100644
--- a/src/compiler/machine-operator-reducer.cc
+++ b/src/compiler/machine-operator-reducer.cc
@@ -439,6 +439,10 @@ Reduction MachineOperatorReducer::Reduce(Node* node) {
       return ReduceFloat64InsertHighWord32(node);
     case IrOpcode::kStore:
       return ReduceStore(node);
+    case IrOpcode::kFloat64Equal:
+    case IrOpcode::kFloat64LessThan:
+    case IrOpcode::kFloat64LessThanOrEqual:
+      return ReduceFloat64Compare(node);
     default:
       break;
   }
@@ -1004,6 +1008,37 @@ Reduction MachineOperatorReducer::ReduceFloat64InsertHighWord32(Node* node) {
 }


+Reduction MachineOperatorReducer::ReduceFloat64Compare(Node* node) {
+  DCHECK((IrOpcode::kFloat64Equal == node->opcode()) ||
+         (IrOpcode::kFloat64LessThan == node->opcode()) ||
+         (IrOpcode::kFloat64LessThanOrEqual == node->opcode()));
+ // As all Float32 values have an exact representation in Float64, comparing + // two Float64 values both converted from Float32 is equivalent to comparing
+  // the original Float32s, so we can ignore the conversions.
+  Float64BinopMatcher m(node);
+  if (m.left().IsChangeFloat32ToFloat64() &&
+      m.right().IsChangeFloat32ToFloat64()) {
+    switch (node->opcode()) {
+      case IrOpcode::kFloat64Equal:
+        node->set_op(machine()->Float32Equal());
+        break;
+      case IrOpcode::kFloat64LessThan:
+        node->set_op(machine()->Float32LessThan());
+        break;
+      case IrOpcode::kFloat64LessThanOrEqual:
+        node->set_op(machine()->Float32LessThanOrEqual());
+        break;
+      default:
+        return NoChange();
+    }
+    node->ReplaceInput(0, m.left().InputAt(0));
+    node->ReplaceInput(1, m.right().InputAt(0));
+    return Changed(node);
+  }
+  return NoChange();
+}
+
+
 CommonOperatorBuilder* MachineOperatorReducer::common() const {
   return jsgraph()->common();
 }
Index: src/compiler/machine-operator-reducer.h
diff --git a/src/compiler/machine-operator-reducer.h b/src/compiler/machine-operator-reducer.h index b0976b78d29e0771eecd99f5811bd4e6654af2bc..7f8ff1a5fd6bd33a70a653acefdfbdf31e823695 100644
--- a/src/compiler/machine-operator-reducer.h
+++ b/src/compiler/machine-operator-reducer.h
@@ -80,6 +80,7 @@ class MachineOperatorReducer final : public Reducer {
   Reduction ReduceWord32Or(Node* node);
   Reduction ReduceFloat64InsertLowWord32(Node* node);
   Reduction ReduceFloat64InsertHighWord32(Node* node);
+  Reduction ReduceFloat64Compare(Node* node);

   Graph* graph() const;
   JSGraph* jsgraph() const { return jsgraph_; }
Index: test/unittests/compiler/machine-operator-reducer-unittest.cc
diff --git a/test/unittests/compiler/machine-operator-reducer-unittest.cc b/test/unittests/compiler/machine-operator-reducer-unittest.cc index ce11fdef815232be74f581a36e8de72a0e50df9b..b14e9d392d8bb649376f8721de52f497c05568ab 100644
--- a/test/unittests/compiler/machine-operator-reducer-unittest.cc
+++ b/test/unittests/compiler/machine-operator-reducer-unittest.cc
@@ -1438,6 +1438,55 @@ TEST_F(MachineOperatorReducerTest, Float64InsertHighWord32WithConstant) {


// -----------------------------------------------------------------------------
+// Float64Equal
+
+
+TEST_F(MachineOperatorReducerTest, Float64EqualWithFloat32Conversions) {
+  Node* const p0 = Parameter(0);
+  Node* const p1 = Parameter(1);
+  Reduction const r = Reduce(graph()->NewNode(
+      machine()->Float64Equal(),
+      graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p0),
+      graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p1)));
+  ASSERT_TRUE(r.Changed());
+  EXPECT_THAT(r.replacement(), IsFloat32Equal(p0, p1));
+}
+
+
+// -----------------------------------------------------------------------------
+// Float64LessThan
+
+
+TEST_F(MachineOperatorReducerTest, Float64LessThanWithFloat32Conversions) {
+  Node* const p0 = Parameter(0);
+  Node* const p1 = Parameter(1);
+  Reduction const r = Reduce(graph()->NewNode(
+      machine()->Float64LessThan(),
+      graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p0),
+      graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p1)));
+  ASSERT_TRUE(r.Changed());
+  EXPECT_THAT(r.replacement(), IsFloat32LessThan(p0, p1));
+}
+
+
+// -----------------------------------------------------------------------------
+// Float64LessThanOrEqual
+
+
+TEST_F(MachineOperatorReducerTest,
+       Float64LessThanOrEqualWithFloat32Conversions) {
+  Node* const p0 = Parameter(0);
+  Node* const p1 = Parameter(1);
+  Reduction const r = Reduce(graph()->NewNode(
+      machine()->Float64LessThanOrEqual(),
+      graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p0),
+      graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p1)));
+  ASSERT_TRUE(r.Changed());
+  EXPECT_THAT(r.replacement(), IsFloat32LessThanOrEqual(p0, p1));
+}
+
+
+// -----------------------------------------------------------------------------
 // Store


Index: test/unittests/compiler/node-test-utils.cc
diff --git a/test/unittests/compiler/node-test-utils.cc b/test/unittests/compiler/node-test-utils.cc index 520ce0159e16d482578c466f92eca19409842acb..f5962ef2d3f96ec94643d7f90c98e5bfe5770c44 100644
--- a/test/unittests/compiler/node-test-utils.cc
+++ b/test/unittests/compiler/node-test-utils.cc
@@ -1832,6 +1832,9 @@ IS_BINOP_MATCHER(Uint32LessThan)
 IS_BINOP_MATCHER(Uint32LessThanOrEqual)
 IS_BINOP_MATCHER(Float32Max)
 IS_BINOP_MATCHER(Float32Min)
+IS_BINOP_MATCHER(Float32Equal)
+IS_BINOP_MATCHER(Float32LessThan)
+IS_BINOP_MATCHER(Float32LessThanOrEqual)
 IS_BINOP_MATCHER(Float64Max)
 IS_BINOP_MATCHER(Float64Min)
 IS_BINOP_MATCHER(Float64Sub)
Index: test/unittests/compiler/node-test-utils.h
diff --git a/test/unittests/compiler/node-test-utils.h b/test/unittests/compiler/node-test-utils.h index a64d9f009a2f977222c0216a6d9880b83c8a8078..c98a504cebbe0f19f481cbc3c9f46d240492115f 100644
--- a/test/unittests/compiler/node-test-utils.h
+++ b/test/unittests/compiler/node-test-utils.h
@@ -254,6 +254,12 @@ Matcher<Node*> IsFloat32Max(const Matcher<Node*>& lhs_matcher,
 Matcher<Node*> IsFloat32Min(const Matcher<Node*>& lhs_matcher,
                             const Matcher<Node*>& rhs_matcher);
 Matcher<Node*> IsFloat32Abs(const Matcher<Node*>& input_matcher);
+Matcher<Node*> IsFloat32Equal(const Matcher<Node*>& lhs_matcher,
+                              const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsFloat32LessThan(const Matcher<Node*>& lhs_matcher,
+                                 const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsFloat32LessThanOrEqual(const Matcher<Node*>& lhs_matcher,
+                                        const Matcher<Node*>& rhs_matcher);
 Matcher<Node*> IsFloat64Max(const Matcher<Node*>& lhs_matcher,
                             const Matcher<Node*>& rhs_matcher);
 Matcher<Node*> IsFloat64Min(const Matcher<Node*>& lhs_matcher,


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to