[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