diff --git a/src/nouveau/compiler/nak_nir_lower_cf.c b/src/nouveau/compiler/nak_nir_lower_cf.c index 817f6de4d73..8b146f1b0ae 100644 --- a/src/nouveau/compiler/nak_nir_lower_cf.c +++ b/src/nouveau/compiler/nak_nir_lower_cf.c @@ -376,6 +376,39 @@ lower_cf_list(nir_builder *b, nir_def *esc_reg, struct scope *parent_scope, } } +bool +nak_nir_phi_is_divergent(nir_phi_instr *phi) +{ + bool divergent = false; + nir_foreach_phi_src(phi_src, phi) { + /* There is a tricky case we need to care about here where a + * convergent block has a divergent dominator. This can happen + * if, for instance, you have the following loop: + * + * loop { + * if (div) { + * %20 = load_ubo(0, 0); + * } else { + * terminate; + * } + * } + * use(%20); + * + * In this case, the load_ubo() dominates the use() even though + * the load_ubo() exists in divergent control-flow. In this + * case, we simply flag the whole phi divergent because we + * don't want to deal with inserting a r2ur somewhere. + */ + if (phi_src->pred->divergent || phi_src->src.ssa->divergent || + nir_def_block(phi_src->src.ssa)->divergent) { + divergent = true; + break; + } + } + + return divergent; +} + static void recompute_phi_divergence_impl(nir_function_impl *impl) { @@ -388,33 +421,7 @@ recompute_phi_divergence_impl(nir_function_impl *impl) break; nir_phi_instr *phi = nir_instr_as_phi(instr); - - bool divergent = false; - nir_foreach_phi_src(phi_src, phi) { - /* There is a tricky case we need to care about here where a - * convergent block has a divergent dominator. This can happen - * if, for instance, you have the following loop: - * - * loop { - * if (div) { - * %20 = load_ubo(0, 0); - * } else { - * terminate; - * } - * } - * use(%20); - * - * In this case, the load_ubo() dominates the use() even though - * the load_ubo() exists in divergent control-flow. In this - * case, we simply flag the whole phi divergent because we - * don't want to deal with inserting a r2ur somewhere. - */ - if (phi_src->pred->divergent || phi_src->src.ssa->divergent || - nir_def_block(phi_src->src.ssa)->divergent) { - divergent = true; - break; - } - } + bool divergent = nak_nir_phi_is_divergent(phi); if (divergent != phi->def.divergent) { phi->def.divergent = divergent; diff --git a/src/nouveau/compiler/nak_private.h b/src/nouveau/compiler/nak_private.h index 588eb897eb4..896f00d279c 100644 --- a/src/nouveau/compiler/nak_private.h +++ b/src/nouveau/compiler/nak_private.h @@ -370,6 +370,7 @@ bool nak_nir_lower_cmat(nir_shader *shader, const struct nak_compiler *nak); * writing uregs from these blocks. */ bool nak_block_is_divergent(const nir_block *block); +bool nak_nir_phi_is_divergent(nir_phi_instr *phi); void nak_optimize_nir(nir_shader *nir, const struct nak_compiler *nak);