From 553ab18656fb542b52565efaba1b6ebbb5cc6290 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Wed, 26 Feb 2025 12:38:58 +0100 Subject: [PATCH] aco/assembler: Fix short jumps over chained branches If we insert s_branch 1 s_branch Target at the end of some block, and later hide an additional chained branch after the existing one, then we have to update the 's_branch 1' to also jump over the newly added branch. Fixes: cab5639a09ab954e67af27486a0f9b41a0373d98 ('aco/assembler: chain branches instead of emitting long jumps') Closes: #12673 Part-of: (cherry picked from commit 6659db285aac3c611c45befaf8fec889982bbd69) --- .pick_status.json | 2 +- src/amd/compiler/aco_assembler.cpp | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.pick_status.json b/.pick_status.json index a99ee618bbf..91331550259 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -154,7 +154,7 @@ "description": "aco/assembler: Fix short jumps over chained branches", "nominated": true, "nomination_type": 2, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": "cab5639a09ab954e67af27486a0f9b41a0373d98", "notes": null diff --git a/src/amd/compiler/aco_assembler.cpp b/src/amd/compiler/aco_assembler.cpp index d04909dbcb9..9ef25e3edd4 100644 --- a/src/amd/compiler/aco_assembler.cpp +++ b/src/amd/compiler/aco_assembler.cpp @@ -1538,6 +1538,8 @@ chain_branches(asm_context& ctx, std::vector& out, branch_info& branch unsigned target = branch.target; branch.target = new_block->index; + unsigned skip_branch_target = 0; /* Target of potentially inserted short jump. */ + /* Find suitable insertion point: * We define two offset ranges within our new branch instruction should be placed. * Then we try to maximize the distance from either the previous branch or the target. @@ -1604,6 +1606,7 @@ chain_branches(asm_context& ctx, std::vector& out, branch_info& branch bld.reset(&ctx.program->blocks[insertion_block_idx].instructions, it); } else { bld.reset(&ctx.program->blocks[insertion_block_idx - 1].instructions); + skip_branch_target = insertion_block_idx; } /* Since we insert a branch into existing code, mitigate LdsBranchVmemWARHazard on GFX10. */ @@ -1623,6 +1626,11 @@ chain_branches(asm_context& ctx, std::vector& out, branch_info& branch insert_code(ctx, out, insert_at, code.size(), code.data()); new_block->offset = block_offset; + if (skip_branch_target) { + /* If we insert a short jump over the new branch at the end of a block, + * ensure that it gets updated accordingly after additional changes. */ + ctx.branches.push_back({block_offset - 1, skip_branch_target}); + } ctx.branches.push_back({block_offset, target}); assert(out[ctx.branches.back().pos] == code.back()); }