Mesa (master): nir: properly find the entry to keep in copy_prop_vars

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Dec 19 17:46:06 UTC 2018


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

Author: Caio Marcelo de Oliveira Filho <caio.oliveira at intel.com>
Date:   Fri Dec 14 16:10:32 2018 -0800

nir: properly find the entry to keep in copy_prop_vars

When copy propagation handles a store/copy, it iterates the current
copy entries to remove aliases, but keeps the "equal" entry (if
exists) to be updated.

The removal step may swap the entries around (to ensure there are no
holes), invalidating previous iteration pointers.  The bug was saving
such pointer to use later.  Change the code to first perform the
removals and then find the remaining right entry.

This was causing updates to be lost since they were being made to an
entry that was not part of the current copies.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=108624
Fixes: b3c61469255 "nir: Copy propagation between blocks"
Cc: mesa-stable at lists.freedesktop.org
Reviewed-by: Jason Ekstrand <jason at jlekstrand.net>

---

 src/compiler/nir/nir_opt_copy_prop_vars.c | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/src/compiler/nir/nir_opt_copy_prop_vars.c b/src/compiler/nir/nir_opt_copy_prop_vars.c
index ce106be8de..771f125650 100644
--- a/src/compiler/nir/nir_opt_copy_prop_vars.c
+++ b/src/compiler/nir/nir_opt_copy_prop_vars.c
@@ -280,7 +280,7 @@ lookup_entry_and_kill_aliases(struct util_dynarray *copies,
 {
    /* TODO: Take into account the write_mask. */
 
-   struct copy_entry *entry = NULL;
+   nir_deref_instr *dst_match = NULL;
    util_dynarray_foreach_reverse(copies, struct copy_entry, iter) {
       if (!iter->src.is_ssa) {
          /* If this write aliases the source of some entry, get rid of it */
@@ -293,13 +293,26 @@ lookup_entry_and_kill_aliases(struct util_dynarray *copies,
       nir_deref_compare_result comp = nir_compare_derefs(iter->dst, deref);
 
       if (comp & nir_derefs_equal_bit) {
-         assert(entry == NULL);
-         entry = iter;
+         /* Removing entries invalidate previous iter pointers, so we'll
+          * collect the matching entry later.  Just make sure it is unique.
+          */
+         assert(!dst_match);
+         dst_match = iter->dst;
       } else if (comp & nir_derefs_may_alias_bit) {
          copy_entry_remove(copies, iter);
       }
    }
 
+   struct copy_entry *entry = NULL;
+   if (dst_match) {
+      util_dynarray_foreach(copies, struct copy_entry, iter) {
+         if (iter->dst == dst_match) {
+            entry = iter;
+            break;
+         }
+      }
+      assert(entry);
+   }
    return entry;
 }
 




More information about the mesa-commit mailing list