Issue 172674
Summary Missed optimization: Avoidable masking for range check of top bits via shifting
Labels new issue
Assignees
Reporter dzaima
    This code:

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

bool foo(uint64_t x) {
    uint16_t t = x >> 48;
    return t >= 10 && t < 20;
}

bool bar(uint64_t x) {
    uint32_t t = x >> 32;
    return t >= 123 && t < 456;
}

bool baz(uint64_t x) {
    uint8_t t = x >> (64-8);
    return t >= 200 && t < 205;
}
```

compiled with `-O3` results in avoidable `and`s / `movzx`s or otherwise inefficient range checks:

```asm
foo:
 shr     rdi, 49
        add     edi, 32763
        and     edi, 32767
 cmp     edi, 5
        setb    al
        ret

bar:
        movabs rax, -528280977408
        add     rax, rdi
        shr     rax, 32
 cmp     eax, 333
        setb    al
        ret

baz:
        shr rdi, 56
        add     edi, 56
        movzx   eax, dil
        cmp eax, 5
        setb    al
        ret
```
whereas GCC  manages to do all of those with just `shr`+`sub`+`cmp`.

https://godbolt.org/z/ETe9zMj4b

(similar things apply to ARM & RISC-V (and presumably others) too, using x86-64 for simplicity; manually doing the desired subtraction & comparison instead of two comparisons doesn't help as LLVM canonicalizes it to the same thing anyway)
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to