From f84d85790ef0bb45488d775fc6c79b1cf1714f80 Mon Sep 17 00:00:00 2001 From: Job Noorman Date: Thu, 16 Oct 2025 10:12:37 +0200 Subject: [PATCH] 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 Fixes: 9d4ba885bb8 ("ir3/ra: make main shader reg select independent of preamble") Part-of: --- src/freedreno/ir3/ir3_ra.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/freedreno/ir3/ir3_ra.c b/src/freedreno/ir3/ir3_ra.c index 8c0a22ddecf..6bc42ddbd98 100644 --- a/src/freedreno/ir3/ir3_ra.c +++ b/src/freedreno/ir3/ir3_ra.c @@ -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);