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>
This commit is contained in:
Icecream95
2021-06-07 19:33:54 +12:00
committed by Marge Bot
parent 31d26ebf1b
commit 38e8d7afe3
+29 -1
View File
@@ -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)