Module: Mesa
Branch: master
Commit: 72b307a3389b8940ec639c3086fcef79f778b7e5
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=72b307a3389b8940ec639c3086fcef79f778b7e5

Author: Rhys Perry <[email protected]>
Date:   Mon Oct 19 11:03:34 2020 +0100

aco: don't do divergent break+discard

If the shader does:
loop {
   if (divergent)
      discard
   else
      a()
   b()
}
then a()'s block will dominate b()'s block in the logical CFG, but not the
linear CFG. This will cause value numbering to try to combine SLAU from
a() and b().

This didn't happen with break/continue because sanitize_if() would move
a() out of the branch. Using sanitize_if() to fix this doesn't look easy,
because discards are not control flow instructions in NIR.

No fossil-db changes.

Signed-off-by: Rhys Perry <[email protected]>
Reviewed-by: Daniel Schürmann <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7216>

---

 src/amd/compiler/aco_instruction_selection.cpp | 40 ++++----------------------
 1 file changed, 6 insertions(+), 34 deletions(-)

diff --git a/src/amd/compiler/aco_instruction_selection.cpp 
b/src/amd/compiler/aco_instruction_selection.cpp
index 38ea21c3817..4de0fe69e8a 100644
--- a/src/amd/compiler/aco_instruction_selection.cpp
+++ b/src/amd/compiler/aco_instruction_selection.cpp
@@ -5263,8 +5263,7 @@ void visit_discard(isel_context* ctx, nir_intrinsic_instr 
*instr)
    bool divergent = ctx->cf_info.parent_if.is_divergent ||
                     ctx->cf_info.parent_loop.has_divergent_continue;
 
-   if (ctx->block->loop_nest_depth &&
-       ((nir_instr_is_last(&instr->instr) && !divergent) || divergent)) {
+   if (ctx->block->loop_nest_depth && (nir_instr_is_last(&instr->instr) && 
!divergent)) {
       /* we handle discards the same way as jump instructions */
       append_logical_end(ctx->block);
 
@@ -5272,39 +5271,12 @@ void visit_discard(isel_context* ctx, 
nir_intrinsic_instr *instr)
       Block *linear_target = ctx->cf_info.parent_loop.exit;
       ctx->block->kind |= block_kind_discard;
 
-      if (!divergent) {
-         /* uniform discard - loop ends here */
-         assert(nir_instr_is_last(&instr->instr));
-         ctx->block->kind |= block_kind_uniform;
-         ctx->cf_info.has_branch = true;
-         bld.branch(aco_opcode::p_branch, bld.hint_vcc(bld.def(s2)));
-         add_linear_edge(ctx->block->index, linear_target);
-         return;
-      }
-
-      /* we add a break right behind the discard() instructions */
-      ctx->block->kind |= block_kind_break;
-      unsigned idx = ctx->block->index;
-
-      ctx->cf_info.parent_loop.has_divergent_branch = true;
-      ctx->cf_info.nir_to_aco[instr->instr.block->index] = idx;
-
-      /* remove critical edges from linear CFG */
-      bld.branch(aco_opcode::p_branch, bld.hint_vcc(bld.def(s2)));
-      Block* break_block = ctx->program->create_and_insert_block();
-      break_block->loop_nest_depth = ctx->cf_info.loop_nest_depth;
-      break_block->kind |= block_kind_uniform;
-      add_linear_edge(idx, break_block);
-      add_linear_edge(break_block->index, linear_target);
-      bld.reset(break_block);
+      /* uniform discard - loop ends here */
+      assert(nir_instr_is_last(&instr->instr));
+      ctx->block->kind |= block_kind_uniform;
+      ctx->cf_info.has_branch = true;
       bld.branch(aco_opcode::p_branch, bld.hint_vcc(bld.def(s2)));
-
-      Block* continue_block = ctx->program->create_and_insert_block();
-      continue_block->loop_nest_depth = ctx->cf_info.loop_nest_depth;
-      add_linear_edge(idx, continue_block);
-      append_logical_start(continue_block);
-      ctx->block = continue_block;
-
+      add_linear_edge(ctx->block->index, linear_target);
       return;
    }
 

_______________________________________________
mesa-commit mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to