| Issue |
108829
|
| Summary |
Simple bit manipulation resulting in disjoint set could be tracked
|
| Labels |
new issue
|
| Assignees |
|
| Reporter |
Validark
|
I just saw this scenario in my real code (simplified):
```zig
export fn foo(s: u64) u64 {
const iter = s & ~(s << 1);
return iter | (iter << 1);
}
```
For your convenience, here is a C version:
```c
#include <stdint.h>
uint64_t foo(uint64_t s) {
uint64_t iter = s & ~(s << 1);
return iter | (iter << 1);
}
```
Currently gives this assembly:
```asm
foo:
lea rax, [rdi + rdi]
andn rax, rax, rdi
lea rcx, [rax + rax]
or rax, rcx
ret
```
I realized that there is an optimization here, we can turn the `|` into a `+`, because `iter` is necessarily disjoint with `iter << 1`. [Z3 agrees](https://alive2.llvm.org/ce/z/ALEMHA). That means we can get this emit:
```asm
foo:
lea rax, [rdi + rdi]
andn rax, rax, rdi
lea rax, [rax + 2*rax]
ret
```
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs