Hello, In our GCC porting (gcc 4.3.1), I am facing a problem with built-in-setjmp test, which failed from -O2. After spending quite some time on it, I figured out what happens, but not sure what is the best way to fix it. The problem is with __builtin_setjmp_receiver.
In built-in-setjmp.c.132r.expand ;; __builtin_setjmp_receiver (&<L0>) (insn 62 61 63 /projects/firepath/tools/work/bmei/gcc-head/src/gcc/testsuite/gcc.c-tort ure/execute/built-in-setjmp.c:21 (use (reg/f:SI 55 r55)) -1 (nil)) (insn 63 62 64 /projects/firepath/tools/work/bmei/gcc-head/src/gcc/testsuite/gcc.c-tort ure/execute/built-in-setjmp.c:21 (clobber (reg:SI 27 r27)) -1 (nil)) (insn 64 63 65 /projects/firepath/tools/work/bmei/gcc-head/src/gcc/testsuite/gcc.c-tort ure/execute/built-in-setjmp.c:21 (set (reg/f:SI 79 virtual-stack-vars) (reg/f:SI 55 r55)) -1 (nil)) (insn 65 64 66 /projects/firepath/tools/work/bmei/gcc-head/src/gcc/testsuite/gcc.c-tort ure/execute/built-in-setjmp.c:21 (clobber (reg/f:SI 55 r55)) -1 (nil)) (insn 66 65 0 /projects/firepath/tools/work/bmei/gcc-head/src/gcc/testsuite/gcc.c-tort ure/execute/built-in-setjmp.c:21 (asm_input/v ("") 0) -1 (nil)) After replacing virtual register with real ones, it is tranformed to following code (builtin-setjmp.c.137r.vregs). R55 is our frame pointer and we have #define STARTING_FRAME_OFFSET -128 (insn 62 61 63 6 /projects/firepath/tools/work/bmei/gcc-head/src/gcc/testsuite/gcc.c-tort ure/execute/built-in-setjmp.c:21 (use (reg/f:SI 55 r55)) -1 (nil)) (insn 63 62 157 6 /projects/firepath/tools/work/bmei/gcc-head/src/gcc/testsuite/gcc.c-tort ure/execute/built-in-setjmp.c:21 (clobber (reg:SI 27 r27)) -1 (nil)) (insn 157 63 65 6 /projects/firepath/tools/work/bmei/gcc-head/src/gcc/testsuite/gcc.c-tort ure/execute/built-in-setjmp.c:21 (set (reg/f:SI 55 r55) (plus:SI (reg/f:SI 55 r55) (const_int 128 [0x80]))) -1 (nil)) (insn 65 157 66 6 /projects/firepath/tools/work/bmei/gcc-head/src/gcc/testsuite/gcc.c-tort ure/execute/built-in-setjmp.c:21 (clobber (reg/f:SI 55 r55)) -1 (nil)) (insn 66 65 67 6 /projects/firepath/tools/work/bmei/gcc-head/src/gcc/testsuite/gcc.c-tort ure/execute/built-in-setjmp.c:21 (asm_input/v ("") 0) -1 (nil)) Now the problem is that insn 157 defines r55, and the following insn 65 clobbers r55 as well. Therefore, in the dead code elimination pass, insn 157 is optimized away (built-in-setjmp.162r.dce) and produces wrong results. (insn 62 61 63 4 /projects/firepath/tools/work/bmei/gcc-head/src/gcc/testsuite/gcc.c-tort ure/execute/built-in-setjmp.c:21 (use (reg/f:SI 55 r55)) -1 (nil)) (insn 63 62 65 4 /projects/firepath/tools/work/bmei/gcc-head/src/gcc/testsuite/gcc.c-tort ure/execute/built-in-setjmp.c:21 (clobber (reg:SI 27 r27)) -1 (expr_list:REG_UNUSED (reg:SI 27 r27) (nil))) (insn 65 63 66 4 /projects/firepath/tools/work/bmei/gcc-head/src/gcc/testsuite/gcc.c-tort ure/execute/built-in-setjmp.c:21 (clobber (reg/f:SI 55 r55)) -1 (nil)) (insn 66 65 114 4 /projects/firepath/tools/work/bmei/gcc-head/src/gcc/testsuite/gcc.c-tort ure/execute/built-in-setjmp.c:21 (asm_input/v ("") 0) -1 (nil)) I checked how the __builtin_setjmp_receiver is expanded in builtins.c: ... #ifdef HAVE_nonlocal_goto if (! HAVE_nonlocal_goto) #endif { emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx); /* This might change the hard frame pointer in ways that aren't apparent to early optimization passes, so force a clobber. */ emit_insn (gen_rtx_CLOBBER (VOIDmode, hard_frame_pointer_rtx)); <---- clobber } ... It always produces the clobber after moving hard frame pointer to virtual_stack_vars_rtx. Commenting out this statement make test work correctly and doesn't effect others. However, I don't want to modify GCC source code itself. I guess other targets may face similar issue. Is this a potential bug for GCC or is there any way to overcome it just by changing my porting? I did a search on the mailing list, and found the following thread reported a very similar issue. Unfortunately, it didn't have follow-up about solution. http://gcc.gnu.org/ml/gcc/2008-03/msg00932.html Cheers, Bingfeng Mei Broadcom UK