From 9b19409ac8ae64b1574fbafcd8fdf296a6c3c44c Mon Sep 17 00:00:00 2001 From: Rhys Perry Date: Tue, 17 Mar 2026 14:32:37 +0000 Subject: [PATCH] ir3/array_to_ssa: skip remove_trivial_phi for non-array phis remove_trivial_phi() mostly does nothing for non-array phis, but it rewrites sources if their definining instruction are trivial phis. In the case of trivial phis in the loop continue block (for loops with divergent non-trivial continues), we might need to keep those if they write a shared register, because the source of the trivial phi will not be reachable from the loop header phi. In this example, the predecessors of the continue block should be block2, but the physical predecessors are block2 and block3, requiring a phi in the continue block which will then be lowered by ir3_lower_shared_phis. loop { block1: a = phi 0, b if (divergent) { block2: b = a + 1 continue; } block3: break; } Fixes RA validation error when compiling blackmythwukong/5645a84e669a6179 from radv_fossils. Signed-off-by: Rhys Perry Backport-to: 26.0 (cherry picked from commit 4f0fb5784f61c38798dccfa6ae97e380ccd1519c) Part-of: --- .pick_status.json | 2 +- src/freedreno/ir3/ir3_array_to_ssa.c | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index eabdd93bc31..baec00cd037 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -544,7 +544,7 @@ "description": "ir3/array_to_ssa: skip remove_trivial_phi for non-array phis", "nominated": true, "nomination_type": 4, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": null, "notes": null diff --git a/src/freedreno/ir3/ir3_array_to_ssa.c b/src/freedreno/ir3/ir3_array_to_ssa.c index 2e9d6820663..d3ea899ed90 100644 --- a/src/freedreno/ir3/ir3_array_to_ssa.c +++ b/src/freedreno/ir3/ir3_array_to_ssa.c @@ -236,10 +236,13 @@ ir3_array_to_ssa(struct ir3 *ir) foreach_block (block, &ir->block_list) { foreach_instr_safe (instr, &block->instr_list) { - if (instr->opc == OPC_META_PHI) + if (instr->opc == OPC_META_PHI) { + if (!(instr->dsts[0]->flags & IR3_REG_ARRAY)) + continue; remove_trivial_phi(instr); - else + } else { break; + } } }