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: [email protected]
ReportedBy: [email protected]
CC: [email protected]
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