Index: src/compiler/x64/instruction-selector-x64.cc |
diff --git a/src/compiler/x64/instruction-selector-x64.cc b/src/compiler/x64/instruction-selector-x64.cc |
index d102e847181f3c8deec72497659bc9d5adf407bd..c84edfe839005d671e5f88700ed74de20f1d75a4 100644 |
--- a/src/compiler/x64/instruction-selector-x64.cc |
+++ b/src/compiler/x64/instruction-selector-x64.cc |
@@ -240,7 +240,18 @@ static void VisitBinop(InstructionSelector* selector, Node* node, |
size_t output_count = 0; |
// TODO(turbofan): match complex addressing modes. |
- if (g.CanBeImmediate(right)) { |
+ if (left == right) { |
+ // If both inputs refer to the same operand, enforce allocating a register |
+ // for both of them to ensure that we don't end up generating code like |
+ // this: |
+ // |
+ // mov rax, [rbp-0x10] |
+ // add rax, [rbp-0x10] |
+ // jo label |
+ InstructionOperand* const input = g.UseRegister(left); |
+ inputs[input_count++] = input; |
+ inputs[input_count++] = input; |
+ } else if (g.CanBeImmediate(right)) { |
inputs[input_count++] = g.UseRegister(left); |
inputs[input_count++] = g.UseImmediate(right); |
} else { |
@@ -796,13 +807,6 @@ static void VisitWordCompare(InstructionSelector* selector, Node* node, |
} |
-static void VisitWordTest(InstructionSelector* selector, Node* node, |
- InstructionCode opcode, FlagsContinuation* cont) { |
- X64OperandGenerator g(selector); |
- VisitCompare(selector, opcode, g.Use(node), g.TempImmediate(-1), cont); |
-} |
- |
- |
static void VisitFloat64Compare(InstructionSelector* selector, Node* node, |
FlagsContinuation* cont) { |
X64OperandGenerator g(selector); |
@@ -815,7 +819,7 @@ static void VisitFloat64Compare(InstructionSelector* selector, Node* node, |
void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, |
BasicBlock* fbranch) { |
- OperandGenerator g(this); |
+ X64OperandGenerator g(this); |
Node* user = branch; |
Node* value = branch->InputAt(0); |
@@ -918,15 +922,19 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, |
break; |
case IrOpcode::kInt32Sub: |
return VisitWordCompare(this, value, kX64Cmp32, &cont, false); |
+ case IrOpcode::kInt64Sub: |
+ return VisitWordCompare(this, value, kX64Cmp, &cont, false); |
case IrOpcode::kWord32And: |
return VisitWordCompare(this, value, kX64Test32, &cont, true); |
+ case IrOpcode::kWord64And: |
+ return VisitWordCompare(this, value, kX64Test, &cont, true); |
default: |
break; |
} |
} |
// Branch could not be combined with a compare, emit compare against 0. |
- VisitWordTest(this, value, kX64Test32, &cont); |
+ VisitCompare(this, kX64Cmp32, g.Use(value), g.TempImmediate(0), &cont); |
} |
@@ -945,7 +953,6 @@ void InstructionSelector::VisitWord32Equal(Node* const node) { |
default: |
break; |
} |
- return VisitWordTest(this, value, kX64Test32, &cont); |
} |
} |
VisitWordCompare(this, node, kX64Cmp32, &cont, false); |
@@ -991,7 +998,6 @@ void InstructionSelector::VisitWord64Equal(Node* const node) { |
default: |
break; |
} |
- return VisitWordTest(this, value, kX64Test, &cont); |
} |
} |
VisitWordCompare(this, node, kX64Cmp, &cont, false); |