On 2019-11-02 1:28 p.m., Kwok Cheung Yeung wrote:
The AMD GCN architecture uses 64-bit pointers, but the scalar
registers are 32-bit wide, so pointers must reside in a pair of
registers.
The two hard registers holding the frame pointer are currently fixed,
but if they are changed to unfixed (so that the FP can be eliminated),
GCC would sometimes allocate the second register to a pseudo while the
frame pointer was in use, clobbering the value of the FP and crashing
the program.
GCC currently does not handle multi-register hard frame pointers
properly - no_unit_alloc_regs, regs_ever_live, eliminable_regset and
ira_no_alloc_regs (which gets copied to lra_no_alloc_regs) are only
set for HARD_FRAME_POINTER_REGNUM and not for any subsequent registers
that may be used, which means that the register allocators consider
HARD_FRAME_POINTER_REGNUM+1 free. This patch determines the number of
registers needed to store the frame pointer using hard_regno_nregs,
and sets the required variables for HARD_FRAME_POINTER_REGNUM and
however many adjacent registers are needed (which on most
architectures should be zero).
Bootstrapped on x86_64 and tested with no regressions, which is not
surprising as nothing different happens when the FP fits into a single
register. I believe this is true for the 64-bit variants of the more
popular architectures as well (ARM, RS6000, MIPS, Sparc). Are there
any other architectures similar to GCN (i.e. 64-bit pointers with
32-bit GPRs)?
I have not included any specific testcases for this issue as it can
affect pretty much everything not using -fomit-frame-pointer on AMD GCN.
Okay for trunk?
Yes. You can commit the patch to the trunk.
Thank you.