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: 6b4b044739 ("nir/opt_loop: add loop peeling optimization")
Signed-off-by: Rob Clark <robdclark@chromium.org>
Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30702>
This commit is contained in:
Rob Clark
2024-08-16 14:15:49 -07:00
committed by Marge Bot
parent 665eae51ef
commit 563ec4754a
+6
View File
@@ -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;