ir3/ra: fix assert during file start reset

While accounting for an input register's merge set when resetting the
file start after the preamble, we implicitly assume that the allocated
register is the preferred one by asserting that the register's merge set
offset is not smaller than its physreg (to prevent an underflow).
However, inputs are not guaranteed to have their preferred register
allocated which causes the assert to get triggered.

Fix this by only taking the whole merge set into account for inputs that
actually got their preferred register allocated.

Signed-off-by: Job Noorman <jnoorman@igalia.com>
Fixes: 9d4ba885bb ("ir3/ra: make main shader reg select independent of preamble")
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37905>
This commit is contained in:
Job Noorman 2025-10-16 10:12:37 +02:00 committed by Marge Bot
parent b6e281d0b1
commit f84d85790e

View file

@ -2300,6 +2300,17 @@ insert_live_out_moves(struct ra_ctx *ctx)
insert_file_live_out_moves(ctx, &ctx->shared);
}
static bool
has_merge_set_preferred_reg(struct ir3_register *reg)
{
assert(reg->merge_set);
assert(reg->num != INVALID_REG);
return reg->merge_set->preferred_reg != (physreg_t)~0 &&
ra_reg_get_physreg(reg) ==
reg->merge_set->preferred_reg + reg->merge_set_offset;
}
static void
handle_block(struct ra_ctx *ctx, struct ir3_block *block)
{
@ -2338,17 +2349,15 @@ handle_block(struct ra_ctx *ctx, struct ir3_block *block)
struct ir3_register *dst = input->dsts[0];
assert(dst->num != INVALID_REG);
physreg_t dst_start = ra_reg_get_physreg(dst);
physreg_t dst_end;
if (dst->merge_set) {
if (dst->merge_set && has_merge_set_preferred_reg(dst)) {
/* Take the whole merge set into account to prevent its range being
* allocated for defs not part of the merge set.
*/
assert(dst_start >= dst->merge_set_offset);
dst_end = dst_start - dst->merge_set_offset + dst->merge_set->size;
dst_end = dst->merge_set->preferred_reg + dst->merge_set->size;
} else {
dst_end = dst_start + reg_size(dst);
dst_end = ra_reg_get_physreg(dst) + reg_size(dst);
}
struct ra_file *file = ra_get_file(ctx, dst);