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

Reply via email to