diff options
Diffstat (limited to 'src/freedreno/ir3/ir3_lower_parallelcopy.c')
-rw-r--r-- | src/freedreno/ir3/ir3_lower_parallelcopy.c | 18 |
1 files 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, }); |