https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84521
--- Comment #8 from Wilco <wilco at gcc dot gnu.org> ---
(In reply to Jakub Jelinek from comment #7)
> cfun->has_nonlocal_label instead of cfun->calls_setjmp would cover
> __builtin_setjmp.
>
> aarch64_frame_pointer_required would force frame_pointer_needed and thus be
> true in that case too. But sure, if it works, we can change:
> /* Force a frame chain for EH returns so the return address is at FP+8.
> */
> cfun->machine->frame.emit_frame_chain
> - = frame_pointer_needed || crtl->calls_eh_return;
> + = frame_pointer_needed || crtl->calls_eh_return ||
> cfun->has_nonlocal_label;
Note I'm not convinced this is sufficient. I tried compiling
testsuite/gcc.c-torture/execute/pr60003.c and it appears to mess up the frame
pointer so it no longer points to a frame chain:
baz:
adrp x1, .LANCHOR0
add x0, x1, :lo12:.LANCHOR0
stp x29, x30, [sp, -16]!
mov x29, sp
ldr x2, [x0, 8]
ldr x29, [x1, #:lo12:.LANCHOR0] // load of bad frame pointer
ldr x0, [x0, 16]
mov sp, x0
br x2
foo:
stp x29, x30, [sp, -176]!
adrp x2, .LANCHOR0
add x1, x2, :lo12:.LANCHOR0
mov x29, sp
add x3, sp, 176 // store of bad frame pointer
str x3, [x2, #:lo12:.LANCHOR0]
stp x19, x20, [sp, 16]
stp x21, x22, [sp, 32]
stp x23, x24, [sp, 48]
stp x25, x26, [sp, 64]
stp x27, x28, [sp, 80]
stp d8, d9, [sp, 96]
stp d10, d11, [sp, 112]
stp d12, d13, [sp, 128]
stp d14, d15, [sp, 144]
str w0, [sp, 172]
adrp x0, .L7
add x0, x0, :lo12:.L7
str x0, [x1, 8]
mov x0, sp
str x0, [x1, 16]
bl baz
.p2align 2
.L7:
ldr w0, [sp, 172]
ldp x19, x20, [sp, 16]
ldp x21, x22, [sp, 32]
ldp x23, x24, [sp, 48]
ldp x25, x26, [sp, 64]
ldp x27, x28, [sp, 80]
ldp d8, d9, [sp, 96]
ldp d10, d11, [sp, 112]
ldp d12, d13, [sp, 128]
ldp d14, d15, [sp, 144]
ldp x29, x30, [sp], 176
ret
What should happen is that it stores the actual sp/fp just before calling baz,
and baz then restores those before jumping to L7.