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.