| Issue |
208989
|
| Summary |
[AggressiveInstCombine] suboptimal debruijin clz pattern codegen
|
| Labels |
llvm:instcombine,
missed-optimization
|
| Assignees |
|
| Reporter |
Andarwinux
|
after https://github.com/llvm/llvm-project/issues/207571
```c
typedef unsigned long long uint64_t;
void
get_msb_index (unsigned long *result, uint64_t value)
{
static const unsigned long deBruijnTable64[64] = {
63, 0, 58, 1, 59, 47, 53, 2, 60, 39, 48, 27, 54,
33, 42, 3, 61, 51, 37, 40, 49, 18, 28, 20, 55, 30,
34, 11, 43, 14, 22, 4, 62, 57, 46, 52, 38, 26, 32,
41, 50, 36, 17, 19, 29, 10, 13, 21, 56, 45, 25, 31,
35, 16, 9, 12, 44, 24, 15, 8, 23, 7, 6, 5
};
value |= value >> 1;
value |= value >> 2;
value |= value >> 4;
value |= value >> 8;
value |= value >> 16;
value |= value >> 32;
*result = deBruijnTable64[((value - (value >> 1))
* (uint64_t) 0x07EDD5E59A4E28C2ULL) >> 58];
}
```
https://godbolt.org/z/znP3eYshv
clang:
```asm
get_msb_index:
test rsi, rsi
je .LBB0_1
lzcnt rax, rsi
xor rax, 63
mov qword ptr [rdi], rax
ret
.LBB0_1:
mov eax, 63
mov qword ptr [rdi], rax
ret
```
gcc:
```asm
"get_msb_index":
lzcnt rsi, rsi
not esi
and esi, 63
mov eax, esi
mov QWORD PTR [rdi], rax
ret
```
LLVM generated a strange select:
```llvm
define dso_local void @get_msb_index(ptr nofree noundef writeonly captures(none) initializes((0, 8)) %result, i64 noundef %value) local_unnamed_addr {
entry:
%0 = tail call range(i64 0, 65) i64 @llvm.ctlz.i64(i64 %value, i1 true)
%1 = xor i64 %0, 63
%2 = icmp eq i64 %value, 0
%3 = select i1 %2, i64 63, i64 %1
store i64 %3, ptr %result, align 8
ret void
}
```
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs