summaryrefslogtreecommitdiffstats
path: root/src/compiler
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2019-07-10 15:14:42 -0500
committerJason Ekstrand <[email protected]>2019-07-15 19:58:51 +0000
commit7a19e05e8c84152af3a15868f5ef781142ac8e23 (patch)
tree6e977c722160041254906cbea83c68c72dacd02a /src/compiler
parented98f8a63a578a425a1af641baa54ea4ad855775 (diff)
nir/opt_if: Clean up single-src phis in opt_if_loop_terminator
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=111071 Fixes: 2a74296f24ba "nir: add opt_if_loop_terminator()" Reviewed-by: Timothy Arceri <[email protected]>
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/nir/nir.h1
-rw-r--r--src/compiler/nir/nir_opt_if.c7
-rw-r--r--src/compiler/nir/nir_opt_remove_phis.c8
3 files changed, 16 insertions, 0 deletions
diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index bc7ae1cc03e..2719087e9a4 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -3882,6 +3882,7 @@ bool nir_opt_peephole_select(nir_shader *shader, unsigned limit,
bool nir_opt_rematerialize_compares(nir_shader *shader);
bool nir_opt_remove_phis(nir_shader *shader);
+bool nir_opt_remove_phis_block(nir_block *block);
bool nir_opt_shrink_load(nir_shader *shader);
diff --git a/src/compiler/nir/nir_opt_if.c b/src/compiler/nir/nir_opt_if.c
index 6d488bd76a3..e360c274bc9 100644
--- a/src/compiler/nir/nir_opt_if.c
+++ b/src/compiler/nir/nir_opt_if.c
@@ -1039,6 +1039,13 @@ opt_if_loop_terminator(nir_if *nif)
if (!nir_is_trivial_loop_if(nif, break_blk))
return false;
+ /* 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_opt_remove_phis_block(nir_cf_node_as_block(nir_cf_node_next(&nif->cf_node)));
+
/* Finally, move the continue from branch after the if-statement. */
nir_cf_list tmp;
nir_cf_extract(&tmp, nir_before_block(first_continue_from_blk),
diff --git a/src/compiler/nir/nir_opt_remove_phis.c b/src/compiler/nir/nir_opt_remove_phis.c
index dd557396ec1..a3186116798 100644
--- a/src/compiler/nir/nir_opt_remove_phis.c
+++ b/src/compiler/nir/nir_opt_remove_phis.c
@@ -137,6 +137,14 @@ remove_phis_block(nir_block *block, nir_builder *b)
return progress;
}
+bool
+nir_opt_remove_phis_block(nir_block *block)
+{
+ nir_builder b;
+ nir_builder_init(&b, nir_cf_node_get_function(&block->cf_node));
+ return remove_phis_block(block, &b);
+}
+
static bool
nir_opt_remove_phis_impl(nir_function_impl *impl)
{