Reviewers: Sven Panne,

Message:
PTAL

Description:
[arm] Fix recognition of VNEG.

TEST=mjsunit,unittests

Please review this at https://codereview.chromium.org/762493006/

Base URL: https://chromium.googlesource.com/v8/v8.git@master

Affected files (+41, -13 lines):
  M src/compiler/arm/instruction-selector-arm.cc
  M src/compiler/node-matchers.h
  M test/mjsunit/asm/float64mul.js
  M test/unittests/compiler/arm/instruction-selector-arm-unittest.cc


Index: src/compiler/arm/instruction-selector-arm.cc
diff --git a/src/compiler/arm/instruction-selector-arm.cc b/src/compiler/arm/instruction-selector-arm.cc index 6e1e0846da4217fa7ef90aa990fa4d2a75aca47a..7d3243e614bcc4665d9354ac8c38353630477e7e 100644
--- a/src/compiler/arm/instruction-selector-arm.cc
+++ b/src/compiler/arm/instruction-selector-arm.cc
@@ -854,16 +854,16 @@ void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) {

 void InstructionSelector::VisitFloat64Add(Node* node) {
   ArmOperandGenerator g(this);
-  Int32BinopMatcher m(node);
+  Float64BinopMatcher m(node);
   if (m.left().IsFloat64Mul() && CanCover(node, m.left().node())) {
-    Int32BinopMatcher mleft(m.left().node());
+    Float64BinopMatcher mleft(m.left().node());
     Emit(kArmVmlaF64, g.DefineSameAsFirst(node),
g.UseRegister(m.right().node()), g.UseRegister(mleft.left().node()),
          g.UseRegister(mleft.right().node()));
     return;
   }
   if (m.right().IsFloat64Mul() && CanCover(node, m.right().node())) {
-    Int32BinopMatcher mright(m.right().node());
+    Float64BinopMatcher mright(m.right().node());
Emit(kArmVmlaF64, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()),
          g.UseRegister(mright.left().node()),
          g.UseRegister(mright.right().node()));
@@ -875,9 +875,14 @@ void InstructionSelector::VisitFloat64Add(Node* node) {

 void InstructionSelector::VisitFloat64Sub(Node* node) {
   ArmOperandGenerator g(this);
-  Int32BinopMatcher m(node);
+  Float64BinopMatcher m(node);
+  if (m.left().IsMinusZero()) {
+    Emit(kArmVnegF64, g.DefineAsRegister(node),
+         g.UseRegister(m.right().node()));
+    return;
+  }
   if (m.right().IsFloat64Mul() && CanCover(node, m.right().node())) {
-    Int32BinopMatcher mright(m.right().node());
+    Float64BinopMatcher mright(m.right().node());
Emit(kArmVmlsF64, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()),
          g.UseRegister(mright.left().node()),
          g.UseRegister(mright.right().node()));
@@ -888,13 +893,7 @@ void InstructionSelector::VisitFloat64Sub(Node* node) {


 void InstructionSelector::VisitFloat64Mul(Node* node) {
-  ArmOperandGenerator g(this);
-  Float64BinopMatcher m(node);
-  if (m.right().Is(-1.0)) {
- Emit(kArmVnegF64, g.DefineAsRegister(node), g.UseRegister(m.left().node()));
-  } else {
-    VisitRRRFloat64(this, kArmVmulF64, node);
-  }
+  VisitRRRFloat64(this, kArmVmulF64, node);
 }


Index: src/compiler/node-matchers.h
diff --git a/src/compiler/node-matchers.h b/src/compiler/node-matchers.h
index ebb772210cd6e2ad6db6ed668b14c2010b1d3287..a1d8b343fa923381d5878868afa3a94d6eb6017a 100644
--- a/src/compiler/node-matchers.h
+++ b/src/compiler/node-matchers.h
@@ -104,6 +104,9 @@ template <typename T, IrOpcode::Value kOpcode>
 struct FloatMatcher FINAL : public ValueMatcher<T, kOpcode> {
   explicit FloatMatcher(Node* node) : ValueMatcher<T, kOpcode>(node) {}

+  bool IsMinusZero() const {
+    return this->Is(0.0) && std::signbit(this->Value());
+  }
bool IsNaN() const { return this->HasValue() && std::isnan(this->Value()); }
 };

@@ -167,6 +170,7 @@ typedef BinopMatcher<UintPtrMatcher, UintPtrMatcher> UintPtrBinopMatcher;
 typedef BinopMatcher<Float64Matcher, Float64Matcher> Float64BinopMatcher;
 typedef BinopMatcher<NumberMatcher, NumberMatcher> NumberBinopMatcher;

+
 template <class BinopMatcher, IrOpcode::Value kAddOpcode,
           IrOpcode::Value kMulOpcode, IrOpcode::Value kShiftOpcode>
 struct AddMatcher : public BinopMatcher {
Index: test/mjsunit/asm/float64mul.js
diff --git a/test/mjsunit/asm/float64mul.js b/test/mjsunit/asm/float64mul.js
index 3896ec4f45c5b3011b12c6ea912a77562cfa4655..9cd95823275d7dd999fdbfc6ee356ad867e47333 100644
--- a/test/mjsunit/asm/float64mul.js
+++ b/test/mjsunit/asm/float64mul.js
@@ -12,22 +12,32 @@ function Module(stdlib, foreign, heap) {
     i = +i;
     return +(-1 * i);
   }
-  return { f1: f1, f2: f2 };
+  function f3(i) {
+    i = +i;
+    return +(-i);
+  }
+  return { f1: f1, f2: f2, f3: f3 };
 }

 var m = Module(this, {}, new ArrayBuffer(64 * 1024));

 assertEquals(NaN, m.f1(NaN));
 assertEquals(NaN, m.f2(NaN));
+assertEquals(NaN, m.f3(NaN));
 assertEquals(Infinity, 1 / m.f1(-0));
 assertEquals(Infinity, 1 / m.f2(-0));
+assertEquals(Infinity, 1 / m.f3(-0));
 assertEquals(Infinity, m.f1(-Infinity));
 assertEquals(Infinity, m.f2(-Infinity));
+assertEquals(Infinity, m.f3(-Infinity));
 assertEquals(-Infinity, 1 / m.f1(0));
 assertEquals(-Infinity, 1 / m.f2(0));
+assertEquals(-Infinity, 1 / m.f3(0));
 assertEquals(-Infinity, m.f1(Infinity));
 assertEquals(-Infinity, m.f2(Infinity));
+assertEquals(-Infinity, m.f3(Infinity));
 for (var i = -2147483648; i < 2147483648; i += 3999777) {
   assertEquals(-i, m.f1(i));
   assertEquals(-i, m.f2(i));
+  assertEquals(-i, m.f3(i));
 }
Index: test/unittests/compiler/arm/instruction-selector-arm-unittest.cc
diff --git a/test/unittests/compiler/arm/instruction-selector-arm-unittest.cc b/test/unittests/compiler/arm/instruction-selector-arm-unittest.cc index f922d62b311ef5dac705eb431f893d7ac2b45af8..fbdf87a2b2f1b9fc77cc99a7dad57e49735702d5 100644
--- a/test/unittests/compiler/arm/instruction-selector-arm-unittest.cc
+++ b/test/unittests/compiler/arm/instruction-selector-arm-unittest.cc
@@ -1482,6 +1482,21 @@ INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
 // Miscellaneous.


+TEST_F(InstructionSelectorTest, Float64SubWithMinusZero) {
+  StreamBuilder m(this, kMachFloat64, kMachFloat64);
+  Node* const p0 = m.Parameter(0);
+  Node* const n = m.Float64Sub(m.Float64Constant(-0.0), p0);
+  m.Return(n);
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kArmVnegF64, s[0]->arch_opcode());
+  ASSERT_EQ(1U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  ASSERT_EQ(1U, s[0]->OutputCount());
+  EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+}
+
+
 TEST_F(InstructionSelectorTest, Int32AddWithInt32Mul) {
   {
     StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);


--
--
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.

Reply via email to