From 563ec4754aef34f8707cccbb01ec8dac29a0c0e3 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Fri, 16 Aug 2024 14:15:49 -0700 Subject: [PATCH] nir/opt_loop: Don't peel initial break if loop ends in break A loop that looks like: loop { do_work_1(); if (cond) { break; } else { } do_work_2(); break; } We can't pull that break ahead of do_work_1() after hoisting the initial do_work_1() out of the loop. So bail in this case. Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/11711 Fixes: 6b4b04473986 ("nir/opt_loop: add loop peeling optimization") Signed-off-by: Rob Clark Reviewed-by: Alyssa Rosenzweig Part-of: --- src/compiler/nir/nir_opt_loop.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/compiler/nir/nir_opt_loop.c b/src/compiler/nir/nir_opt_loop.c index cfc9099607d..1f996854146 100644 --- a/src/compiler/nir/nir_opt_loop.c +++ b/src/compiler/nir/nir_opt_loop.c @@ -396,6 +396,12 @@ opt_loop_peel_initial_break(nir_loop *loop) !is_block_empty(nir_if_first_else_block(nif))) return false; + /* If do_work_2() ends in a break (presumably with a continue somewhere) + * then we can't move it to the top of the loop ahead of do_work_1() + */ + if (nir_block_ends_in_break(nir_loop_last_block(loop))) + return false; + /* Check that there is actual work to be done after the initial break. */ if (!block_contains_work(nir_cf_node_cf_tree_next(if_node))) return false;