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.