Mesa (main): ir3/lower_pcopy: Fix bug with "illegal" copies and swaps

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Nov 19 17:23:03 UTC 2021


Module: Mesa
Branch: main
Commit: c98adc56f4fe08231b0fec84b6a92c89eb94d59b
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=c98adc56f4fe08231b0fec84b6a92c89eb94d59b

Author: Connor Abbott <cwabbott0 at gmail.com>
Date:   Tue Nov 16 15:20:52 2021 +0100

ir3/lower_pcopy: Fix bug with "illegal" copies and swaps

If the source and destination were within the same full register, like
hr90.x and hr90.y (which both map to r45.x), then we'd perform the
swap/copy with the wrong register. This broke
dEQP-VK.ssbo.phys.layout.random.16bit.scalar.35 once BDA is enabled.

Fixes: 0ffcb19b9d9 ("ir3: Rewrite register allocation")
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13818>

---

 src/freedreno/ir3/ir3_lower_parallelcopy.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/src/freedreno/ir3/ir3_lower_parallelcopy.c b/src/freedreno/ir3/ir3_lower_parallelcopy.c
index b927e031a17..fbcd6ff62a6 100644
--- a/src/freedreno/ir3/ir3_lower_parallelcopy.c
+++ b/src/freedreno/ir3/ir3_lower_parallelcopy.c
@@ -109,11 +109,18 @@ do_swap(struct ir3_compiler *compiler, struct ir3_instruction *instr,
                     .flags = entry->flags & ~IR3_REG_HALF,
                  });
 
+         /* If src and dst are within the same full register, then swapping src
+          * with tmp above will also move dst to tmp. Account for that here.
+          */
+         unsigned dst =
+            (entry->src.reg & ~1u) == (entry->dst & ~1u) ?
+            tmp + (entry->dst & 1u) : entry->dst;
+
          /* Do the original swap with src replaced with tmp */
          do_swap(compiler, instr,
                  &(struct copy_entry){
                     .src = {.reg = tmp + (entry->src.reg & 1)},
-                    .dst = entry->dst,
+                    .dst = dst,
                     .flags = entry->flags,
                  });
 
@@ -192,9 +199,16 @@ do_copy(struct ir3_compiler *compiler, struct ir3_instruction *instr,
                     .flags = entry->flags & ~IR3_REG_HALF,
                  });
 
+         /* Similar to in do_swap(), account for src being swapped with tmp if
+          * src and dst are in the same register.
+          */
+         struct copy_src src = entry->src;
+         if (!src.flags && (src.reg & ~1u) == (entry->dst & ~1u))
+            src.reg = tmp + (src.reg & 1u);
+
          do_copy(compiler, instr,
                  &(struct copy_entry){
-                    .src = entry->src,
+                    .src = src,
                     .dst = tmp + (entry->dst & 1),
                     .flags = entry->flags,
                  });



More information about the mesa-commit mailing list