aco: emit nir_intrinsic_discard() as p_discard_if()

This simplifies the code and emits a slightly better
sequence in some cases.

Reviewed-by: Rhys Perry <pendingchaos02@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14805>
This commit is contained in:
Daniel Schürmann
2022-01-31 14:26:50 +01:00
committed by Marge Bot
parent 1895e17591
commit b67092e685
2 changed files with 22 additions and 42 deletions
+4 -33
View File
@@ -5754,39 +5754,10 @@ visit_discard(isel_context* ctx, nir_intrinsic_instr* instr)
return;
}
/* it can currently happen that NIR doesn't remove the unreachable code */
if (!nir_instr_is_last(&instr->instr)) {
ctx->program->needs_exact = true;
/* save exec somewhere temporarily so that it doesn't get
* overwritten before the discard from outer exec masks */
Temp cond = bld.sop2(Builder::s_and, bld.def(bld.lm), bld.def(s1, scc),
Operand::c32(0xFFFFFFFF), Operand(exec, bld.lm));
bld.pseudo(aco_opcode::p_discard_if, cond);
ctx->block->kind |= block_kind_uses_discard_if;
return;
}
/* This condition is incorrect for uniformly branched discards in a loop
* predicated by a divergent condition, but the above code catches that case
* and the discard would end up turning into a discard_if.
* For example:
* if (divergent) {
* while (...) {
* if (uniform) {
* discard;
* }
* }
* }
*/
if (!ctx->cf_info.parent_if.is_divergent) {
/* program just ends here */
ctx->block->kind |= block_kind_uses_discard_if;
bld.pseudo(aco_opcode::p_discard_if, Operand::c32(0xFFFFFFFFu));
// TODO: it will potentially be followed by a branch which is dead code to sanitize NIR phis
} else {
ctx->block->kind |= block_kind_discard;
/* branch and linear edge is added by visit_if() */
}
ctx->program->needs_exact = true;
bld.pseudo(aco_opcode::p_discard_if, Operand::c32(-1u));
ctx->block->kind |= block_kind_uses_discard_if;
return;
}
enum aco_descriptor_type {