[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:
parent
48d726cd6f
commit
7a675e0e3b
@ -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);
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user