| 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