Mesa (master): nir/opt_if: Fix opt_if_simplification when else branch has jump

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Jul 22 14:46:32 UTC 2020


Module: Mesa
Branch: master
Commit: 6f94b3da111f65a46126fdb3652474dc4d9cbda5
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=6f94b3da111f65a46126fdb3652474dc4d9cbda5

Author: Danylo Piliaiev <danylo.piliaiev at globallogic.com>
Date:   Thu Jul 16 21:09:08 2020 +0300

nir/opt_if: Fix opt_if_simplification when else branch has jump

Consider the following case:

 if ssa_1 {
    block block_2:
    /* succs: block_4 */
 } else {
    block block_3:
    ...
    break
    /* succs: block_5 */
 }

 block block_4:
 vec1 32 ssa_100 = phi block_2: ssa_2

After block_3 extraction and reinsertion, phi->pred becomes invalid
and isn't updated by reinsertion since it is unreachable from block_3.

Call nir_opt_remove_phis_block before moving block to eliminate single
source phis after the if.

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/3282
Fixes: e3e929f8c342b32dc8f5296adf8fb337866fa40a
Signed-off-by: Danylo Piliaiev <danylo.piliaiev at globallogic.com>
Reviewed-by: Matt Turner <mattst88 at gmail.com>
Reviewed-by: Timothy Arceri <tarceri at itsqueeze.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5945>

---

 src/compiler/nir/nir_opt_if.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/src/compiler/nir/nir_opt_if.c b/src/compiler/nir/nir_opt_if.c
index 9c32ab1cc57..a7feac1db93 100644
--- a/src/compiler/nir/nir_opt_if.c
+++ b/src/compiler/nir/nir_opt_if.c
@@ -931,6 +931,17 @@ opt_if_simplification(nir_builder *b, nir_if *nif)
    nir_block *then_block = nir_if_last_then_block(nif);
    nir_block *else_block = nir_if_last_else_block(nif);
 
+   if (nir_block_ends_in_jump(else_block)) {
+      /* Even though this if statement has a jump on one side, we may still have
+       * phis afterwards.  Single-source phis can be produced by loop unrolling
+       * or dead control-flow passes and are perfectly legal.  Run a quick phi
+       * removal on the block after the if to clean up any such phis.
+       */
+      nir_block *const next_block =
+         nir_cf_node_as_block(nir_cf_node_next(&nif->cf_node));
+      nir_opt_remove_phis_block(next_block);
+   }
+
    rewrite_phi_predecessor_blocks(nif, then_block, else_block, else_block,
                                   then_block);
 



More information about the mesa-commit mailing list