The test case is gcc.c-torture/execute/built-in-setjmp.c.

The __builtin_setjmp stores Y+1 in the setjmp buffer. With -O0 the first
instruction after the jmp does a "sbiw r28, 1" that restores the
original value, but for some reason, with higher optimization levels,
this instruction is optimized away, leaving R28 pointing to the wrong
address by one.

The __builtin_setjmp code:

  if (__builtin_setjmp (buf))
16a:    ce 01           movw    r24, r28
16c:    01 96           adiw    r24, 0x01       ; 1
  Notice the increment here, before storing R28

16e:    90 93 07 01     sts     0x0107, r25
172:    80 93 06 01     sts     0x0106, r24
176:    8f ee           ldi     r24, 0xEF       ; 239
178:    90 e0           ldi     r25, 0x00       ; 0
17a:    90 93 09 01     sts     0x0109, r25
17e:    80 93 08 01     sts     0x0108, r24
182:    ed b7           in      r30, 0x3d       ; 61
184:    fe b7           in      r31, 0x3e       ; 62
186:    f0 93 0b 01     sts     0x010B, r31
18a:    e0 93 0a 01     sts     0x010A, r30

The __builtin_longjmp code:

  __builtin_longjmp (buf, 1);
10c:    e0 91 08 01     lds     r30, 0x0108
110:    f0 91 09 01     lds     r31, 0x0109
114:    c0 91 06 01     lds     r28, 0x0106
118:    d0 91 07 01     lds     r29, 0x0107
11c:    80 91 0a 01     lds     r24, 0x010A
120:    90 91 0b 01     lds     r25, 0x010B

no decrement, R28 is used "as is".


-- 
           Summary: __builtin_setjmp / __builtin_longjmp fails stack frame
                    address with O2, O3 and Os
           Product: gcc
           Version: 4.3.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: pmarques at grupopie dot com
 GCC build triplet: i686-pc-linux-gnu
  GCC host triplet: i686-pc-linux-gnu
GCC target triplet: avr-*-*


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34879

Reply via email to