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.