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

             Bug #: 53049
           Summary: expand/TER unappropriate moving unspec volatile
    Classification: Unclassified
           Product: gcc
           Version: 4.7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
        AssignedTo: unassig...@gcc.gnu.org
        ReportedBy: g...@gcc.gnu.org
                CC: eric.wedding...@atmel.com
            Target: avr


extern unsigned ivar;

void test2 (unsigned val)
{
  val = 65535U / val;

  __builtin_avr_cli();
  ivar = val;
  __builtin_avr_sei();
}

void test3 (unsigned val)
{
  val = 65535U / val;

  __asm__ __volatile__ ("cli" ::: "memory");
  ivar = val;
  __asm__ __volatile__ ("sei" ::: "memory");
}

In this C code, the division is performed by a libgcc call, and TER drags the
CLI builtin resp. asm volatile over the operation.

It's not forbidden by the standard, but anyone who ever did system programming
will agree that such transformation is devastating for interrupt response time:

In the example, the CLI/SEI instructions are used to temporarily switch off
IRQs so that an atomic (write) operation to IVAR can be performed.

Seen with 4.7.1 20120416 (prerelease) and with 4.8.0, presumably also present
on older versions.

Compiled with:

$ avr-gcc test2.c -S -Os -fdump-rtl-expand-details -dP -O1

-fno-tree-ter fixed the issue

Comfigured with:

../../gcc.gnu.org/gcc-4_7-branch/configure --target=avr
--prefix=/local/gnu/install/gcc-4.7 --disable-nls --with-dwarf2
--enable-languages=c,c++

GNU C (GCC) version 4.7.1 20120416 (prerelease) (avr)
        compiled by GNU C version 4.3.2 [gcc-4_3-branch revision 141291], GMP
version 4.3.2, MPFR version 2.4.2, MPC version 0.8.2

Reply via email to