diff options
author | Icecream95 <ixn@disroot.org> | 2021-06-07 19:33:54 +1200 |
---|---|---|
committer | Eric Engestrom <eric@engestrom.ch> | 2021-06-18 18:31:43 +0100 |
commit | b6d704d5a1ce1184713b03696b10fcd9c0c9e2eb (patch) | |
tree | 5d00f5397314faf566eafdba01272b675e05aefc /src/panfrost | |
parent | 5c6f340bf5a929335928c709a10abaac674ac79f (diff) |
pan/mdg: Fix reading a spilt register in the bundle it's written
Read directly from the instruction getting spilt. Otherwise a fill
will be inserted before the spill writing the value, so the
instruction reading the spilt value gets garbage data.
Use the bundle_id to check if the instructions are in the same bundle.
Insert a move instruction, as the spill needs the value in a LD/ST
register such as AL0, while the ALU instruction reading the value
needs it in a work register such as R0.
Cc: mesa-stable
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/4857
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11212>
(cherry picked from commit 38e8d7afe30bb33218191ac681607de48753fbae)
Diffstat (limited to 'src/panfrost')
-rw-r--r-- | src/panfrost/midgard/midgard_ra.c | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/src/panfrost/midgard/midgard_ra.c b/src/panfrost/midgard/midgard_ra.c index e42f637e57a..bb404e6dde4 100644 --- a/src/panfrost/midgard/midgard_ra.c +++ b/src/panfrost/midgard/midgard_ra.c @@ -896,9 +896,37 @@ mir_spill_register( ins->dest = dest; ins->no_spill |= (1 << spill_class); + bool move = false; + + /* In the same bundle, reads of the destination + * of the spilt instruction need to be direct */ + midgard_instruction *it = ins; + while ((it = list_first_entry(&it->link, midgard_instruction, link)) + && (it->bundle_id == ins->bundle_id)) { + + if (!mir_has_arg(it, spill_node)) continue; + + mir_rewrite_index_src_single(it, spill_node, dest); + + /* The spilt instruction will write to + * a work register for `it` to read but + * the spill needs an LD/ST register */ + move = true; + } + + if (move) + dest = spill_index++; + midgard_instruction st = - v_load_store_scratch(ins->dest, spill_slot, true, ins->mask); + v_load_store_scratch(dest, spill_slot, true, ins->mask); mir_insert_instruction_after_scheduled(ctx, block, ins, st); + + if (move) { + midgard_instruction mv = v_mov(ins->dest, dest); + mv.no_spill |= (1 << spill_class); + + mir_insert_instruction_after_scheduled(ctx, block, ins, mv); + } } if (!is_special) |