http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49065
Summary: Write of non-aligned volatile float generates extra read instructions on PowerPC Product: gcc Version: 3.4.4 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassig...@gcc.gnu.org ReportedBy: jay.kulpin...@gmail.com On the PowerPC, a write to a non-aligned float within a packed data structure results in each byte being read before being written if the object is declared volatile. This can cause unexpected behavior with hardware. The bug exists in recent 4.x gcc versions as well. $ powerpc-eabi-gcc -v -save-temps -S -O2 gcc_bug.c Reading specs from /opt/crossgcc/004DBN01/lib/gcc/powerpc-eabi/3.4.4/specs Configured with: /opt/crossgcc/004DBN01/src/gcc-3.4.4/configure --target=powerpc-eabi --prefix=/opt/crossgcc/004DBN01 --with-gnu-as --with-gnu-ld --with-newlib --disable-multilib Thread model: single gcc version 3.4.4 /opt/crossgcc/004DBN01/libexec/gcc/powerpc-eabi/3.4.4/cc1 -E -quiet -v gcc_bug.c -O2 -o gcc_bug.i ignoring nonexistent directory "/opt/crossgcc/004DBN01/lib/gcc/powerpc-eabi/3.4.4/../../../../powerpc-eabi/sys-include" #include "..." search starts here: #include <...> search starts here: /opt/crossgcc/004DBN01/lib/gcc/powerpc-eabi/3.4.4/include /opt/crossgcc/004DBN01/lib/gcc/powerpc-eabi/3.4.4/../../../../powerpc-eabi/include End of search list. /opt/crossgcc/004DBN01/libexec/gcc/powerpc-eabi/3.4.4/cc1 -fpreprocessed gcc_bug.i -quiet -dumpbase gcc_bug.c -auxbase gcc_bug -O2 -version -o gcc_bug.s GNU C version 3.4.4 (powerpc-eabi) compiled by GNU C version 4.1.2 20071124 (Red Hat 4.1.2-42). GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 $ $ cat gcc_bug.i # 1 "gcc_bug.c" # 1 "<built-in>" # 1 "<command line>" # 1 "gcc_bug.c" struct msg { short header; float data; } __attribute__((packed)); void nonvolatile_good(struct msg *p) { p->data = 0.0; } void volatile_bad(volatile struct msg *p) { p->data = 0.0; } $ $ cat gcc_bug.s .file "gcc_bug.c" .section ".text" .align 2 .globl nonvolatile_good .type nonvolatile_good, @function nonvolatile_good: li 0,0 stb 0,5(3) stb 0,2(3) stb 0,3(3) stb 0,4(3) blr .size nonvolatile_good, .-nonvolatile_good .align 2 .globl volatile_bad .type volatile_bad, @function volatile_bad: li 0,0 lbz 9,2(3) <--- troublesome load stb 0,2(3) lbz 9,3(3) <--- troublesome load stb 0,3(3) lbz 9,4(3) <--- troublesome load stb 0,4(3) lbz 9,5(3) <--- troublesome load stb 0,5(3) blr .size volatile_bad, .-volatile_bad .ident "GCC: (GNU) 3.4.4"