Mesa (main): aco: emit nir_intrinsic_discard() as p_discard_if()

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Feb 8 16:39:36 UTC 2022


Module: Mesa
Branch: main
Commit: b67092e685cdd35e3505607d2bef3dbc62cb295a
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=b67092e685cdd35e3505607d2bef3dbc62cb295a

Author: Daniel Schürmann <daniel at schuermann.dev>
Date:   Mon Jan 31 14:26:50 2022 +0100

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 at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14805>

---

 src/amd/compiler/aco_insert_exec_mask.cpp      | 27 ++++++++++++-------
 src/amd/compiler/aco_instruction_selection.cpp | 37 +++-----------------------
 2 files changed, 22 insertions(+), 42 deletions(-)

diff --git a/src/amd/compiler/aco_insert_exec_mask.cpp b/src/amd/compiler/aco_insert_exec_mask.cpp
index 56e7045b852..55f9accb0bb 100644
--- a/src/amd/compiler/aco_insert_exec_mask.cpp
+++ b/src/amd/compiler/aco_insert_exec_mask.cpp
@@ -718,18 +718,27 @@ process_instructions(exec_ctx& ctx, Block* block, std::vector<aco_ptr<Instructio
             transition_to_WQM(ctx, bld, block->index);
             ctx.info[block->index].exec.back().second &= ~mask_type_global;
          }
-         int num = ctx.info[block->index].exec.size();
-         assert(num);
 
-         /* discard from current exec */
-         const Operand cond = instr->operands[0];
-         Temp exit_cond = bld.sop2(Builder::s_andn2, Definition(exec, bld.lm), bld.def(s1, scc),
-                                   Operand(exec, bld.lm), cond)
-                             .def(1)
-                             .getTemp();
+         Temp cond, exit_cond;
+         if (instr->operands[0].isConstant()) {
+            assert(instr->operands[0].constantValue() == -1u);
+            /* save condition and set exec to zero */
+            exit_cond = bld.tmp(s1);
+            cond =
+               bld.sop1(Builder::s_and_saveexec, bld.def(bld.lm), bld.scc(Definition(exit_cond)),
+                        Definition(exec, bld.lm), Operand::zero(), Operand(exec, bld.lm));
+         } else {
+            cond = instr->operands[0].getTemp();
+            /* discard from current exec */
+            exit_cond = bld.sop2(Builder::s_andn2, Definition(exec, bld.lm), bld.def(s1, scc),
+                                 Operand(exec, bld.lm), cond)
+                           .def(1)
+                           .getTemp();
+         }
 
          /* discard from inner to outer exec mask on stack */
-         for (int i = num - 2; i >= 0; i--) {
+         int num = ctx.info[block->index].exec.size() - 2;
+         for (int i = num; i >= 0; i--) {
             Instruction* andn2 = bld.sop2(Builder::s_andn2, bld.def(bld.lm), bld.def(s1, scc),
                                           ctx.info[block->index].exec[i].first, cond);
             ctx.info[block->index].exec[i].first = Operand(andn2->definitions[0].getTemp());
diff --git a/src/amd/compiler/aco_instruction_selection.cpp b/src/amd/compiler/aco_instruction_selection.cpp
index d8af3d9e76b..bf202bebc1e 100644
--- a/src/amd/compiler/aco_instruction_selection.cpp
+++ b/src/amd/compiler/aco_instruction_selection.cpp
@@ -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 {



More information about the mesa-commit mailing list