This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c/39255] New: bitfield alias generates incorrect assembly


Consider the following code:

typedef struct {
    unsigned long A:16;
    unsigned long B:48;
} bits;

int
wrong(unsigned long y)
{
    bits *p = (bits *) &y;

    if (y == 0 || p->A >= 512) {
        return (1);
    }

    return (0);
}

int
right(unsigned long y)
{
    bits *p = (bits *) &y;

    if (y == 0 || p->A >= 512) {
        return (-1);
    }

    return (0);
}

The *only* difference between right() and wrong() is the return value in the IF
clause. With -O2, the function right() compiles to correct, if suboptimal,
code. The function wrong(), however, generates the following:

wrong:
    .prologue
    .body
    .mmi
    cmp.ne p6, p7 = 0, r32
    nop 0
    addl r14 = 511, r0
    .mmi
    ld2 r15 = [r12]    <<<<<< HUH?
    st8 [r12] = r32    <<<<<< HUH?
    addl r8 = 1, r0
    .mib
    nop 0
    nop 0
    (p7) br.ret.dpnt.many rp
    ;;
    .mmi
    cmp4.gtu p6, p7 = r15, r14
    ;;wrong:
    .prologue
    .body
    .mmi
    cmp.ne p6, p7 = 0, r32
    nop 0
    addl r14 = 511, r0
    .mmi
    ld2 r15 = [r12]
    st8 [r12] = r32
    addl r8 = 1, r0
    .mib
    nop 0
    nop 0
    (p7) br.ret.dpnt.many rp
    ;;
    .mmi
    cmp4.gtu p6, p7 = r15, r14
    ;;
    (p6) addl r14 = 1, r0
    (p7) mov r14 = r0
    ;;
    .mib
    nop 0
    mov r8 = r14
    br.ret.sptk.many rp
    .endp wrong#

    (p6) addl r14 = 1, r0
    (p7) mov r14 = r0
    ;;
    .mib
    nop 0
    mov r8 = r14
    br.ret.sptk.many rp
    .endp wrong#

It is clearly wrong to perform the load from the stack before the proper value
(r32) has been stored. When run, the value of p->A is the low 16 bits of
whatever was stored on the stack before.


-- 
           Summary: bitfield alias generates incorrect assembly
           Product: gcc
           Version: 4.3.1
            Status: UNCONFIRMED
          Severity: critical
          Priority: P3
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: jsworley at qwest dot net
  GCC host triplet: i686-linux-gnu
GCC target triplet: ia64-linux-gnu


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]