| Index: src/compiler/machine-operator-reducer.cc
|
| diff --git a/src/compiler/machine-operator-reducer.cc b/src/compiler/machine-operator-reducer.cc
|
| index 86e677d8ee69e501218eee8f24a5806e590db84b..b70eef5ccf0a44ca8f5989797a7af05b8d28d31f 100644
|
| --- a/src/compiler/machine-operator-reducer.cc
|
| +++ b/src/compiler/machine-operator-reducer.cc
|
| @@ -1008,16 +1008,36 @@ Reduction MachineOperatorReducer::ReduceFloat64InsertHighWord32(Node* node) {
|
| }
|
|
|
|
|
| +namespace {
|
| +
|
| +bool IsFloat64RepresentableAsFloat32(const Float64Matcher& m) {
|
| + if (m.HasValue()) {
|
| + double v = m.Value();
|
| + float fv = static_cast<float>(v);
|
| + return static_cast<double>(fv) == v;
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +
|
| 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.
|
| + // the original Float32s, so we can ignore the conversions. We can also reduce
|
| + // comparisons of converted Float64 values against constants that can be
|
| + // represented exactly as Float32.
|
| Float64BinopMatcher m(node);
|
| - if (m.left().IsChangeFloat32ToFloat64() &&
|
| - m.right().IsChangeFloat32ToFloat64()) {
|
| + if ((m.left().IsChangeFloat32ToFloat64() &&
|
| + m.right().IsChangeFloat32ToFloat64()) ||
|
| + (m.left().IsChangeFloat32ToFloat64() &&
|
| + IsFloat64RepresentableAsFloat32(m.right())) ||
|
| + (IsFloat64RepresentableAsFloat32(m.left()) &&
|
| + m.right().IsChangeFloat32ToFloat64())) {
|
| switch (node->opcode()) {
|
| case IrOpcode::kFloat64Equal:
|
| node->set_op(machine()->Float32Equal());
|
| @@ -1031,8 +1051,14 @@ Reduction MachineOperatorReducer::ReduceFloat64Compare(Node* node) {
|
| default:
|
| return NoChange();
|
| }
|
| - node->ReplaceInput(0, m.left().InputAt(0));
|
| - node->ReplaceInput(1, m.right().InputAt(0));
|
| + node->ReplaceInput(
|
| + 0, m.left().HasValue()
|
| + ? Float32Constant(static_cast<float>(m.left().Value()))
|
| + : m.left().InputAt(0));
|
| + node->ReplaceInput(
|
| + 1, m.right().HasValue()
|
| + ? Float32Constant(static_cast<float>(m.right().Value()))
|
| + : m.right().InputAt(0));
|
| return Changed(node);
|
| }
|
| return NoChange();
|
|
|