Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GCC - two identical functions but the code generated differs. Why?

The code:

#define OPPOSITE(c) (*((typeof(x) *)&(x)))

int foo(volatile int x)
{
    OPPOSITE(x) = OPPOSITE(x) + OPPOSITE(x);
    return x;
}

int bar(volatile int x)
{
    OPPOSITE(x) = OPPOSITE(x) + OPPOSITE(x);
    return x;
}

The result (-Os):

foo:
        mov     DWORD PTR [rsp-4], edi
        mov     eax, DWORD PTR [rsp-4]
        mov     edx, DWORD PTR [rsp-4]
        add     eax, edx
        mov     DWORD PTR [rsp-4], eax
        mov     eax, DWORD PTR [rsp-4]
        ret
bar:
        mov     DWORD PTR [rsp-4], edi
        mov     eax, DWORD PTR [rsp-4]
        add     eax, eax
        ret

or ARM gcc. (-O3)

foo:
        sub     sp, sp, #8
        str     r0, [sp, #4]
        ldr     r3, [sp, #4]
        ldr     r2, [sp, #4]
        add     r3, r3, r2
        str     r3, [sp, #4]
        ldr     r0, [sp, #4]
        add     sp, sp, #8
        bx      lr
bar:
        sub     sp, sp, #8
        str     r0, [sp, #4]
        ldr     r0, [sp, #4]
        lsl     r0, r0, #1
        add     sp, sp, #8
        bx      lr

https://godbolt.org/z/6z5Td9GsP

like image 824
0___________ Avatar asked Jan 18 '26 21:01

0___________


1 Answers

You can replace the code with

int foo(volatile int x)
{
        x = x + x;
        return x;
}

int bar(volatile int x)
{
    x = x + x;
    return x;
}

And have the same effect. No other C compiler generates this effect other than GCC, so I think it's reasonable to say this is some sort of compiler bug.

like image 150
pizzamonkey Avatar answered Jan 21 '26 11:01

pizzamonkey