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)
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) {
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) {
}
}
-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) {
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));
unreachable("unimplemented cf list type");
}
}
+ return false;
}
static void export_vs_varying(isel_context *ctx, int slot, bool is_pos, int *next_pos)