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