From af8105d085e02bbd1fc370c685c8de851f22f190 Mon Sep 17 00:00:00 2001 From: Job Noorman Date: Mon, 14 Apr 2025 16:00:13 +0200 Subject: [PATCH] ir3/ra: ignore phis handled by shared RA If shared RA is used, it may have handled some phis. These are already ignored by regular RA in handle_phi but were used before that in potentially dangerous ways. More specifically, the interval of such phis was accessed which may cause an out-of-bounds read since it was never created. Fix this by skipping such phis earlier. Signed-off-by: Job Noorman Fixes: c6a932d4b37 ("ir3/ra: handle phis with preferred regs first") Part-of: --- src/freedreno/ir3/ir3_ra.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/freedreno/ir3/ir3_ra.c b/src/freedreno/ir3/ir3_ra.c index 18297ad2d30..eddd9eb91cc 100644 --- a/src/freedreno/ir3/ir3_ra.c +++ b/src/freedreno/ir3/ir3_ra.c @@ -2035,9 +2035,6 @@ handle_live_out(struct ra_ctx *ctx, struct ir3_register *def) static void handle_phi(struct ra_ctx *ctx, struct ir3_register *def) { - if (!(def->flags & IR3_REG_SSA)) - return; - struct ra_file *file = ra_get_file(ctx, def); struct ra_interval *interval = ra_interval_get(ctx, def); @@ -2311,6 +2308,11 @@ handle_block(struct ra_ctx *ctx, struct ir3_block *block) if (instr->opc == OPC_META_PHI) { struct ir3_register *dst = instr->dsts[0]; + /* Some phis may have been handled by shared RA already. */ + if (!(dst->flags & IR3_REG_SSA)) { + continue; + } + if (dst->merge_set && dst->merge_set->preferred_reg != (physreg_t)~0) { handle_phi(ctx, dst); } else { @@ -2329,6 +2331,10 @@ handle_block(struct ra_ctx *ctx, struct ir3_block *block) if (instr->opc == OPC_META_PHI) { struct ir3_register *dst = instr->dsts[0]; + if (!(dst->flags & IR3_REG_SSA)) { + continue; + } + if (!ra_interval_get(ctx, dst)->interval.inserted) { handle_phi(ctx, dst); }