nir: Handle register sources in lower_phis_to_regs_block
authorJason Ekstrand <jason.ekstrand@collabora.com>
Fri, 22 Apr 2022 21:37:37 +0000 (16:37 -0500)
committerMarge Bot <emma+marge@anholt.net>
Tue, 31 May 2022 14:12:21 +0000 (14:12 +0000)
During certain control-flow manipulation passes, we go out-of-SSA
temporarily in certain areas of the code to make control-flow
manipulation easier.  This can result in registers being in phi sources
temporarily.  If two sub-passes run before we get a chance to do
clean-up, we can end up doing some out-of-SSA and then a bit more
out-of-SSA and trigger this case.  It's easy enough to handle.

Fixes: a620f66872c2 ("nir: Add a couple quick-and-dirty out-of-SSA helpers")
Fixes: 79a987ad2a1e ("nir/opt_if: also merge break statements with ones after the branch")
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/6370
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16111>

src/compiler/nir/nir_from_ssa.c

index 707e670..9ad45cb 100644 (file)
@@ -1006,10 +1006,16 @@ nir_lower_phis_to_regs_block(nir_block *block)
       nir_ssa_def_rewrite_uses(&phi->dest.ssa, def);
 
       nir_foreach_phi_src(src, phi) {
-         assert(src->src.is_ssa);
-         _mesa_set_add(visited_blocks, src->src.ssa->parent_instr->block);
-         place_phi_read(&b, reg, src->src.ssa, src->pred, visited_blocks);
-         _mesa_set_clear(visited_blocks, NULL);
+         if (src->src.is_ssa) {
+            _mesa_set_add(visited_blocks, src->src.ssa->parent_instr->block);
+            place_phi_read(&b, reg, src->src.ssa, src->pred, visited_blocks);
+            _mesa_set_clear(visited_blocks, NULL);
+         } else {
+            b.cursor = nir_after_block_before_jump(src->pred);
+            nir_ssa_def *src_ssa =
+               nir_ssa_for_src(&b, src->src, phi->dest.ssa.num_components);
+            nir_store_reg(&b, reg, src_ssa, ~0);
+         }
       }
 
       nir_instr_remove(&phi->instr);