[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}
This commit is contained in:
bmeurer 2015-06-24 02:15:19 -07:00 committed by Commit bot
parent 48d726cd6f
commit 7a675e0e3b
2 changed files with 29 additions and 20 deletions

View File

@ -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);
}

View File

@ -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());
}