Issue 149073
Summary x86-64 optimization: (x <= 0xFFFFF) in '-Os' mode can convert to ((x >> 20) == 0)
Labels new issue
Assignees
Reporter Explorer09
    Test code

```c
#include <stdbool.h>
#include <stdint.h>

bool func1(uint32_t x) {
    return x < 0x100000U;
}

bool func2(uint32_t x) {
    return ((x >> 20) == 0);
}

bool func3(uint32_t x) {
    return ((x / 0x100000U) == 0);
}
```

The three functions are equivalent. Specifically the threshold constant to be compared with is a power-of-two. If there is no shortage of temporary registers, then the right shift version (that is, `func2`) will likely make the smallest code.

My expected result is like this (assuming `-Os` optimization, not `-O2`)

```x86asm
        shrl    $20, %edi
 sete    %al
        retq
```

Instead I got this (x86-64 clang 20.1.0 with `-Os` option, tested in Compiler Explorer):

```x86asm
        cmpl $1048576, %edi
        setb    %al
        retq
```

(Clang can recognize the three functions are equivalent. It just made suboptimal code among the possible choices.)

Note that in RISC-V targets of Clang, it does use the right shift to reduce code size

```text
        srliw   a0, a0, 20
        seqz    a0, a0
        ret
```
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to