From 087e172179be3b9be89955cd012a26ea770ee9eb Mon Sep 17 00:00:00 2001
From: Jason Ekstrand <jason@jlekstrand.net>
Date: Thu, 1 Dec 2016 13:51:03 -0800
Subject: nir/gcm: Rework the schedule late loop

This fixes a bug in code motion that occurred when the best block is the
same as the schedule early block.  In this case, because we're checking
(lca != def->parent_instr->block) at the top of the loop, we never get to
the check for loop depth so we wouldn't move it out of the loop.  This
commit reworks the loop to be a simple for loop up the dominator chain and
we place the (lca != def->parent_instr->block) check at the end of the
loop.

Reviewed-by: Matt Turner <mattst88@gmail.com>
---
 src/compiler/nir/nir_opt_gcm.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

(limited to 'src/compiler/nir')

diff --git a/src/compiler/nir/nir_opt_gcm.c b/src/compiler/nir/nir_opt_gcm.c
index 77eb8e6da5a..9d7f59c8b33 100644
--- a/src/compiler/nir/nir_opt_gcm.c
+++ b/src/compiler/nir/nir_opt_gcm.c
@@ -326,12 +326,13 @@ gcm_schedule_late_def(nir_ssa_def *def, void *void_state)
     * as far outside loops as we can get.
     */
    nir_block *best = lca;
-   while (lca != def->parent_instr->block) {
-      assert(lca);
-      if (state->blocks[lca->index].loop_depth <
+   for (nir_block *block = lca; block != NULL; block = block->imm_dom) {
+      if (state->blocks[block->index].loop_depth <
           state->blocks[best->index].loop_depth)
-         best = lca;
-      lca = lca->imm_dom;
+         best = block;
+
+      if (block == def->parent_instr->block)
+         break;
    }
    def->parent_instr->block = best;
 
-- 
cgit v1.2.3