aco/spill_preserved: Fix spilled VGPR overflow handling

We modified the spill offset inside the function, which made subsequent
calls to emit_vgpr_spills_reloads reload from the wrong offset.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29580>
This commit is contained in:
Natalie Vock 2026-01-13 23:46:31 +01:00 committed by Marge Bot
parent d563415100
commit eb86ae3b8c

View file

@ -168,7 +168,7 @@ add_preserved_sgpr_spill(spill_preserved_ctx& ctx, PhysReg reg,
void
emit_vgpr_spills_reloads(spill_preserved_ctx& ctx, Builder& bld,
std::vector<std::pair<PhysReg, unsigned>>& spills, PhysReg stack_reg,
const std::vector<std::pair<PhysReg, unsigned>>& spills, PhysReg stack_reg,
bool reload, bool linear)
{
if (spills.empty())
@ -176,12 +176,12 @@ emit_vgpr_spills_reloads(spill_preserved_ctx& ctx, Builder& bld,
unsigned first_spill_offset =
DIV_ROUND_UP(ctx.program->config->scratch_bytes_per_wave, ctx.program->wave_size);
unsigned spill_stack_base = 0;
int end_offset = (int)spills.back().second;
bool overflow = end_offset >= ctx.program->dev.scratch_global_offset_max;
if (overflow) {
for (auto& spill : spills)
spill.second -= first_spill_offset;
spill_stack_base = first_spill_offset;
if (ctx.program->gfx_level < GFX9)
first_spill_offset *= ctx.program->wave_size;
@ -201,25 +201,26 @@ emit_vgpr_spills_reloads(spill_preserved_ctx& ctx, Builder& bld,
if (reload)
bld.scratch(aco_opcode::scratch_load_dword,
Definition(spill.first, linear ? v1.as_linear() : v1), Operand(v1),
Operand(stack_reg, s1), spill.second,
Operand(stack_reg, s1), spill.second - spill_stack_base,
memory_sync_info(storage_vgpr_spill, semantic_private));
else
bld.scratch(aco_opcode::scratch_store_dword, Operand(v1), Operand(stack_reg, s1),
Operand(spill.first, linear ? v1.as_linear() : v1),
spill.second,
spill.second - spill_stack_base,
memory_sync_info(storage_vgpr_spill, semantic_private));
} else {
if (reload) {
Instruction* instr = bld.mubuf(
aco_opcode::buffer_load_dword, Definition(spill.first, linear ? v1.as_linear() : v1),
Operand(stack_reg, s4), Operand(v1), Operand::c32(0), spill.second, false);
Instruction* instr = bld.mubuf(aco_opcode::buffer_load_dword,
Definition(spill.first, linear ? v1.as_linear() : v1),
Operand(stack_reg, s4), Operand(v1), Operand::c32(0),
spill.second - spill_stack_base, false);
instr->mubuf().sync = memory_sync_info(storage_vgpr_spill, semantic_private);
instr->mubuf().cache.value = ac_swizzled;
} else {
Instruction* instr =
bld.mubuf(aco_opcode::buffer_store_dword, Operand(stack_reg, s4), Operand(v1),
Operand::c32(0), Operand(spill.first, linear ? v1.as_linear() : v1),
spill.second, false);
spill.second - spill_stack_base, false);
instr->mubuf().sync = memory_sync_info(storage_vgpr_spill, semantic_private);
instr->mubuf().cache.value = ac_swizzled;
}