https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96338

            Bug ID: 96338
           Summary: [SVE] Unnecessary register saves in exception handler
           Product: gcc
           Version: 11.0
            Status: UNCONFIRMED
          Keywords: missed-optimization
          Severity: enhancement
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: rsandifo at gcc dot gnu.org
  Target Milestone: ---

Compiling the following testcase with -march=armv8.2-a+sve -O2:

---------------------------------------------------------------------
void bar (__SVFloat32_t);
void
foo (__SVFloat32_t x)
{
  try { bar (x); } catch (...) { bar (x); throw; }
}
---------------------------------------------------------------------

gives an EH handler like the following;

---------------------------------------------------------------------
        .cfi_restore_state
        str     z8, [sp, #2, mul vl]
        .cfi_escape 0x10,0x48,0x8,0x8f,0,0x92,0x2e,0,0x40,0x1e,0x22
        str     z9, [sp, #3, mul vl]
        .cfi_escape 0x10,0x49,0x8,0x8f,0,0x92,0x2e,0,0x48,0x1e,0x22
        str     z10, [sp, #4, mul vl]
        .cfi_escape 0x10,0x4a,0x9,0x8f,0,0x92,0x2e,0,0x8,0x20,0x1e,0x22
        str     z11, [sp, #5, mul vl]
        .cfi_escape 0x10,0x4b,0x9,0x8f,0,0x92,0x2e,0,0x8,0x28,0x1e,0x22
        str     z12, [sp, #6, mul vl]
        .cfi_escape 0x10,0x4c,0x9,0x8f,0,0x92,0x2e,0,0x8,0x30,0x1e,0x22
        str     z13, [sp, #7, mul vl]
        .cfi_escape 0x10,0x4d,0x9,0x8f,0,0x92,0x2e,0,0x8,0x38,0x1e,0x22
        str     z14, [sp, #8, mul vl]
        .cfi_escape 0x10,0x4e,0x9,0x8f,0,0x92,0x2e,0,0x8,0x40,0x1e,0x22
        str     z15, [sp, #9, mul vl]
        .cfi_escape 0x10,0x4f,0x9,0x8f,0,0x92,0x2e,0,0x8,0x48,0x1e,0x22
        str     z16, [sp, #10, mul vl]
        str     z17, [sp, #11, mul vl]
        str     z18, [sp, #12, mul vl]
        str     z19, [sp, #13, mul vl]
        str     z20, [sp, #14, mul vl]
        str     z21, [sp, #15, mul vl]
        str     z22, [sp, #16, mul vl]
        str     z23, [sp, #17, mul vl]
        str     p5, [sp, #1, mul vl]
        str     p6, [sp, #2, mul vl]
        str     p7, [sp, #3, mul vl]
        str     p8, [sp, #4, mul vl]
        str     p9, [sp, #5, mul vl]
        str     p10, [sp, #6, mul vl]
        str     p11, [sp, #7, mul vl]
        str     p12, [sp, #8, mul vl]
        str     p13, [sp, #9, mul vl]
        str     p14, [sp, #10, mul vl]
        str     p15, [sp, #11, mul vl]
        str     p4, [sp]
        bl      __cxa_begin_catch
        add     x0, sp, 32
        ldr     z0, [x0, #18, mul vl]
.LEHB1:
        bl      _Z3bar13__SVFloat32_t
        bl      __cxa_rethrow
.LEHE1:
.L5:
        mov     x19, x0
        bl      __cxa_end_catch
        mov     x0, x19
.LEHB2:
        bl      _Unwind_Resume
---------------------------------------------------------------------

The spills of z8-z23 and p4-p15 are completely unnecessary,
since the noreturn _Unwind_Resume call ensures that this code
never returns to foo's caller.

I think the fix is to make ira.c:update_equiv_regs_prescan
a bit smarter: if a call occurs in a block that has no
path to the exit block, then we only need to consider
(parts of) registers that are clobbered by the callee
but preserved by both eh_edge_abi and the current
function's abi.

If, as is usual, eh_edge_abi is the lowest common denominator
among the available ABIs, no callees will clobber something
that is preserved by eh_edge_abi.

Reply via email to