problem with -fno-sjlj-exceptions on alpha (ss 970907)

scott snyder snyder@d0sgif.fnal.gov
Tue Sep 9 21:58:00 GMT 1997


hi -

I've run into a problem trying to use no-sjlj-exceptions on the alpha
with optimization on.  (This is ss 970907 on alpha-dec-osf4.0.)
The problem is that the generated __throw procedure wants to modify
its return address, in order to peel off the outermost stack frame.
It does this by storing the new return address into (mem:DI (reg:DI 15 $15)).
However, when optimization is on, gcc eliminates the frame pointer;
it then fails to change this reference to the stack pointer.

Here's an example.  If i compile this source with
gcc -S -O2 -fno-sjlj-exceptions:

-- tt.cc ------------------------------------------------------------------
class A {};

main ()
{
  try {
    throw A ();
    abort ();
  }
  catch (A&) {
  }
}
---------------------------------------------------------------------------


the start of the __throw function looks like:

        .ent __throw
__throw:
        ldgp $29,0($27)
__throw..ng:
        lda $30,-16($30)
        .frame $30,16,$26,0
        stq $26,0($30)
        stq $15,8($30)
        .mask 0x4008000,-16
        .prologue 1
$EHB75:
        lda $1,__eh_type
        ldq $1,0($1)
        beq $1,$71
        lda $1,__eh_pc
        ldq $16,0($1)
        jsr $26,__find_first_exception_table_match
        ldgp $29,0($26)
        beq $0,$70
        stq $0,0($15)  <--- Here it tries to store the return address;
                            however, the frame pointer has been eliminated,
                            so $15 is not valid.
        br $31,$79
        .align 4


The insn generated to do that store is:

(insn 27 25 28 (set (mem:DI (reg:DI 15 $15))
        (reg:DI 0 $0)) -1 (nil)
    (nil))

Note that for the alpha, HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM.
Reload doesn't touch the reference to reg 15 in that insn because
there's no elimination rule given for HARD_FRAME_POINTER_REGNUM.

It's not entirely clear to me what's intended to be happening here.
Is reload supposed to fix up references to HARD_FRAME_POINTER_REGNUM
if the fp is eliminated, or is the RTL generation not supposed to
use HARD_FRAME_POINTER_REGNUM in contexts where fp elimination can
change things?

A workaround is to compile with fno-omit-frame-pointer.

sss



More information about the Gcc mailing list