nir: fix selection of loop terminator when two or more have the same limit
authorTimothy Arceri <tarceri@itsqueeze.com>
Mon, 4 Jun 2018 06:26:46 +0000 (16:26 +1000)
committerTimothy Arceri <tarceri@itsqueeze.com>
Sat, 30 Jun 2018 00:13:03 +0000 (10:13 +1000)
We need to add loop terminators to the list in the order we come
across them otherwise if two or more have the same exit condition
we will select that last one rather than the first one even though
its unreachable.

This fix is for simple unrolls where we only have a single exit
point. When unrolling these type of loops the unreachable
terminators and their unreachable branch are removed prior to
unrolling. Because of the logic change we also switch some
list access in the complex unrolling logic to avoid breakage.

Fixes: 6772a17acc8e ("nir: Add a loop analysis pass")
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
src/compiler/nir/nir_loop_analyze.c
src/compiler/nir/nir_opt_loop_unroll.c

index 438e1fac3eafbf6d231099b22fa814115a59c6cc..d564296aa678f5627a58dd044aa21b633d54b54f 100644 (file)
@@ -330,8 +330,8 @@ find_loop_terminators(loop_info_state *state)
          nir_loop_terminator *terminator =
             rzalloc(state->loop->info, nir_loop_terminator);
 
-         list_add(&terminator->loop_terminator_link,
-                  &state->loop->info->loop_terminator_list);
+         list_addtail(&terminator->loop_terminator_link,
+                      &state->loop->info->loop_terminator_list);
 
          terminator->nif = nif;
          terminator->break_block = break_blk;
index 04caa7c346dec9e44f1558bfd1282bce07a25b4f..955dfede6947457a336cafa11769fe76504dd856 100644 (file)
@@ -530,14 +530,14 @@ process_loops(nir_shader *sh, nir_cf_node *cf_node, bool *innermost_loop)
          if (num_lt == 2) {
             bool limiting_term_second = true;
             nir_loop_terminator *terminator =
-               list_last_entry(&loop->info->loop_terminator_list,
+               list_first_entry(&loop->info->loop_terminator_list,
                                 nir_loop_terminator, loop_terminator_link);
 
 
             if (terminator->nif == loop->info->limiting_terminator->nif) {
                limiting_term_second = false;
                terminator =
-                  list_first_entry(&loop->info->loop_terminator_list,
+                  list_last_entry(&loop->info->loop_terminator_list,
                                   nir_loop_terminator, loop_terminator_link);
             }