Commit c34c85a5 authored by Leszek Swirski's avatar Leszek Swirski Committed by V8 LUCI CQ

[maglev] Fix deopt condition in Int32Div

1. A remainder equal to zero means no deopt.
2. We need the input value in the input register, so we need to treat
   rax as a clobbered temporary instead of a fixed input.

Bug: v8:7700
Change-Id: I9a7b7f3cc48e17b262aa7f9084fa864ad505be54
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3788099
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Auto-Submit: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/main@{#82044}
parent 04483dbb
...@@ -1701,24 +1701,29 @@ void Int32MultiplyWithOverflow::GenerateCode(MaglevCodeGenState* code_gen_state, ...@@ -1701,24 +1701,29 @@ void Int32MultiplyWithOverflow::GenerateCode(MaglevCodeGenState* code_gen_state,
void Int32DivideWithOverflow::AllocateVreg( void Int32DivideWithOverflow::AllocateVreg(
MaglevVregAllocationState* vreg_state) { MaglevVregAllocationState* vreg_state) {
UseFixed(left_input(), rax); UseRegister(left_input());
UseRegister(right_input()); UseRegister(right_input());
DefineAsFixed(vreg_state, this, rax); DefineAsFixed(vreg_state, this, rax);
// rdx is clobbered by idiv. // rax,rdx are clobbered by idiv.
RequireSpecificTemporary(rax);
RequireSpecificTemporary(rdx); RequireSpecificTemporary(rdx);
} }
void Int32DivideWithOverflow::GenerateCode(MaglevCodeGenState* code_gen_state, void Int32DivideWithOverflow::GenerateCode(MaglevCodeGenState* code_gen_state,
const ProcessingState& state) { const ProcessingState& state) {
DCHECK_EQ(rax, ToRegister(left_input())); DCHECK(temporaries().has(rax));
DCHECK(temporaries().has(rdx)); DCHECK(temporaries().has(rdx));
Register left = ToRegister(left_input());
Register right = ToRegister(right_input()); Register right = ToRegister(right_input());
__ movl(rax, left);
// Clear rdx so that it doesn't participate in the division. // Clear rdx so that it doesn't participate in the division.
__ xorl(rdx, rdx); __ xorl(rdx, rdx);
// TODO(leszeks): peephole optimise division by a constant. // TODO(leszeks): peephole optimise division by a constant.
__ idivl(right); __ idivl(right);
__ cmpl(rdx, Immediate(0)); __ cmpl(rdx, Immediate(0));
EmitEagerDeoptIf(equal, code_gen_state, DeoptimizeReason::kNotInt32, this); EmitEagerDeoptIf(not_equal, code_gen_state, DeoptimizeReason::kNotInt32,
this);
DCHECK_EQ(ToRegister(result()), rax);
} }
void Int32BitwiseAnd::AllocateVreg(MaglevVregAllocationState* vreg_state) { void Int32BitwiseAnd::AllocateVreg(MaglevVregAllocationState* vreg_state) {
......
...@@ -460,6 +460,17 @@ void StraightForwardRegisterAllocator::UpdateUse( ...@@ -460,6 +460,17 @@ void StraightForwardRegisterAllocator::UpdateUse(
}); });
} }
#ifdef DEBUG
namespace {
Register GetNodeResultRegister(Node* node) {
ValueNode* value_node = node->TryCast<ValueNode>();
if (!value_node) return Register::no_reg();
if (!value_node->result().operand().IsRegister()) return Register::no_reg();
return value_node->result().AssignedGeneralRegister();
}
} // namespace
#endif // DEBUG
void StraightForwardRegisterAllocator::AllocateNode(Node* node) { void StraightForwardRegisterAllocator::AllocateNode(Node* node) {
current_node_ = node; current_node_ = node;
if (FLAG_trace_maglev_regalloc) { if (FLAG_trace_maglev_regalloc) {
...@@ -507,7 +518,11 @@ void StraightForwardRegisterAllocator::AllocateNode(Node* node) { ...@@ -507,7 +518,11 @@ void StraightForwardRegisterAllocator::AllocateNode(Node* node) {
printing_visitor_->os() << "\n"; printing_visitor_->os() << "\n";
} }
DCHECK_EQ(general_registers_.free() | node->temporaries(), // All the temporaries should be free by the end. The exception is the node
// result, which could be written into a register that was previously
// considered a temporary.
DCHECK_EQ(general_registers_.free() |
(node->temporaries() - GetNodeResultRegister(node)),
general_registers_.free()); general_registers_.free());
general_registers_.clear_blocked(); general_registers_.clear_blocked();
double_registers_.clear_blocked(); double_registers_.clear_blocked();
......
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