From d9977a61762b99b75cc747fc3a52675502f02e6e Mon Sep 17 00:00:00 2001 From: Job Noorman Date: Fri, 16 Aug 2024 15:54:24 +0200 Subject: [PATCH] ir3: fix adding physical edges multiple times After opt_jump, we might end up with weird control flow likes this: block0: br block2 [more blocks] block1: br block3 block2: ... block3: ... Since block2 is a logical successor of block1 (due to the fall through), a physical edge will be added. However, another one will be added because the branch to block3 crosses block2 (which is a reconvergence point due to the branch from block0). This currently results in an assert. This commit fixes this by ignoring successors of the start block of edges that cross reconvergence points. Part-of: --- src/freedreno/ir3/ir3_reconvergence.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/freedreno/ir3/ir3_reconvergence.c b/src/freedreno/ir3/ir3_reconvergence.c index aa01ec9b7b9..5101fb39a95 100644 --- a/src/freedreno/ir3/ir3_reconvergence.c +++ b/src/freedreno/ir3/ir3_reconvergence.c @@ -294,10 +294,16 @@ ir3_calc_reconvergence(struct ir3_shader_variant *so) * adding redundant physical edges in case multiple edges have the * same start point by comparing with the previous edge. Therefore * we should only add the physical edge once. + * However, we should skip logical successors of the edge's start + * block since physical edges for those have already been added + * initially. */ - for (unsigned i = 0; i < block->physical_predecessors_count; i++) - assert(block->physical_predecessors[i] != edge->start_block); - ir3_block_link_physical(edge->start_block, block); + if (block != edge->start_block->successors[0] && + block != edge->start_block->successors[1]) { + for (unsigned i = 0; i < block->physical_predecessors_count; i++) + assert(block->physical_predecessors[i] != edge->start_block); + ir3_block_link_physical(edge->start_block, block); + } } prev = edge; }