summaryrefslogtreecommitdiff
path: root/src/panfrost
diff options
context:
space:
mode:
authorIcecream95 <ixn@disroot.org>2021-06-07 19:33:54 +1200
committerEric Engestrom <eric@engestrom.ch>2021-06-18 18:31:43 +0100
commitb6d704d5a1ce1184713b03696b10fcd9c0c9e2eb (patch)
tree5d00f5397314faf566eafdba01272b675e05aefc /src/panfrost
parent5c6f340bf5a929335928c709a10abaac674ac79f (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.c30
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)