Commit e0a2d93e authored by Joey Gouly's avatar Joey Gouly Committed by Commit Bot

[arm64] Allow immediate operands to be swapped in compares

This was deleted in 5b2ab2f6, it seems only
the first part of the condition should have been deleted.

This changes (from the embedded builtins):

    movz x9, #0x2
    cmp x9, x8

Back to:

    cmp x8, #0x2

This saves 0.29% in the embedded builtins size for a pointer-compression enabled arm64 build.

Also a minor cleanup by removing the commutative boolean parameter and always commuting the
FlagsContinuation. For a commutative operation the FlagsContinuation will stay the same.

Change-Id: I5bba84a07bb32284b4756bc6293560ee106745f2
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1762522Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Commit-Queue: Martyn Capewell <martyn.capewell@arm.com>
Cr-Commit-Position: refs/heads/master@{#63337}
parent eeef6199
...@@ -1833,12 +1833,19 @@ void VisitCompare(InstructionSelector* selector, InstructionCode opcode, ...@@ -1833,12 +1833,19 @@ void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
// Shared routine for multiple word compare operations. // Shared routine for multiple word compare operations.
void VisitWordCompare(InstructionSelector* selector, Node* node, void VisitWordCompare(InstructionSelector* selector, Node* node,
InstructionCode opcode, FlagsContinuation* cont, InstructionCode opcode, FlagsContinuation* cont,
bool commutative, ImmediateMode immediate_mode) { ImmediateMode immediate_mode) {
Arm64OperandGenerator g(selector); Arm64OperandGenerator g(selector);
Node* left = node->InputAt(0); Node* left = node->InputAt(0);
Node* right = node->InputAt(1); Node* right = node->InputAt(1);
// Match immediates on left or right side of comparison. // If one of the two inputs is an immediate, make sure it's on the right.
if (!g.CanBeImmediate(right, immediate_mode) &&
g.CanBeImmediate(left, immediate_mode)) {
cont->Commute();
std::swap(left, right);
}
if (g.CanBeImmediate(right, immediate_mode)) { if (g.CanBeImmediate(right, immediate_mode)) {
VisitCompare(selector, opcode, g.UseRegister(left), g.UseImmediate(right), VisitCompare(selector, opcode, g.UseRegister(left), g.UseImmediate(right),
cont); cont);
...@@ -2369,8 +2376,7 @@ void InstructionSelector::VisitWordCompareZero(Node* user, Node* value, ...@@ -2369,8 +2376,7 @@ void InstructionSelector::VisitWordCompareZero(Node* user, Node* value,
if (m.right().Is(0)) { if (m.right().Is(0)) {
Node* const left = m.left().node(); Node* const left = m.left().node();
if (CanCover(value, left) && left->opcode() == IrOpcode::kWord64And) { if (CanCover(value, left) && left->opcode() == IrOpcode::kWord64And) {
return VisitWordCompare(this, left, kArm64Tst, cont, true, return VisitWordCompare(this, left, kArm64Tst, cont, kLogical64Imm);
kLogical64Imm);
} }
// Merge the Word64Equal(x, 0) comparison into a cbz instruction. // Merge the Word64Equal(x, 0) comparison into a cbz instruction.
if ((cont->IsBranch() || cont->IsDeoptimize()) && if ((cont->IsBranch() || cont->IsDeoptimize()) &&
...@@ -2380,25 +2386,20 @@ void InstructionSelector::VisitWordCompareZero(Node* user, Node* value, ...@@ -2380,25 +2386,20 @@ void InstructionSelector::VisitWordCompareZero(Node* user, Node* value,
return; return;
} }
} }
return VisitWordCompare(this, value, kArm64Cmp, cont, false, return VisitWordCompare(this, value, kArm64Cmp, cont, kArithmeticImm);
kArithmeticImm);
} }
case IrOpcode::kInt64LessThan: case IrOpcode::kInt64LessThan:
cont->OverwriteAndNegateIfEqual(kSignedLessThan); cont->OverwriteAndNegateIfEqual(kSignedLessThan);
return VisitWordCompare(this, value, kArm64Cmp, cont, false, return VisitWordCompare(this, value, kArm64Cmp, cont, kArithmeticImm);
kArithmeticImm);
case IrOpcode::kInt64LessThanOrEqual: case IrOpcode::kInt64LessThanOrEqual:
cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual); cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
return VisitWordCompare(this, value, kArm64Cmp, cont, false, return VisitWordCompare(this, value, kArm64Cmp, cont, kArithmeticImm);
kArithmeticImm);
case IrOpcode::kUint64LessThan: case IrOpcode::kUint64LessThan:
cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
return VisitWordCompare(this, value, kArm64Cmp, cont, false, return VisitWordCompare(this, value, kArm64Cmp, cont, kArithmeticImm);
kArithmeticImm);
case IrOpcode::kUint64LessThanOrEqual: case IrOpcode::kUint64LessThanOrEqual:
cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
return VisitWordCompare(this, value, kArm64Cmp, cont, false, return VisitWordCompare(this, value, kArm64Cmp, cont, kArithmeticImm);
kArithmeticImm);
case IrOpcode::kFloat32Equal: case IrOpcode::kFloat32Equal:
cont->OverwriteAndNegateIfEqual(kEqual); cont->OverwriteAndNegateIfEqual(kEqual);
return VisitFloat32Compare(this, value, cont); return VisitFloat32Compare(this, value, cont);
...@@ -2460,16 +2461,13 @@ void InstructionSelector::VisitWordCompareZero(Node* user, Node* value, ...@@ -2460,16 +2461,13 @@ void InstructionSelector::VisitWordCompareZero(Node* user, Node* value,
} }
break; break;
case IrOpcode::kInt32Add: case IrOpcode::kInt32Add:
return VisitWordCompare(this, value, kArm64Cmn32, cont, true, return VisitWordCompare(this, value, kArm64Cmn32, cont, kArithmeticImm);
kArithmeticImm);
case IrOpcode::kInt32Sub: case IrOpcode::kInt32Sub:
return VisitWord32Compare(this, value, cont); return VisitWord32Compare(this, value, cont);
case IrOpcode::kWord32And: case IrOpcode::kWord32And:
return VisitWordCompare(this, value, kArm64Tst32, cont, true, return VisitWordCompare(this, value, kArm64Tst32, cont, kLogical32Imm);
kLogical32Imm);
case IrOpcode::kWord64And: case IrOpcode::kWord64And:
return VisitWordCompare(this, value, kArm64Tst, cont, true, return VisitWordCompare(this, value, kArm64Tst, cont, kLogical64Imm);
kLogical64Imm);
case IrOpcode::kStackPointerGreaterThan: case IrOpcode::kStackPointerGreaterThan:
cont->OverwriteAndNegateIfEqual(kStackPointerGreaterThanCondition); cont->OverwriteAndNegateIfEqual(kStackPointerGreaterThanCondition);
return VisitStackPointerGreaterThan(value, cont); return VisitStackPointerGreaterThan(value, cont);
...@@ -2532,7 +2530,7 @@ void InstructionSelector::VisitWord32Equal(Node* const node) { ...@@ -2532,7 +2530,7 @@ void InstructionSelector::VisitWord32Equal(Node* const node) {
case IrOpcode::kWord32And: case IrOpcode::kWord32And:
return VisitWord32Compare(this, node, &cont); return VisitWord32Compare(this, node, &cont);
case IrOpcode::kInt32Sub: case IrOpcode::kInt32Sub:
return VisitWordCompare(this, value, kArm64Cmp32, &cont, false, return VisitWordCompare(this, value, kArm64Cmp32, &cont,
kArithmeticImm); kArithmeticImm);
case IrOpcode::kWord32Equal: { case IrOpcode::kWord32Equal: {
// Word32Equal(Word32Equal(x, y), 0) => Word32Compare(x, y, ne). // Word32Equal(Word32Equal(x, y), 0) => Word32Compare(x, y, ne).
...@@ -2589,15 +2587,14 @@ void InstructionSelector::VisitWord64Equal(Node* const node) { ...@@ -2589,15 +2587,14 @@ void InstructionSelector::VisitWord64Equal(Node* const node) {
if (CanCover(user, value)) { if (CanCover(user, value)) {
switch (value->opcode()) { switch (value->opcode()) {
case IrOpcode::kWord64And: case IrOpcode::kWord64And:
return VisitWordCompare(this, value, kArm64Tst, &cont, true, return VisitWordCompare(this, value, kArm64Tst, &cont, kLogical64Imm);
kLogical64Imm);
default: default:
break; break;
} }
return VisitWord64Test(this, value, &cont); return VisitWord64Test(this, value, &cont);
} }
} }
VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm); VisitWordCompare(this, node, kArm64Cmp, &cont, kArithmeticImm);
} }
void InstructionSelector::VisitInt32AddWithOverflow(Node* node) { void InstructionSelector::VisitInt32AddWithOverflow(Node* node) {
...@@ -2655,24 +2652,24 @@ void InstructionSelector::VisitInt64SubWithOverflow(Node* node) { ...@@ -2655,24 +2652,24 @@ void InstructionSelector::VisitInt64SubWithOverflow(Node* node) {
void InstructionSelector::VisitInt64LessThan(Node* node) { void InstructionSelector::VisitInt64LessThan(Node* node) {
FlagsContinuation cont = FlagsContinuation::ForSet(kSignedLessThan, node); FlagsContinuation cont = FlagsContinuation::ForSet(kSignedLessThan, node);
VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm); VisitWordCompare(this, node, kArm64Cmp, &cont, kArithmeticImm);
} }
void InstructionSelector::VisitInt64LessThanOrEqual(Node* node) { void InstructionSelector::VisitInt64LessThanOrEqual(Node* node) {
FlagsContinuation cont = FlagsContinuation cont =
FlagsContinuation::ForSet(kSignedLessThanOrEqual, node); FlagsContinuation::ForSet(kSignedLessThanOrEqual, node);
VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm); VisitWordCompare(this, node, kArm64Cmp, &cont, kArithmeticImm);
} }
void InstructionSelector::VisitUint64LessThan(Node* node) { void InstructionSelector::VisitUint64LessThan(Node* node) {
FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node); FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node);
VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm); VisitWordCompare(this, node, kArm64Cmp, &cont, kArithmeticImm);
} }
void InstructionSelector::VisitUint64LessThanOrEqual(Node* node) { void InstructionSelector::VisitUint64LessThanOrEqual(Node* node) {
FlagsContinuation cont = FlagsContinuation cont =
FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node); FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node);
VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm); VisitWordCompare(this, node, kArm64Cmp, &cont, kArithmeticImm);
} }
void InstructionSelector::VisitFloat32Neg(Node* node) { void InstructionSelector::VisitFloat32Neg(Node* node) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment