https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84521
--- Comment #19 from Wilco <wilco at gcc dot gnu.org> --- (In reply to sudi from comment #17) > I looked up what other targets were doing and one thing found to be > interesting was that a lot of them are defining the target hook > TARGET_BUILTIN_SETJMP_FRAME_VALUE. In AArch64 case I am suggesting to define > it to return the hard frame pointer. That seems to solve the issue with both > the attached test case and the test that Wilco mentioned. > > Does this look like it solves "mid-end versus back-end : who fixes this > issue" problem? > > I am still pretty new to knowing how the stack should actually look. So > calling for some help! This is not about stack layout but ensuring we don't corrupt the frame pointer or the stack pointer. Any changes to SP/FP are inherently extremely risky and need to be done exactly right or lots of things will fail. There are too many issues to make a full list, but here are a few obvious ones: 1. The TARGET_BUILTIN_SETJMP_FRAME_VALUE only fixes the store of the frame pointer, however it does not fix the landing pad, I see code like this: str x29, [x3, #:lo12:.LANCHOR0] mov x0, sp stp x1, x0, [x2, 8] bl baz .p2align 2 .L7: sub x29, x29, #176 ldr w0, [x29, 172] mov sp, x29 So now the store is correct, but when returning at L2 we corrupt the frame pointer badly (and then the stack pointer as well)... This is basically the same as pr60003.c but with an alloca added. 2. We still need to force the frame pointer to be saved, TARGET_BUILTIN_SETJMP_FRAME_VALUE doesn't fix that. 3. __builtin_longjmp is still incorrect, like I showed in PR64242, it also fails on AArch64: #include <setjmp.h> #include <string.h> void bug (jmp_buf buf) { jmp_buf buf2; memcpy (buf2, buf, sizeof (jmp_buf)); __builtin_longjmp (buf2, 1); } bug: stp x29, x30, [sp, -336]! mov x1, x0 mov x2, 312 mov x29, sp add x0, x29, 24 bl memcpy ldr x0, [x29, 32] ldr x29, [x29, 24] // oops ldr x1, [x29, 40] mov sp, x1 br x0 4. Trying to use setjmp and longjmp in the same function often gives this ICE: during RTL pass: cse1 setjmp.c: In function ‘bug1’: setjmp.c:86:1: internal compiler error: in mark_jump_label_1, at jump.c:1151 } ^ 0xa598f7 mark_jump_label_1 /home/wdijkstr/gcc/gcc/jump.c:1151 0xa59a6b mark_jump_label_1 /home/wdijkstr/gcc/gcc/jump.c:1211 0xa59a6b mark_jump_label_1 /home/wdijkstr/gcc/gcc/jump.c:1211 0xa59e17 mark_all_labels /home/wdijkstr/gcc/gcc/jump.c:305 0xa59e17 rebuild_jump_labels_1 /home/wdijkstr/gcc/gcc/jump.c:74 0x128ce23 rest_of_handle_cse /home/wdijkstr/gcc/gcc/cse.c:7628 0x128ce23 execute /home/wdijkstr/gcc/gcc/cse.c:7662 5. Things get really interesting on ARM and Thumb-2 where there are multiple frame pointer registers. This shows again why it is wrong to change the sp/fp in the longjmp - for it to work correctly it must be done in the landing pad in the function that has the setjmp.