}
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());
--- /dev/null
+// 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));
+}
// -----------------------------------------------------------------------------
+// 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
IS_BINOP_MATCHER(Int32LessThan)
IS_BINOP_MATCHER(Uint32LessThan)
IS_BINOP_MATCHER(Uint32LessThanOrEqual)
+IS_BINOP_MATCHER(Float64Sub)
#undef IS_BINOP_MATCHER
Matcher<Node*> IsTruncateFloat64ToFloat32(const Matcher<Node*>& input_matcher);
Matcher<Node*> IsTruncateFloat64ToInt32(const Matcher<Node*>& input_matcher);
Matcher<Node*> IsTruncateInt64ToInt32(const Matcher<Node*>& input_matcher);
+Matcher<Node*> IsFloat64Sub(const Matcher<Node*>& lhs_matcher,
+ const Matcher<Node*>& rhs_matcher);
Matcher<Node*> IsFloat64Sqrt(const Matcher<Node*>& input_matcher);
Matcher<Node*> IsFloat64Floor(const Matcher<Node*>& input_matcher);
Matcher<Node*> IsFloat64Ceil(const Matcher<Node*>& input_matcher);