Mesa (main): pan/mdg: Fix reading a spilt register in the bundle it's written

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Jun 17 20:04:49 UTC 2021


Module: Mesa
Branch: main
Commit: 38e8d7afe30bb33218191ac681607de48753fbae
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=38e8d7afe30bb33218191ac681607de48753fbae

Author: Icecream95 <ixn at disroot.org>
Date:   Mon Jun  7 19:33:54 2021 +1200

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>

---

 src/panfrost/midgard/midgard_ra.c | 30 +++++++++++++++++++++++++++++-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/src/panfrost/midgard/midgard_ra.c b/src/panfrost/midgard/midgard_ra.c
index 110b5c9cd44..1b11eb775b2 100644
--- a/src/panfrost/midgard/midgard_ra.c
+++ b/src/panfrost/midgard/midgard_ra.c
@@ -916,9 +916,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)



More information about the mesa-commit mailing list