summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorConnor Abbott <cwabbott0@gmail.com>2023-10-31 18:06:44 +0100
committerMarge Bot <emma+marge@anholt.net>2024-04-26 12:55:13 +0000
commit81015b262082e3228233e1d142b431b9cfaee883 (patch)
treef7620c67d53e7b3bd8ff9faa2db1b0167bebd238
parentfec5b9397f43ec350b40a1c3a6c013213559bb4a (diff)
ir3/lower_copies: Fix "inaccessible" half reg lowering with shared regs
With shared phi nodes we may start needing this lowering for the same reason normal parallel copies need it. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22075>
-rw-r--r--src/freedreno/ir3/ir3_lower_parallelcopy.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/src/freedreno/ir3/ir3_lower_parallelcopy.c b/src/freedreno/ir3/ir3_lower_parallelcopy.c
index f84be2a5b57..7d8b52a5d64 100644
--- a/src/freedreno/ir3/ir3_lower_parallelcopy.c
+++ b/src/freedreno/ir3/ir3_lower_parallelcopy.c
@@ -88,6 +88,9 @@ do_swap(struct ir3_compiler *compiler, struct ir3_instruction *instr,
assert(!entry->src.flags);
if (entry->flags & IR3_REG_HALF) {
+ const unsigned half_size =
+ (entry->flags & IR3_REG_SHARED) ? RA_SHARED_HALF_SIZE : RA_HALF_SIZE;
+
/* We currently make sure to never emit parallel copies where the
* source/destination is a half-reg above the range accessable to half
* registers. However, when a full-reg source overlaps a half-reg
@@ -97,7 +100,7 @@ do_swap(struct ir3_compiler *compiler, struct ir3_instruction *instr,
* "illegal" swap instead. This may also be useful for implementing
* "spilling" half-regs to the inaccessable space.
*/
- if (entry->src.reg >= RA_HALF_SIZE) {
+ if (entry->src.reg >= half_size) {
/* Choose a temporary that doesn't overlap src or dst */
physreg_t tmp = entry->dst < 2 ? 2 : 0;
@@ -137,7 +140,7 @@ do_swap(struct ir3_compiler *compiler, struct ir3_instruction *instr,
/* If dst is not addressable, we only need to swap the arguments and
* let the case above handle it.
*/
- if (entry->dst >= RA_HALF_SIZE) {
+ if (entry->dst >= half_size) {
do_swap(compiler, instr,
&(struct copy_entry){
.src = {.reg = entry->dst},
@@ -184,7 +187,9 @@ do_copy(struct ir3_compiler *compiler, struct ir3_instruction *instr,
{
if (entry->flags & IR3_REG_HALF) {
/* See do_swap() for why this is here. */
- if (entry->dst >= RA_HALF_SIZE) {
+ const unsigned half_size =
+ (entry->flags & IR3_REG_SHARED) ? RA_SHARED_HALF_SIZE : RA_HALF_SIZE;
+ if (entry->dst >= half_size) {
/* TODO: is there a hw instruction we can use for this case? */
physreg_t tmp = !entry->src.flags && entry->src.reg < 2 ? 2 : 0;
@@ -218,7 +223,7 @@ do_copy(struct ir3_compiler *compiler, struct ir3_instruction *instr,
return;
}
- if (!entry->src.flags && entry->src.reg >= RA_HALF_SIZE) {
+ if (!entry->src.flags && entry->src.reg >= half_size) {
unsigned src_num = ra_physreg_to_num(entry->src.reg & ~1u,
entry->flags & ~IR3_REG_HALF);
unsigned dst_num = ra_physreg_to_num(entry->dst, entry->flags);