diff --git a/src/amd/compiler/aco_assembler.cpp b/src/amd/compiler/aco_assembler.cpp index 9ef25e3edd4..5d12fb5000e 100644 --- a/src/amd/compiler/aco_assembler.cpp +++ b/src/amd/compiler/aco_assembler.cpp @@ -1575,15 +1575,20 @@ chain_branches(asm_context& ctx, std::vector& out, branch_info& branch if (insert_at == 0) { /* Find the last block that is still within reach. */ unsigned insertion_block_idx = 0; - while (ctx.program->blocks[insertion_block_idx + 1].offset < upper_end) - insertion_block_idx++; + unsigned next_block = 0; + while (ctx.program->blocks[next_block + 1].offset < upper_end) { + if (!ctx.program->blocks[next_block].instructions.empty()) + insertion_block_idx = next_block; + next_block++; + } - insert_at = ctx.program->blocks[insertion_block_idx].offset; - auto it = ctx.program->blocks[insertion_block_idx].instructions.begin(); - int skip = 0; + insert_at = ctx.program->blocks[next_block].offset; if (insert_at < upper_start) { /* Ensure some forward progress by splitting the block if necessary. */ + auto it = ctx.program->blocks[next_block].instructions.begin(); + int skip = 0; while (skip-- > 0 || insert_at < upper_start) { + assert(it != ctx.program->blocks[next_block].instructions.end()); Instruction* instr = (it++)->get(); if (instr->isSOPP()) { if (instr->opcode == aco_opcode::s_clause) @@ -1603,10 +1608,11 @@ chain_branches(asm_context& ctx, std::vector& out, branch_info& branch /* If the insertion point is in the middle of the block, insert the branch instructions * into that block instead. */ - bld.reset(&ctx.program->blocks[insertion_block_idx].instructions, it); + bld.reset(&ctx.program->blocks[next_block].instructions, it); } else { - bld.reset(&ctx.program->blocks[insertion_block_idx - 1].instructions); - skip_branch_target = insertion_block_idx; + /* Insert the additional branches at the end of the previous non-empty block. */ + bld.reset(&ctx.program->blocks[insertion_block_idx].instructions); + skip_branch_target = next_block; } /* Since we insert a branch into existing code, mitigate LdsBranchVmemWARHazard on GFX10. */ @@ -1619,6 +1625,7 @@ chain_branches(asm_context& ctx, std::vector& out, branch_info& branch branch_instr = bld.sopp(aco_opcode::s_branch, 1).instr; emit_sopp_instruction(ctx, code, branch_instr, true); } + assert(insert_at >= upper_start); const unsigned block_offset = insert_at + code.size(); branch_instr = bld.sopp(aco_opcode::s_branch, 0);