From 806fcc6193e305c22366baa17ccf88c8e1da1bda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Thu, 5 Mar 2026 21:05:33 +0100 Subject: [PATCH] nir/opt_loop: always try to peel initial break from loops with unrolling hint This allows to unroll these loops, even if loop analyze is unable to calculate the iteration count. As always with loops, the throughput stats are meaningless. Totals from 6 (0.00% of 202440) affected shaders: (Navi48) Instrs: 7825 -> 6201 (-20.75%) CodeSize: 37056 -> 30412 (-17.93%) Latency: 21563 -> 16934 (-21.47%) InvThroughput: 144649 -> 77962 (-46.10%) SClause: 139 -> 133 (-4.32%) Copies: 536 -> 388 (-27.61%) Branches: 156 -> 84 (-46.15%) PreVGPRs: 298 -> 296 (-0.67%); split: -1.01%, +0.34% VALU: 2493 -> 2378 (-4.61%); split: -4.65%, +0.04% SALU: 3263 -> 2199 (-32.61%) SMEM: 188 -> 183 (-2.66%) Reviewed-by: Timothy Arceri Part-of: --- src/compiler/nir/nir_opt_loop.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/compiler/nir/nir_opt_loop.c b/src/compiler/nir/nir_opt_loop.c index bbc33721897..19158cf76f5 100644 --- a/src/compiler/nir/nir_opt_loop.c +++ b/src/compiler/nir/nir_opt_loop.c @@ -356,6 +356,13 @@ should_peel_initial_break(nir_loop *loop) nir_cf_node *if_node = nir_cf_node_next(&header_block->cf_node); nir_if *nif = nir_cf_node_as_if(if_node); + /* If this loop is supposed to get unrolled, try doing so by peeling + * one iteration at a time. This works in cases where loop analysis + * is not able to calculate the iteration count. + */ + if (loop->control & nir_loop_control_unroll) + return can_constant_fold(nir_get_scalar(nif->condition.ssa, 0), header_block); + /* This loop is already in do-while form. */ if (loop->do_while) return false;