From dd788d0a7fa78eeb28092d1a337cfb3a5876758c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Wed, 13 Nov 2024 19:32:49 -0500 Subject: [PATCH] nir/opt_varyings: remove rare dead output stores after inter-shader code motion Backward inter-shader code motion left dead output stores in the producer in rare cases. Those dead stores would then make their way into drivers and hw. Reviewed-by: Alyssa Rosenzweig Part-of: --- src/compiler/nir/nir_opt_varyings.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/compiler/nir/nir_opt_varyings.c b/src/compiler/nir/nir_opt_varyings.c index 4d069f50885..abe05c241e8 100644 --- a/src/compiler/nir/nir_opt_varyings.c +++ b/src/compiler/nir/nir_opt_varyings.c @@ -3774,6 +3774,32 @@ try_move_postdominator(struct linkage_info *linkage, * in final_slot) */ remove_all_stores_and_clear_slot(linkage, slot_index, progress); + } else { + /* If a load has 2 uses and one of those uses is moved into the previous + * shader, making that "use" dead, the load and its associated store + * can't be removed because there is still one use remaining. However, + * there are actually 2 uses remaining because the use that is dead isn't + * removed from NIR, but is left dangling there. + * + * When we run this optimization again and make the second use dead, + * which makes the load dead, the output store in the producer isn't removed + * because the post-dominator of the second use doesn't post-dominate + * the load because we left the first use dangling there. + * + * To fix that, we could run DCE, but that would be costly because we would + * need to re-gather all IO. Instead, remove dead uses by replacing them + * with undef here, so that when this code motion pass is entered again, + * the load has its number of uses reduced and the corresponding output store + * will be removed by the code above. + */ + nir_foreach_use_safe(src, nir_instr_def(load)) { + if (nir_instr_dominates_use(postdom_state, postdom, + nir_src_parent_instr(src))) { + nir_src_rewrite(src, nir_undef(&linkage->consumer_builder, + src->ssa->num_components, + src->ssa->bit_size)); + } + } } }