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.