From 881cece8de4991b94aa82c80972531c04fdd29af Mon Sep 17 00:00:00 2001 From: "bmeurer@chromium.org" Date: Thu, 6 Nov 2014 06:13:10 +0000 Subject: [PATCH] [turbofan] Transform x * -1.0 to -0.0 - x. TEST=msjunit/asm,unittests R=jarin@chromium.org Review URL: https://codereview.chromium.org/683753004 Cr-Commit-Position: refs/heads/master@{#25176} git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@25176 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/compiler/machine-operator-reducer.cc | 6 ++++ test/mjsunit/asm/float64mul.js | 33 +++++++++++++++++++ .../machine-operator-reducer-unittest.cc | 21 ++++++++++++ test/unittests/compiler/node-test-utils.cc | 1 + test/unittests/compiler/node-test-utils.h | 2 ++ 5 files changed, 63 insertions(+) create mode 100644 test/mjsunit/asm/float64mul.js diff --git a/src/compiler/machine-operator-reducer.cc b/src/compiler/machine-operator-reducer.cc index d1a275d56a..900fadfe50 100644 --- a/src/compiler/machine-operator-reducer.cc +++ b/src/compiler/machine-operator-reducer.cc @@ -441,6 +441,12 @@ Reduction MachineOperatorReducer::Reduce(Node* node) { } case IrOpcode::kFloat64Mul: { Float64BinopMatcher m(node); + if (m.right().Is(-1)) { // x * -1.0 => -0.0 - x + node->set_op(machine()->Float64Sub()); + node->ReplaceInput(0, Float64Constant(-0.0)); + node->ReplaceInput(1, m.left().node()); + return Changed(node); + } if (m.right().Is(1)) return Replace(m.left().node()); // x * 1.0 => x if (m.right().IsNaN()) { // x * NaN => NaN return Replace(m.right().node()); diff --git a/test/mjsunit/asm/float64mul.js b/test/mjsunit/asm/float64mul.js new file mode 100644 index 0000000000..3896ec4f45 --- /dev/null +++ b/test/mjsunit/asm/float64mul.js @@ -0,0 +1,33 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +function Module(stdlib, foreign, heap) { + "use asm"; + function f1(i) { + i = +i; + return +(i * -1); + } + function f2(i) { + i = +i; + return +(-1 * i); + } + return { f1: f1, f2: f2 }; +} + +var m = Module(this, {}, new ArrayBuffer(64 * 1024)); + +assertEquals(NaN, m.f1(NaN)); +assertEquals(NaN, m.f2(NaN)); +assertEquals(Infinity, 1 / m.f1(-0)); +assertEquals(Infinity, 1 / m.f2(-0)); +assertEquals(Infinity, m.f1(-Infinity)); +assertEquals(Infinity, m.f2(-Infinity)); +assertEquals(-Infinity, 1 / m.f1(0)); +assertEquals(-Infinity, 1 / m.f2(0)); +assertEquals(-Infinity, m.f1(Infinity)); +assertEquals(-Infinity, m.f2(Infinity)); +for (var i = -2147483648; i < 2147483648; i += 3999777) { + assertEquals(-i, m.f1(i)); + assertEquals(-i, m.f2(i)); +} diff --git a/test/unittests/compiler/machine-operator-reducer-unittest.cc b/test/unittests/compiler/machine-operator-reducer-unittest.cc index 268afc4b27..d811808adf 100644 --- a/test/unittests/compiler/machine-operator-reducer-unittest.cc +++ b/test/unittests/compiler/machine-operator-reducer-unittest.cc @@ -1106,6 +1106,27 @@ TEST_F(MachineOperatorReducerTest, Uint32LessThanWithWord32Sar) { } +// ----------------------------------------------------------------------------- +// Float64Mul + + +TEST_F(MachineOperatorReducerTest, Float64MulWithMinusOne) { + Node* const p0 = Parameter(0); + { + Reduction r = Reduce( + graph()->NewNode(machine()->Float64Mul(), p0, Float64Constant(-1.0))); + ASSERT_TRUE(r.Changed()); + EXPECT_THAT(r.replacement(), IsFloat64Sub(IsFloat64Constant(-0.0), p0)); + } + { + Reduction r = Reduce( + graph()->NewNode(machine()->Float64Mul(), Float64Constant(-1.0), p0)); + ASSERT_TRUE(r.Changed()); + EXPECT_THAT(r.replacement(), IsFloat64Sub(IsFloat64Constant(-0.0), p0)); + } +} + + // ----------------------------------------------------------------------------- // Store diff --git a/test/unittests/compiler/node-test-utils.cc b/test/unittests/compiler/node-test-utils.cc index 5f1dea3886..fde7f03c3c 100644 --- a/test/unittests/compiler/node-test-utils.cc +++ b/test/unittests/compiler/node-test-utils.cc @@ -1040,6 +1040,7 @@ IS_BINOP_MATCHER(Int32MulHigh) IS_BINOP_MATCHER(Int32LessThan) IS_BINOP_MATCHER(Uint32LessThan) IS_BINOP_MATCHER(Uint32LessThanOrEqual) +IS_BINOP_MATCHER(Float64Sub) #undef IS_BINOP_MATCHER diff --git a/test/unittests/compiler/node-test-utils.h b/test/unittests/compiler/node-test-utils.h index 89fcc4b87c..870d55513d 100644 --- a/test/unittests/compiler/node-test-utils.h +++ b/test/unittests/compiler/node-test-utils.h @@ -156,6 +156,8 @@ Matcher IsChangeUint32ToUint64(const Matcher& input_matcher); Matcher IsTruncateFloat64ToFloat32(const Matcher& input_matcher); Matcher IsTruncateFloat64ToInt32(const Matcher& input_matcher); Matcher IsTruncateInt64ToInt32(const Matcher& input_matcher); +Matcher IsFloat64Sub(const Matcher& lhs_matcher, + const Matcher& rhs_matcher); Matcher IsFloat64Sqrt(const Matcher& input_matcher); Matcher IsFloat64Floor(const Matcher& input_matcher); Matcher IsFloat64Ceil(const Matcher& input_matcher);