aco: improve check for unreachable loop continue blocks
The old code would have previously caught:
loop {
...
break
}
when it was meant to just catch:
loop {
if (...)
break
else
break
}
Signed-off-by: Rhys Perry <pendingchaos02@gmail.com>
CC: <mesa-stable@lists.freedesktop.org>
Reviewed-by: Daniel Schürmann <daniel@schuermann.dev>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/3658>
This commit is contained in:
@@ -90,7 +90,7 @@ struct if_context {
|
||||
Block BB_endif;
|
||||
};
|
||||
|
||||
static void visit_cf_list(struct isel_context *ctx,
|
||||
static bool visit_cf_list(struct isel_context *ctx,
|
||||
struct exec_list *list);
|
||||
|
||||
static void add_logical_edge(unsigned pred_idx, Block *succ)
|
||||
@@ -8566,7 +8566,7 @@ static void visit_loop(isel_context *ctx, nir_loop *loop)
|
||||
unsigned loop_header_idx = loop_header->index;
|
||||
loop_info_RAII loop_raii(ctx, loop_header_idx, &loop_exit);
|
||||
append_logical_start(ctx->block);
|
||||
visit_cf_list(ctx, &loop->body);
|
||||
bool unreachable = visit_cf_list(ctx, &loop->body);
|
||||
|
||||
//TODO: what if a loop ends with a unconditional or uniformly branched continue and this branch is never taken?
|
||||
if (!ctx->cf_info.has_branch) {
|
||||
@@ -8611,8 +8611,11 @@ static void visit_loop(isel_context *ctx, nir_loop *loop)
|
||||
bld.branch(aco_opcode::p_branch);
|
||||
}
|
||||
|
||||
/* fixup phis in loop header from unreachable blocks */
|
||||
if (ctx->cf_info.has_branch || ctx->cf_info.parent_loop.has_divergent_branch) {
|
||||
/* Fixup phis in loop header from unreachable blocks.
|
||||
* has_branch/has_divergent_branch also indicates if the loop ends with a
|
||||
* break/continue instruction, but we don't emit those if unreachable=true */
|
||||
if (unreachable) {
|
||||
assert(ctx->cf_info.has_branch || ctx->cf_info.parent_loop.has_divergent_branch);
|
||||
bool linear = ctx->cf_info.has_branch;
|
||||
bool logical = ctx->cf_info.has_branch || ctx->cf_info.parent_loop.has_divergent_branch;
|
||||
for (aco_ptr<Instruction>& instr : ctx->program->blocks[loop_header_idx].instructions) {
|
||||
@@ -8956,7 +8959,7 @@ static bool visit_if(isel_context *ctx, nir_if *if_stmt)
|
||||
}
|
||||
}
|
||||
|
||||
static void visit_cf_list(isel_context *ctx,
|
||||
static bool visit_cf_list(isel_context *ctx,
|
||||
struct exec_list *list)
|
||||
{
|
||||
foreach_list_typed(nir_cf_node, node, node, list) {
|
||||
@@ -8966,7 +8969,7 @@ static void visit_cf_list(isel_context *ctx,
|
||||
break;
|
||||
case nir_cf_node_if:
|
||||
if (!visit_if(ctx, nir_cf_node_as_if(node)))
|
||||
return;
|
||||
return true;
|
||||
break;
|
||||
case nir_cf_node_loop:
|
||||
visit_loop(ctx, nir_cf_node_as_loop(node));
|
||||
@@ -8975,6 +8978,7 @@ static void visit_cf_list(isel_context *ctx,
|
||||
unreachable("unimplemented cf list type");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void export_vs_varying(isel_context *ctx, int slot, bool is_pos, int *next_pos)
|
||||
|
||||
Reference in New Issue
Block a user