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"

Reply via email to