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 tree-optimization/45903] unnecessary load of 32/64bit variable when only 8 bits are needed


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

--- Comment #1 from Zdenek Sojka <zsojka at seznam dot cz> 2010-10-06 10:03:48 UTC ---
The first example should actually be:

f64:
mov al, DWORD PTR [esp+5]
add al, DWORD PTR [esp+13]
ret

This happens to other operators, not just plus:

uint8_t f64or(uint64_t a, uint64_t b)
{
    return (a >> 8) | (b >> 8);
}

is compiled as:

f64or:
        push    ebx
        mov     ecx, DWORD PTR [esp+8]
        mov     ebx, DWORD PTR [esp+12]
        mov     eax, DWORD PTR [esp+16]
        mov     edx, DWORD PTR [esp+20]
        shrd    ecx, ebx, 8
        pop     ebx
        shrd    eax, edx, 8
        or      eax, ecx
        ret

or when the shift is done after the operation:

uint8_t f64or2(uint64_t a, uint64_t b)
{
    return (a | b) >> 8;
}

results in:

f64or2:
        mov     ecx, DWORD PTR [esp+12]
        mov     eax, DWORD PTR [esp+4]
        mov     edx, DWORD PTR [esp+8]
        or      eax, ecx
        mov     ecx, DWORD PTR [esp+16]
        or      edx, ecx
        shrd    eax, edx, 8
        ret

When there is no shift, code is better:

uint8_t f64or3(uint64_t a, uint64_t b)
{
    return a | b;
}

is compiled as

f64or3:
        mov     eax, DWORD PTR [esp+12]
        or      al, BYTE PTR [esp+4]
        ret


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