nir/lcssa: allow to create LCSSA phis for loop-invariant booleans
authorRhys Perry <pendingchaos02@gmail.com>
Mon, 5 Aug 2019 14:24:18 +0000 (15:24 +0100)
committerDaniel Schürmann <daniel@schuermann.dev>
Tue, 20 Aug 2019 15:40:05 +0000 (17:40 +0200)
ACO depends on LCSSA phis for divergent booleans to work correctly.

Reviewed-by: Connor Abbott <cwabbott0@gmail.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
src/compiler/nir/nir.h
src/compiler/nir/nir_to_lcssa.c

index 6146445..57326fe 100644 (file)
@@ -3923,7 +3923,7 @@ bool nir_repair_ssa_impl(nir_function_impl *impl);
 bool nir_repair_ssa(nir_shader *shader);
 
 void nir_convert_loop_to_lcssa(nir_loop *loop);
-bool nir_convert_to_lcssa(nir_shader *shader, bool skip_invariants);
+bool nir_convert_to_lcssa(nir_shader *shader, bool skip_invariants, bool skip_bool_invariants);
 
 /* If phi_webs_only is true, only convert SSA values involved in phi nodes to
  * registers.  If false, convert all values (even those not involved in a phi
index e66d89a..e5b760c 100644 (file)
@@ -48,6 +48,7 @@ typedef struct {
 
    /* Whether to skip loop invariant variables */
    bool skip_invariants;
+   bool skip_bool_invariants;
 
    bool progress;
 } lcssa_state;
@@ -193,7 +194,8 @@ convert_loop_exit_for_ssa(nir_ssa_def *def, void *void_state)
    bool all_uses_inside_loop = true;
 
    /* Don't create LCSSA-Phis for loop-invariant variables */
-   if (state->skip_invariants) {
+   if (state->skip_invariants &&
+       (def->bit_size != 1 || state->skip_bool_invariants)) {
       assert(def->parent_instr->pass_flags != undefined);
       if (def->parent_instr->pass_flags == invariant)
          return true;
@@ -361,6 +363,7 @@ nir_convert_loop_to_lcssa(nir_loop *loop)
    state->loop = loop;
    state->shader = impl->function->shader;
    state->skip_invariants = false;
+   state->skip_bool_invariants = false;
 
    nir_foreach_block_in_cf_node (block, &loop->cf_node) {
       nir_foreach_instr(instr, block)
@@ -371,12 +374,13 @@ nir_convert_loop_to_lcssa(nir_loop *loop)
 }
 
 bool
-nir_convert_to_lcssa(nir_shader *shader, bool skip_invariants)
+nir_convert_to_lcssa(nir_shader *shader, bool skip_invariants, bool skip_bool_invariants)
 {
    bool progress = false;
    lcssa_state *state = rzalloc(NULL, lcssa_state);
    state->shader = shader;
    state->skip_invariants = skip_invariants;
+   state->skip_bool_invariants = skip_bool_invariants;
 
    nir_foreach_function(function, shader) {
       if (function->impl == NULL)