aco: handle NIR loops without breaks

Signed-off-by: Rhys Perry <pendingchaos02@gmail.com>
Reviewed-by: Daniel Schürmann <daniel@schuermann.dev>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11626>
This commit is contained in:
Rhys Perry 2021-06-22 15:23:37 +01:00 committed by Marge Bot
parent fd5c787958
commit a9c4a31d8d
1 changed files with 18 additions and 0 deletions

View File

@ -9916,10 +9916,28 @@ static Operand create_continue_phis(isel_context *ctx, unsigned first, unsigned
return vals[last - first];
}
static void begin_uniform_if_then(isel_context *ctx, if_context *ic, Temp cond);
static void begin_uniform_if_else(isel_context *ctx, if_context *ic);
static void end_uniform_if(isel_context *ctx, if_context *ic);
static void 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(0u));
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;