From b6d704d5a1ce1184713b03696b10fcd9c0c9e2eb Mon Sep 17 00:00:00 2001 From: Icecream95 Date: Mon, 7 Jun 2021 19:33:54 +1200 Subject: [PATCH] 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: (cherry picked from commit 38e8d7afe30bb33218191ac681607de48753fbae) --- .pick_status.json | 2 +- src/panfrost/midgard/midgard_ra.c | 30 +++++++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index 270dead01cb..3917364a76e 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -346,7 +346,7 @@ "description": "pan/mdg: Fix reading a spilt register in the bundle it's written", "nominated": true, "nomination_type": 0, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": null }, 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)