Commit ad7f35c4 authored by martyn.capewell's avatar martyn.capewell Committed by Commit bot

[turbofan] Reduce Float64 comparison to Float32.

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

Review URL: https://codereview.chromium.org/1235663002

Cr-Commit-Position: refs/heads/master@{#29586}
parent f91119c4
......@@ -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();
}
......
......@@ -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_; }
......
......@@ -1437,6 +1437,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
......
......@@ -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)
......
......@@ -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,
......
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