nak: add nak_nir_phi_is_divergent helper

This commit is contained in:
Karol Herbst 2026-03-17 00:37:22 +01:00 committed by Karol Herbst
parent 0fc02a8b69
commit 584ba918a1
2 changed files with 35 additions and 27 deletions

View file

@ -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;

View file

@ -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);