summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorConnor Abbott <cwabbott0@gmail.com>2021-11-16 15:20:52 +0100
committerEric Engestrom <eric@engestrom.ch>2021-12-01 18:55:47 +0000
commitd3d950ce4adfa7f2504cd715f67f9c7a076d1dba (patch)
tree7adce3e3da4cf9c1ef249c7d895e277bf624d685
parentc6bdf7a811c507431c9dd178055c2168640564f3 (diff)
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> (cherry picked from commit c98adc56f4fe08231b0fec84b6a92c89eb94d59b)
-rw-r--r--.pick_status.json2
-rw-r--r--src/freedreno/ir3/ir3_lower_parallelcopy.c18
2 files changed, 17 insertions, 3 deletions
diff --git a/.pick_status.json b/.pick_status.json
index 326f0768d3e..603e0a56b49 100644
--- a/.pick_status.json
+++ b/.pick_status.json
@@ -2029,7 +2029,7 @@
"description": "ir3/lower_pcopy: Fix bug with \"illegal\" copies and swaps",
"nominated": true,
"nomination_type": 1,
- "resolution": 0,
+ "resolution": 1,
"main_sha": null,
"because_sha": "0ffcb19b9d9fbe902224542047c389a661fbf816"
},
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,
});