nir: fix crash in loop unroll corner case
authorTimothy Arceri <tarceri@itsqueeze.com>
Mon, 26 Mar 2018 00:41:51 +0000 (11:41 +1100)
committerTimothy Arceri <tarceri@itsqueeze.com>
Tue, 27 Mar 2018 22:59:38 +0000 (09:59 +1100)
commit629ee690addad9b3dc8f68cfff5ae09858f31caf
treea6375d6c88de6e0b24f6f2be11e05177820f631e
parent48f6014903454dcb0e8e05afb41cabf2dbac0585
nir: fix crash in loop unroll corner case

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"
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=105670
src/compiler/nir/nir_opt_loop_unroll.c