Module: Mesa Branch: staging/20.0 Commit: f130cbe7168269e0e42bebc240a4ab3567fe630b URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=f130cbe7168269e0e42bebc240a4ab3567fe630b
Author: Rhys Perry <[email protected]> Date: Fri Jan 31 16:39:20 2020 +0000 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 <[email protected]> CC: <[email protected]> Reviewed-by: Daniel Schürmann <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/3658> (cherry picked from commit 8d8c864beba399ae4ee2267f680d1f600ad32767) --- .pick_status.json | 2 +- src/amd/compiler/aco_instruction_selection.cpp | 16 ++++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index 20e6dc2f2a6..39f357da526 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -472,7 +472,7 @@ "description": "aco: improve check for unreachable loop continue blocks", "nominated": true, "nomination_type": 0, - "resolution": 0, + "resolution": 1, "master_sha": null, "because_sha": null }, diff --git a/src/amd/compiler/aco_instruction_selection.cpp b/src/amd/compiler/aco_instruction_selection.cpp index f0e95d1fc1f..f6ebb72e950 100644 --- a/src/amd/compiler/aco_instruction_selection.cpp +++ b/src/amd/compiler/aco_instruction_selection.cpp @@ -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) @@ -7942,7 +7942,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) { @@ -7987,8 +7987,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) { @@ -8314,7 +8317,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) { @@ -8324,7 +8327,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)); @@ -8333,6 +8336,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) _______________________________________________ mesa-commit mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-commit
