[testcase] ia64 retaddr elimination failure
Geoff Keating
geoffk@geoffk.org
Tue Jan 22 15:34:00 GMT 2002
Way way back in March, Jim Wilson wrote:
> This testcase is very IA-64 specific. It works because reload is
> setting frame_pointer_needed wrong. builtin_frame_address emits a
> direct reference to HARD_FRAME_POINTER_REGNUM, which in the IA-64 port
> is the last allocatable register. But since there is no frame pointer
> according to reload, the IA-64 prologue code is confused into thinking
> that all allocatable regs have been used. Thus the return_address
> gets saved on the stack instead of in a register, causing
> builtin_return_address to fail. This is very unlikely to ever fail
> the same way on any other target.
I have found a target on which it fails in a completely different way.
We document __builtin_frame_address as a user-callable builtin that
returns the address of the frame. On xstormy16, I found that if the
function does not have a frame, __builtin_frame_address will return
whatever happens to be stored in the hard frame register. The
particular function I was looking at didn't use the hard frame
register for anything else, and so I got the frame pointer for one of
its callers... which is not what I expected.
[I was using __builtin_frame_address(0) in malloc, to determine how
much space was between the stack and the heap.]
The interesting thing is that the solution,
> The reload problem is that it checks all uses of FRAME_POINTER_REGNUM
> to see if they are eliminable. If they are, then we don't need a
> frame pointer. However, on targets where HARD_FRAME_POINTER_REGNUM !=
> FRAME_POINTER_REGNUM, we still need a frame pointer if there are any
> direct uses of the hard frame pointer. This check is missing. We
> either need to add this check to reload, or else change builtins.c to
> use frame_pointer_rtx instead of hard_frame_pointer_rtx. Either way,
> this isn't a change I feel comfortable making for an obscure bug when
> we are this close to a release.
is still good. Including the last sentence :-(.
Actually, what I expected is that if the routine has no frame pointer,
then __builtin_frame_pointer(0) should either (a) fail, or (b) return
the stack pointer which is what the frame pointer got eliminated to,
and which is what we're actually accessing the frame with. I think
(b) is nicer.
I also came up with a third possible fix. Maybe I can just tell
register elimination to eliminate HARD_FRAME_POINTER_REGNUM to
STACK_POINTER_REGNUM, with offset 0. I'm not sure if this will work,
though; it might interfere with using the hard frame pointer's
register in register allocation.
--
- Geoffrey Keating <geoffk@geoffk.org> <geoffk@redhat.com>
More information about the Gcc
mailing list