From 40f96460eeebbf936e31c2ae7478453064a1e93b Mon Sep 17 00:00:00 2001 From: Georg Lehmann Date: Mon, 17 Feb 2025 18:10:14 +0100 Subject: [PATCH] nir/peephole_select: handle demote and terminate in nir_opt_collapse_if MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Daniel Schürmann Reviewed-by: Alyssa Rosenzweig Part-of: --- src/compiler/nir/nir_opt_peephole_select.c | 72 ++++++++++++---------- 1 file changed, 38 insertions(+), 34 deletions(-) diff --git a/src/compiler/nir/nir_opt_peephole_select.c b/src/compiler/nir/nir_opt_peephole_select.c index db60025da26..613fa112346 100644 --- a/src/compiler/nir/nir_opt_peephole_select.c +++ b/src/compiler/nir/nir_opt_peephole_select.c @@ -282,6 +282,39 @@ block_check_for_allowed_instrs(nir_block *block, unsigned *count, return true; } +/* If we're moving discards out of the if for non-CF hardware, we need to add + * the if's condition to it + */ +static void +rewrite_discard_conds(nir_instr *instr, nir_def *if_cond, bool is_else) +{ + if (instr->type != nir_instr_type_intrinsic) + return; + nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr); + + if (intr->intrinsic != nir_intrinsic_terminate_if && + intr->intrinsic != nir_intrinsic_terminate && + intr->intrinsic != nir_intrinsic_demote_if && + intr->intrinsic != nir_intrinsic_demote) + return; + + nir_builder b = nir_builder_at(nir_before_instr(instr)); + + if (is_else) + if_cond = nir_inot(&b, if_cond); + + if (intr->intrinsic == nir_intrinsic_terminate_if || + intr->intrinsic == nir_intrinsic_demote_if) { + nir_src_rewrite(&intr->src[0], nir_iand(&b, intr->src[0].ssa, if_cond)); + } else { + if (intr->intrinsic == nir_intrinsic_terminate) + nir_terminate_if(&b, if_cond); + else + nir_demote_if(&b, if_cond); + nir_instr_remove(instr); + } +} + /** * Try to collapse nested ifs: * This optimization turns @@ -388,7 +421,11 @@ nir_opt_collapse_if(nir_if *if_stmt, nir_shader *shader, unsigned limit, } } - /* combine the conditions */ + /* combine condition with potential demote/terminate */ + nir_foreach_instr_safe(instr, first) + rewrite_discard_conds(instr, parent_if->condition.ssa, false); + + /* combine the if conditions */ struct nir_builder b = nir_builder_at(nir_before_cf_node(&if_stmt->cf_node)); nir_def *cond = nir_iand(&b, if_stmt->condition.ssa, parent_if->condition.ssa); @@ -404,39 +441,6 @@ nir_opt_collapse_if(nir_if *if_stmt, nir_shader *shader, unsigned limit, return true; } -/* If we're moving discards out of the if for non-CF hardware, we need to add - * the if's condition to it - */ -static void -rewrite_discard_conds(nir_instr *instr, nir_def *if_cond, bool is_else) -{ - if (instr->type != nir_instr_type_intrinsic) - return; - nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr); - - if (intr->intrinsic != nir_intrinsic_terminate_if && - intr->intrinsic != nir_intrinsic_terminate && - intr->intrinsic != nir_intrinsic_demote_if && - intr->intrinsic != nir_intrinsic_demote) - return; - - nir_builder b = nir_builder_at(nir_before_instr(instr)); - - if (is_else) - if_cond = nir_inot(&b, if_cond); - - if (intr->intrinsic == nir_intrinsic_terminate_if || - intr->intrinsic == nir_intrinsic_demote_if) { - nir_src_rewrite(&intr->src[0], nir_iand(&b, intr->src[0].ssa, if_cond)); - } else { - if (intr->intrinsic == nir_intrinsic_terminate) - nir_terminate_if(&b, if_cond); - else - nir_demote_if(&b, if_cond); - nir_instr_remove(instr); - } -} - static bool nir_opt_peephole_select_block(nir_block *block, nir_shader *shader, unsigned limit, bool indirect_load_ok,