Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Missed optimization in clang only on powers of two

When compiling with -Ofast, clang correctly deduces that the following function will always return 0.

int zero(bool b) {
    const int x = 5;
    return (x * b) + (-x * b);
}

compiles to

zero(bool):                               # @zero(bool)
        xor     eax, eax
        ret

However, if I change the constant to be any power of two (except 1 or 0), clang no longer makes the same deduction

int zero(bool b) {
    const int x = 8;
    return (x * b) + (-x * b);
}

compiles to

zero(bool):                               # @zero(bool)
        mov     eax, edi
        shl     eax, 3
        xor     dil, 1
        movzx   ecx, dil
        lea     eax, [rax + 8*rcx]
        add     eax, -8
        ret

The code compiled with compiler explorer.

If I change the function parameter to be anything bigger (short, int, long) the optimization is correctly made.

What causes this weird edge case?

like image 843
spyr03 Avatar asked Jun 02 '19 16:06

spyr03


1 Answers

It is an optimization problem in Clang, which was fixed after version 10.0.0. We can reproduce this problem in version 9.0.1.

Compared versions 9.0.1 and 10.0.0 in compiler explorer.

like image 169
Nejc Galof Avatar answered Nov 13 '22 10:11

Nejc Galof