aco: fix NIR infinite loops
authorDaniel Schürmann <daniel@schuermann.dev>
Wed, 8 Mar 2023 04:15:04 +0000 (05:15 +0100)
committerMarge Bot <emma+marge@anholt.net>
Wed, 8 Mar 2023 16:59:41 +0000 (16:59 +0000)
The previous solution breaks potential loop header phis.
Move the dummy-break to the bottom of the loop.

Fixes: dEQP-VK.reconvergence.subgroup_uniform_control_flow_ballot.*
Fixes: a9c4a31d8d8a955711d6f49869090caf87846f1b ('aco: handle NIR loops without breaks')
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21736>

src/amd/compiler/aco_instruction_selection.cpp

index 7f1ca20..1b6f877 100644 (file)
@@ -10366,19 +10366,6 @@ visit_loop(isel_context* ctx, nir_loop* loop)
    loop_context lc;
    begin_loop(ctx, &lc);
 
-   /* NIR seems to allow this, and even though the loop exit has no predecessors, SSA defs from the
-    * loop header are live. Handle this without complicating the ACO IR by creating a dummy break.
-    */
-   if (nir_cf_node_cf_tree_next(&loop->cf_node)->predecessors->entries == 0) {
-      Builder bld(ctx->program, ctx->block);
-      Temp cond = bld.copy(bld.def(s1, scc), Operand::zero());
-      if_context ic;
-      begin_uniform_if_then(ctx, &ic, cond);
-      emit_loop_break(ctx);
-      begin_uniform_if_else(ctx, &ic);
-      end_uniform_if(ctx, &ic);
-   }
-
    bool unreachable = visit_cf_list(ctx, &loop->body);
 
    unsigned loop_header_idx = ctx->cf_info.parent_loop.header_idx;
@@ -10420,6 +10407,19 @@ visit_loop(isel_context* ctx, nir_loop* loop)
       }
    }
 
+   /* NIR seems to allow this, and even though the loop exit has no predecessors, SSA defs from the
+    * loop header are live. Handle this without complicating the ACO IR by creating a dummy break.
+    */
+   if (nir_cf_node_cf_tree_next(&loop->cf_node)->predecessors->entries == 0) {
+      Builder bld(ctx->program, ctx->block);
+      Temp cond = bld.copy(bld.def(s1, scc), Operand::zero());
+      if_context ic;
+      begin_uniform_if_then(ctx, &ic, cond);
+      emit_loop_break(ctx);
+      begin_uniform_if_else(ctx, &ic);
+      end_uniform_if(ctx, &ic);
+   }
+
    end_loop(ctx, &lc);
 }