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

            Bug ID: 95361
           Summary: Segfault when generating an epilogue for a
                    partly-shrinked-wrapped SVE frame
           Product: gcc
           Version: 11.0
            Status: UNCONFIRMED
          Keywords: ice-on-valid-code
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: rsandifo at gcc dot gnu.org
  Target Milestone: ---
            Target: aarch64*-*-*

Compiling the following with -O2 -march=armv8.2+sve causes
the compiler to segfault during aarch64_expand_epilogue:

----------------------------------------------------
__SVInt8_t
f (__SVInt8_t x, int y)
{
  if (y == 1)
    asm volatile ("" ::: "z8");
  if (y == 2)
    asm volatile ("" ::: "z9");
  return x;
}
----------------------------------------------------

The problem is that we individually shrink-wrap the saves
and restores of z8 and z9, but need to keep the stack
allocation common to both arms.  Before emitting the
deallocation instruction, we try to add a REG_CFA_DEF_CFA
note to the final restore, which doesn't exist:

  if (callee_adjust != 0 || maybe_gt (initial_adjust, 65536))
    {
      /* Emit delayed restores and set the CFA to be SP + initial_adjust.  */
      insn = get_last_insn ();
      rtx new_cfa = plus_constant (Pmode, stack_pointer_rtx, initial_adjust);
      REG_NOTES (insn) = alloc_reg_note (REG_CFA_DEF_CFA, new_cfa, cfi_ops);
      RTX_FRAME_RELATED_P (insn) = 1;
      cfi_ops = NULL;
    }

This in practice only happens for SVE because:

(a) We don't try to shrink-wrap wb_candidate* registers even when
    we've decided to treat them as normal saves and restores.
    I have a fix for that.

(b) Even with (a) fixed, we're (almost?) guaranteed to emit a stack
    tie for frames that are 64k or larger, so we end up hanging the
    REG_CFA_DEF_CFA note on that instead.

I haven't yet checked how far back this goes.

Reply via email to