ir3/ra: Fix bug with collect source handling

It can be the case that a collect and one of its sources are assigned
to non-overlapping parts of the same merge set, for example:

	ssa_1 = ...
	ssa_2 = ...
	ssa_3 = ...

	ssa_4 = collect ssa_1, ssa_2 (kill), ssa_3
	... = ssa_4 (kill)

	ssa_5 = collect ssa_1, ssa_3

	... = ssa_1 (kill)
	... = ssa_3 (kill)
	... = ssa_5 (kill)

If we merge the first collect first, we get a merge set:

	ssa_1 (offset 0)
	ssa_2 (offset 2)
	ssa_3 (offset 4)
	ssa_4 (offset 0)

Now, we decide to merge ssa_1 and ssa_5:

	ssa_1 (offset 0)
	ssa_2 (offset 2)
	ssa_3 (offset 4)
	ssa_4 (offset 0)
	ssa_5 (offset 0)

ssa_3 cannot become a child of ssa_5 in the interval tree, just like a
source not in the same merge set, so we should not remove it and then
reinsert it assuming that RA will make it a child of ssa_5.

This fixes an RA validation error in Farming Simulater.

Fixes: 0ffcb19 ("ir3: Rewrite register allocation")
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27497>
This commit is contained in:
Connor Abbott
2024-02-06 14:14:04 -05:00
committed by Marge Bot
parent cdb8020f16
commit aeed5fd98d

View File

@@ -1725,8 +1725,14 @@ handle_collect(struct ra_ctx *ctx, struct ir3_instruction *instr)
struct ra_interval *interval = &ctx->intervals[src->def->name];
if (src->def->merge_set != dst_set || interval->is_killed)
/* We only need special handling if the source's interval overlaps with
* the destination's interval.
*/
if (src->def->interval_start >= instr->dsts[0]->interval_end ||
instr->dsts[0]->interval_start >= src->def->interval_end ||
interval->is_killed)
continue;
while (interval->interval.parent != NULL) {
interval = ir3_reg_interval_to_ra_interval(interval->interval.parent);
}