[PATCH] Fix aarch64 exception handling (PR c++/59813)

Jakub Jelinek jakub@redhat.com
Fri May 10 08:15:00 GMT 2019


Hi!

My recent patch for tail call improvement apparently affects also the
_Unwind_Resume_or_Rethrow function in libgcc:

_Unwind_Reason_Code __attribute__((optimize ("no-omit-frame-pointer")))
_Unwind_Resume_or_Rethrow (struct _Unwind_Exception *exc)
{
  struct _Unwind_Context this_context, cur_context;
  _Unwind_Reason_Code code;
  unsigned long frames;
  if (exc->private_1 == 0)
    return _Unwind_RaiseException (exc);
  do { __builtin_unwind_init (); uw_init_context_1 (&this_context, __builtin_dwarf_cfa (), __builtin_return_address (0)); } while (0);
  cur_context = this_context;
  code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context, &frames);
  ((void)(!(code == _URC_INSTALL_CONTEXT) ? abort (), 0 : 0));
  do { long offset = uw_install_context_1 ((&this_context), (&cur_context)); void *handler = uw_frob_return_addr ((&this_context), (&cur_context));
 _Unwind_DebugHook ((&cur_context)->cfa, handler); ; __builtin_eh_return (offset, handler); } while (0);
}

Previously, the mere existence of the addressable variables this_context
and cur_context prevented tail call on the early out
return _Unwind_RaiseException (exc);
but since r271013 the tailcall analysis figures that while those two
variables are there, they aren't touched before the possible tail call
site, so they can't be really live during the call.
The problem is that this is one of the few calls that call
__builtin_eh_return which normally user code doesn't use, we use it just
for the unwinder routines and so some targets (in this case aarch64, in
another report powerpc-darwin) show that the combination of
cfun->calls_eh_return + tail calls has not been really tested.
One possibility is to do if (cfun->calls_eh_return) return false; in
the target hook *_ok_for_sibcall, the other possibility is to fix that
case properly.

The following patch fixes the aarch64 case.
The code emitted for the code path from the start of the function
till the tail call was:
0000000000002778 <_Unwind_Resume_or_Rethrow>:
    2778:       d12143ff        sub     sp, sp, #0x850
    277c:       a9007bfd        stp     x29, x30, [sp]
    2780:       910003fd        mov     x29, sp
    2784:       a90107e0        stp     x0, x1, [sp, #16]
    2788:       f9400801        ldr     x1, [x0, #16]
    278c:       a9020fe2        stp     x2, x3, [sp, #32]
    2790:       a90353f3        stp     x19, x20, [sp, #48]
    2794:       aa0003f3        mov     x19, x0
    2798:       a9045bf5        stp     x21, x22, [sp, #64]
    279c:       a90563f7        stp     x23, x24, [sp, #80]
    27a0:       a9066bf9        stp     x25, x26, [sp, #96]
    27a4:       a90773fb        stp     x27, x28, [sp, #112]
    27a8:       6d0827e8        stp     d8, d9, [sp, #128]
    27ac:       6d092fea        stp     d10, d11, [sp, #144]
    27b0:       6d0a37ec        stp     d12, d13, [sp, #160]
    27b4:       6d0b3fee        stp     d14, d15, [sp, #176]
    27b8:       b5000201        cbnz    x1, 27f8 <_Unwind_Resume_or_Rethrow+0x80>
    27bc:       a9407bfd        ldp     x29, x30, [sp]
    27c0:       a94107e0        ldp     x0, x1, [sp, #16]
    27c4:       a9420fe2        ldp     x2, x3, [sp, #32]
    27c8:       a94353f3        ldp     x19, x20, [sp, #48]
    27cc:       a9445bf5        ldp     x21, x22, [sp, #64]
    27d0:       a94563f7        ldp     x23, x24, [sp, #80]
    27d4:       a9466bf9        ldp     x25, x26, [sp, #96]
    27d8:       a94773fb        ldp     x27, x28, [sp, #112]
    27dc:       6d4827e8        ldp     d8, d9, [sp, #128]
    27e0:       6d492fea        ldp     d10, d11, [sp, #144]
    27e4:       6d4a37ec        ldp     d12, d13, [sp, #160]
    27e8:       6d4b3fee        ldp     d14, d15, [sp, #176]
    27ec:       912143ff        add     sp, sp, #0x850
    27f0:       8b2463ff        add     sp, sp, x4
    27f4:       14000000        b       23c8 <_Unwind_RaiseException>
                        27f4: R_AARCH64_JUMP26  _Unwind_RaiseException
This does a lot of register saving and restoring, which is not needed but is
not wrong-code (guess separate shrink wrapping would help here if
implemented for the target).  The only wrong-code is actually the
add sp, sp, x4 instruction though.  The previous instruction restored sp to
the value it had at the start of the function and then we should just tail
call.  This instruction is something that is needed in the spot where
__builtin_eh_return is emitted.

Fixed thusly, bootstrapped/regtested on aarch64-linux, ok for trunk?

2019-05-10  Jakub Jelinek  <jakub@redhat.com>

	PR c++/59813
	* config/aarch64/aarch64.c (aarch64_expand_epilogue): Don't add
	EH_RETURN_STACKADJ_RTX to sp in sibcall epilogues.

--- gcc/config/aarch64/aarch64.c.jj	2019-05-02 12:18:40.004979690 +0200
+++ gcc/config/aarch64/aarch64.c	2019-05-09 20:08:00.774718003 +0200
@@ -5913,7 +5913,7 @@ aarch64_expand_epilogue (bool for_sibcal
     }
 
   /* Stack adjustment for exception handler.  */
-  if (crtl->calls_eh_return)
+  if (crtl->calls_eh_return && !for_sibcall)
     {
       /* We need to unwind the stack by the offset computed by
 	 EH_RETURN_STACKADJ_RTX.  We have already reset the CFA

	Jakub



More information about the Gcc-patches mailing list