diff options
author | Quentin Carbonneaux <quentin@c9x.me> | 2021-10-25 13:39:20 +0200 |
---|---|---|
committer | Quentin Carbonneaux <quentin@c9x.me> | 2021-10-26 20:31:46 +0200 |
commit | b2a25215fcc71c86e0120c7bac14f679b70a3a3c (patch) | |
tree | b75a1ecb2ee717dfbb0666568dbbad6ea8a03ba7 /arm64/abi.c | |
parent | fd33b2ef25ff55217e229666c4d2f0877aac2515 (diff) | |
download | roux-b2a25215fcc71c86e0120c7bac14f679b70a3a3c.tar.gz |
spill: fix regs assertions
Some arm64 abi tests have been failing for some time now. This fixes them by being a bit more careful with liveset management in spill.c. A late bsclr() call in spill.c may drop legitimately live registers in e.g., R12 =w add R12, 1 While it hurts for regs, it does not matter for ssa temps because those cannot be both in the arguments & return (by the ssa invariant). I added a check before bsclr() to make sure we are clearing only ssa temps. One might be surprised that any ssa temp may be live at this point. The reason why this is the case is the special handling of dead return values earlier in spill(). I think that it is the only case where the return value can be (awkwardly) live at the same time as the arguments, and I think this never happens with registers (i.e., we never have dead register- assigning instructions). I added an assert to check the latter invariant. Finally, there was a simple bug in the arm64 abi which I fixed: In case the return happens via a pointer, x8 needs to be marked live at the beginning of the function. This was caught by test/abi4.ssa.
Diffstat (limited to 'arm64/abi.c')
-rw-r--r-- | arm64/abi.c | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/arm64/abi.c b/arm64/abi.c index d38dcf5..8209944 100644 --- a/arm64/abi.c +++ b/arm64/abi.c @@ -448,6 +448,7 @@ selpar(Fn *fn, Ins *i0, Ins *i1) if (cr.class & Cptr) { fn->retr = newtmp("abi", Kl, fn); emit(Ocopy, Kl, fn->retr, TMP(R8), R); + fn->reg |= BIT(R8); } } |