https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63360
Peter Bergner <bergner at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |RESOLVED Resolution|--- |INVALID --- Comment #16 from Peter Bergner <bergner at gcc dot gnu.org> --- Ok, this is an application problem. From the last gdb session, we see that the jmpbuf has an address non 16-byte aligned address, which the setjmp/longjmp code requires. (gdb) i reg r3 r3 0x2086db8 34106808 This leads to the code that saves the Altivec registers to clobber the jmpbuf field where f31 is stored, since the stvx store instruction implicitly truncates the bottom nibble of its address, giving it the same address as f31's field. Speaking with Camm offline, he doesn't use the jmpbuf type included from setjmp.h, but rather uses: struct frame { char frs_jmpbuf[SIZEOF_JMP_BUF]; object *frs_lex; bds_ptr frs_bds_top; object frs_val; ihs_ptr frs_ihs; char frs_class; char frs_in_signal_handler; char frs_pad[6]; /*Keep frs_jumpbuf 8 byte aligned*/ }; ...which will only enforce an 8 byte alignment. If you look at the jmpbuf declaration included from setjmp.h, you'll see it defined as: typedef long int __jmp_buf[64 + (12 * 4)] __attribute__ ((__aligned__ (16))); The save/restore code within setjmp/longjmp requires the 16-byte alignment. I'm guessing the working "optimized" code was only getting lucky with the address of your jmpbuf. I'll note that the same jmpbuf layout and setjmp/longjmp code is used for both ELFv1 and ELFv2, so you'll need to do this for both of them. The __powerpc64__ macro is defined for both ELFv1 and ELFv2, so you can use that to increase your jumpbuf's alignment when compiling for ELFv1 and ELFv2.