[Mesa-dev] [PATCH] nir: fix crash in loop unroll corner case
Jason Ekstrand
jason at jlekstrand.net
Mon Mar 26 23:44:42 UTC 2018
On Sun, Mar 25, 2018 at 6:32 PM, Timothy Arceri <tarceri at itsqueeze.com>
wrote:
> When an if nesting inside anouther if is optimised away we can
> end up with a loop terminator and following block that looks like
> this:
>
> if ssa_596 {
> block block_5:
> /* preds: block_4 */
> vec1 32 ssa_601 = load_const (0xffffffff /* -nan */)
> break
> /* succs: block_8 */
> } else {
> block block_6:
> /* preds: block_4 */
> /* succs: block_7 */
> }
> block block_7:
> /* preds: block_6 */
> vec1 32 ssa_602 = phi block_6: ssa_552
> vec1 32 ssa_603 = phi block_6: ssa_553
> vec1 32 ssa_604 = iadd ssa_551, ssa_66
>
> The problem is the phis. Loop unrolling expects the last block in
> the loop to be empty once we splice the instructions in the last
> block into the continue branch. The problem is we cant move phis
> so here we lower the phis to regs when preparing the loop for
> unrolling. As it could be possible to have multiple additional
> blocks/ifs following the terminator we just convert all phis at
> the top level of the loop body for simplicity.
>
> We also add some comments to loop_prepare_for_unroll() while we
> are here.
>
> Fixes: 51daccb289eb "nir: add a loop unrolling pass"
>
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=105670
> ---
> src/compiler/nir/nir_opt_loop_unroll.c | 17 ++++++++++++-----
> 1 file changed, 12 insertions(+), 5 deletions(-)
>
> diff --git a/src/compiler/nir/nir_opt_loop_unroll.c
> b/src/compiler/nir/nir_opt_loop_unroll.c
> index 79d04f978bc..85df3097264 100644
> --- a/src/compiler/nir/nir_opt_loop_unroll.c
> +++ b/src/compiler/nir/nir_opt_loop_unroll.c
> @@ -37,10 +37,10 @@
> #define LOOP_UNROLL_LIMIT 26
>
> /* Prepare this loop for unrolling by first converting to lcssa and then
> - * converting the phis from the loops first block and the block that
> follows
> - * the loop into regs. Partially converting out of SSA allows us to
> unroll
> - * the loop without having to keep track of and update phis along the way
> - * which gets tricky and doesn't add much value over conveting to regs.
> + * converting the phis from the top level of the loop body to regs.
> + * Partially converting out of SSA allows us to unroll the loop without
> having
> + * to keep track of and update phis along the way which gets tricky and
> + * doesn't add much value over conveting to regs.
>
converting
> *
> * The loop may have a continue instruction at the end of the loop which
> does
> * nothing. Once we're out of SSA, we can safely delete it so we don't
> have
> @@ -51,13 +51,20 @@ loop_prepare_for_unroll(nir_loop *loop)
> {
> nir_convert_loop_to_lcssa(loop);
>
> - nir_lower_phis_to_regs_block(nir_loop_first_block(loop));
> + /* Lower phis at the top level of the loop body */
> + foreach_list_typed_safe(nir_cf_node, node, node, &loop->body) {
> + if (nir_cf_node_block == node->type) {
> + nir_lower_phis_to_regs_block(nir_cf_node_as_block(node));
> + }
> + }
>
This is a bit of a big hammer and I don't really like it for that but it
does work. We could predicate it on block->predecessors->entries == 1 or
we could try and do something even more clever. That said, this is tricky
and what you've done is robust so I'm ok with it as-is.
Reviewed-by: Jason Ekstrand <jason at jlekstrand.net>
> + /* Lower phis after the loop */
> nir_block *block_after_loop =
> nir_cf_node_as_block(nir_cf_node_next(&loop->cf_node));
>
> nir_lower_phis_to_regs_block(block_after_loop);
>
> + /* Remove continue if its the last instruction in the loop */
> nir_instr *last_instr = nir_block_last_instr(nir_loop_
> last_block(loop));
> if (last_instr && last_instr->type == nir_instr_type_jump) {
> assert(nir_instr_as_jump(last_instr)->type == nir_jump_continue);
> --
> 2.14.3
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20180326/95a0a0ac/attachment.html>
More information about the mesa-dev
mailing list