From 92c721e086a95c3c053adb9e697c69881a131d5b Mon Sep 17 00:00:00 2001 From: lemon Date: Sun, 25 Jun 2023 09:32:28 +0200 Subject: regalloc: fix temporary rename clobbering return register with multiple returns --- regalloc.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'regalloc.c') diff --git a/regalloc.c b/regalloc.c index ee96187..1e781f4 100644 --- a/regalloc.c +++ b/regalloc.c @@ -278,8 +278,19 @@ use(struct rega *ra, struct block *blk, int curi, enum op op, int hint, union re *ref = mkaddr(addr); return; } else if (ref->t == RREG) { + int reg = ref->i; assert(hint<0 || !rstest(excl, hint)); - forcetake(ra, ref->i, *ref, blk, curi); + if (op == -Jret) { + /* since return marks an exit block, if any temporary is occuping a + * return register we mark it as dead since it cannot be live after + * the return, so can't rename it like forcetake would try to do */ + if (!rstest(ra->m.free, reg)) { + (void)imap_set(&ra->m.allocs, ra->m.regs[reg], afree()); + ra->m.free = rsset(ra->m.free, reg); + } + } + forcetake(ra, reg, *ref, blk, curi); + return; } if (ref->t != RTMP) return; @@ -639,7 +650,7 @@ regalloc(struct function *fn) /* do not allocate a reg for a cmp op used a branch argument, since it's a pseudo op */ if (blk->jmp.t == Jb && blk->jmp.arg[i].t == RTMP && oiscmp(instrtab[blk->jmp.arg[i].i].op)) break; - use(&ra, blk, curi, (blk->jmp.t != Jb) - 1, + use(&ra, blk, curi, -blk->jmp.t, blk->jmp.t == Jret ? fn->abiret[i].reg : -1, &blk->jmp.arg[i], blk->jmp.arg[!i]); } -- cgit v1.2.3