From 7a675e0e3be0fe1415c8243841fcbdff704dc32a Mon Sep 17 00:00:00 2001 From: bmeurer Date: Wed, 24 Jun 2015 02:15:19 -0700 Subject: [PATCH] [x64] Fix instruction selection for Word64Equal(Word64And, 0). This fixes a slight inconsistency in the InstructionSelector that basically disabled the optimization for things like ObjectIsSmi. R=jarin@chromium.org Review URL: https://codereview.chromium.org/1206773002 Cr-Commit-Position: refs/heads/master@{#29250} --- src/compiler/x64/instruction-selector-x64.cc | 42 +++++++++++++++------------- test/cctest/compiler/test-run-intrinsics.cc | 7 ++++- 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/src/compiler/x64/instruction-selector-x64.cc b/src/compiler/x64/instruction-selector-x64.cc index c841ace..839af8e 100644 --- a/src/compiler/x64/instruction-selector-x64.cc +++ b/src/compiler/x64/instruction-selector-x64.cc @@ -1313,9 +1313,27 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, case IrOpcode::kUint32LessThanOrEqual: cont.OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); return VisitWordCompare(this, value, kX64Cmp32, &cont); - case IrOpcode::kWord64Equal: + case IrOpcode::kWord64Equal: { cont.OverwriteAndNegateIfEqual(kEqual); + Int64BinopMatcher m(value); + if (m.right().Is(0)) { + // Try to combine the branch with a comparison. + Node* const user = m.node(); + Node* const value = m.left().node(); + if (CanCover(user, value)) { + switch (value->opcode()) { + case IrOpcode::kInt64Sub: + return VisitWord64Compare(this, value, &cont); + case IrOpcode::kWord64And: + return VisitWordCompare(this, value, kX64Test, &cont); + default: + break; + } + } + return VisitCompareZero(this, value, kX64Cmp, &cont); + } return VisitWord64Compare(this, value, &cont); + } case IrOpcode::kInt64LessThan: cont.OverwriteAndNegateIfEqual(kSignedLessThan); return VisitWord64Compare(this, value, &cont); @@ -1478,25 +1496,12 @@ void InstructionSelector::VisitUint32LessThanOrEqual(Node* node) { void InstructionSelector::VisitWord64Equal(Node* const node) { - Node* user = node; FlagsContinuation cont(kEqual, node); - Int64BinopMatcher m(user); + Int64BinopMatcher m(node); if (m.right().Is(0)) { - Node* value = m.left().node(); - - // Try to combine with comparisons against 0 by simply inverting the branch. - while (CanCover(user, value) && value->opcode() == IrOpcode::kWord64Equal) { - Int64BinopMatcher m(value); - if (m.right().Is(0)) { - user = value; - value = m.left().node(); - cont.Negate(); - } else { - break; - } - } - - // Try to combine the branch with a comparison. + // Try to combine the equality check with a comparison. + Node* const user = m.node(); + Node* const value = m.left().node(); if (CanCover(user, value)) { switch (value->opcode()) { case IrOpcode::kInt64Sub: @@ -1507,7 +1512,6 @@ void InstructionSelector::VisitWord64Equal(Node* const node) { break; } } - return VisitCompareZero(this, value, kX64Cmp, &cont); } VisitWord64Compare(this, node, &cont); } diff --git a/test/cctest/compiler/test-run-intrinsics.cc b/test/cctest/compiler/test-run-intrinsics.cc index d53d864..1fa3774 100644 --- a/test/cctest/compiler/test-run-intrinsics.cc +++ b/test/cctest/compiler/test-run-intrinsics.cc @@ -172,12 +172,17 @@ TEST(IsRegExp) { TEST(IsSmi) { FunctionTester T("(function(a) { return %_IsSmi(a); })", flags); + T.CheckFalse(T.NewObject("new Date()")); + T.CheckFalse(T.NewObject("(function() {})")); + T.CheckFalse(T.NewObject("([1])")); + T.CheckFalse(T.NewObject("({})")); + T.CheckFalse(T.NewObject("(/x/)")); + T.CheckFalse(T.undefined()); T.CheckTrue(T.Val(1)); T.CheckFalse(T.Val(1.1)); T.CheckFalse(T.Val(-0.0)); T.CheckTrue(T.Val(-2)); T.CheckFalse(T.Val(-2.3)); - T.CheckFalse(T.undefined()); } -- 2.7.4