From 360650d1892deb8a8e47bd62d2300952c43fc724 Mon Sep 17 00:00:00 2001 From: Job Noorman Date: Fri, 22 May 2026 17:20:58 +0200 Subject: [PATCH] ir3/spill: extract child intervals for live-in reloads When reloading live-ins, child intervals need to be extracted to ensure we can add live-in phi nodes for them. Fixes asserts with spillall for a bunch of ray_query and ray_tracing_pipeline CTS tests: src/freedreno/ir3/ir3_spill.c: add_live_in_phi: Assertion `entry' failed. Signed-off-by: Job Noorman Fixes: 613eaac7b53 ("ir3: Initial support for spilling non-shared registers") Part-of: --- src/freedreno/ir3/ir3_spill.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/freedreno/ir3/ir3_spill.c b/src/freedreno/ir3/ir3_spill.c index 08e0dedf791..53e92b28734 100644 --- a/src/freedreno/ir3/ir3_spill.c +++ b/src/freedreno/ir3/ir3_spill.c @@ -1507,6 +1507,29 @@ live_in_rewrite(struct ra_spill_ctx *ctx, _mesa_hash_table_insert(state->remap, def, new_val); } +static void +live_in_interval_rewrite(struct ra_spill_ctx *ctx, + struct ra_spill_interval *interval, + struct reg_or_immed *new_val, struct ir3_block *block, + unsigned pred_idx, struct ir3_cursor cursor) +{ + live_in_rewrite(ctx, interval, new_val, block, pred_idx); + + rb_tree_foreach (struct ra_spill_interval, child, + &interval->interval.children, interval.node) { + assert(!(new_val->flags & (IR3_REG_CONST | IR3_REG_IMMED))); + struct ir3_register *child_reg = child->interval.reg; + struct ir3_register *child_def = extract( + new_val->def, + (child_reg->interval_start - interval->interval.reg->interval_start) / + reg_elem_size(new_val->def), + reg_elems(child_reg), cursor); + struct reg_or_immed *child_val = ralloc(ctx, struct reg_or_immed); + child_val->def = child_def; + live_in_interval_rewrite(ctx, child, child_val, block, pred_idx, cursor); + } +} + static void reload_live_in(struct ra_spill_ctx *ctx, struct ir3_register *def, struct ir3_block *block) @@ -1531,7 +1554,8 @@ reload_live_in(struct ra_spill_ctx *ctx, struct ir3_register *def, new_val->def = reload(ctx, def, ir3_before_terminator(pred)); new_val->flags = new_val->def->flags; } - live_in_rewrite(ctx, interval, new_val, block, i); + live_in_interval_rewrite(ctx, interval, new_val, block, i, + ir3_before_terminator(pred)); } }