From fb2fbf03dd072bf22a7edd6a59cd3493f26a46f3 Mon Sep 17 00:00:00 2001 From: Gert Wollny Date: Mon, 11 Aug 2025 14:55:16 +0200 Subject: [PATCH] r600/sfn: Fix AR use tracking off-by-one error The evauation of loading the AR register was off by one, so that splitting an ALU group could actually happen after AR was loaded resulting in a failure to lower to assembly. Fixes: d617052db6b ("r600/sfn: take address loads into account when scheduling") Signed-off-by: Gert Wollny Part-of: (cherry picked from commit 5d0f212d819b24d81d63619a2a62e36a0b2fb64c) --- .pick_status.json | 2 +- src/gallium/drivers/r600/sfn/sfn_scheduler.cpp | 17 ++++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index 2afecab725b..df61a2f216a 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -7904,7 +7904,7 @@ "description": "r600/sfn: Fix AR use tracking off-by-one error", "nominated": true, "nomination_type": 2, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": "d617052db6b2f359d7242875013603ec63b069fc", "notes": null diff --git a/src/gallium/drivers/r600/sfn/sfn_scheduler.cpp b/src/gallium/drivers/r600/sfn/sfn_scheduler.cpp index 2a8eb6ace22..e4e3f6942f9 100644 --- a/src/gallium/drivers/r600/sfn/sfn_scheduler.cpp +++ b/src/gallium/drivers/r600/sfn/sfn_scheduler.cpp @@ -526,6 +526,7 @@ BlockScheduler::schedule_alu(Shader::ShaderBlocks& out_blocks) { bool success = false; AluGroup *group = nullptr; + int expected_ar_uses = m_current_block->expected_ar_uses(); sfn_log << SfnLog::schedule << "Schedule alu with " << m_current_block->expected_ar_uses() @@ -544,6 +545,7 @@ BlockScheduler::schedule_alu(Shader::ShaderBlocks& out_blocks) if (m_current_block->type() != Block::alu) { start_new_block(out_blocks, Block::alu); m_alu_groups_scheduled = 0; + expected_ar_uses = 0; } } @@ -564,7 +566,7 @@ BlockScheduler::schedule_alu(Shader::ShaderBlocks& out_blocks) alu_groups_ready.erase(alu_groups_ready.begin()); success = true; } else { - if (m_current_block->expected_ar_uses() == 0) { + if (expected_ar_uses == 0) { start_new_block(out_blocks, Block::alu); if (!m_current_block->try_reserve_kcache(*group)) @@ -620,7 +622,9 @@ BlockScheduler::schedule_alu(Shader::ShaderBlocks& out_blocks) // AR is loaded but not all uses are done, we don't want // to start a new CF here - assert(m_current_block->expected_ar_uses() ==0); + // TODO this can explode, if kcache reservation fails with + // an instruction that also requires AR + assert(expected_ar_uses == 0); // kcache reservation failed, so we have to start a new CF start_new_block(out_blocks, Block::alu); @@ -648,13 +652,13 @@ BlockScheduler::schedule_alu(Shader::ShaderBlocks& out_blocks) if (is_index) { if (addr->sel() == AddressRegister::idx0 && m_idx0_pending) { assert(!group->has_lds_group_start()); - assert(m_current_block->expected_ar_uses() == 0); + assert(expected_ar_uses == 0); start_new_block(out_blocks, Block::alu); m_current_block->try_reserve_kcache(*group); } if (addr->sel() == AddressRegister::idx1 && m_idx1_pending) { assert(!group->has_lds_group_start()); - assert(m_current_block->expected_ar_uses() == 0); + assert(expected_ar_uses == 0); start_new_block(out_blocks, Block::alu); m_current_block->try_reserve_kcache(*group); } @@ -670,8 +674,7 @@ BlockScheduler::schedule_alu(Shader::ShaderBlocks& out_blocks) m_idx1_pending |= m_idx1_loading; m_idx1_loading = false; - if (!m_current_block->lds_group_active() && - m_current_block->expected_ar_uses() == 0 && + if (!m_current_block->lds_group_active() && expected_ar_uses == 0 && (!addr || is_index)) { group->set_instr_flag(Instr::no_lds_or_addr_group); } @@ -684,7 +687,7 @@ BlockScheduler::schedule_alu(Shader::ShaderBlocks& out_blocks) if (group->has_kill_op()) { assert(!group->has_lds_group_start()); - assert(m_current_block->expected_ar_uses() == 0); + assert(expected_ar_uses == 0); start_new_block(out_blocks, Block::alu); }