Optimization regression after llvm 17
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
All clang versions on godbolt after 17.0.1 fail to optimize this lookup table into simple shift instructions
```c
typedef struct {
#define X(a) int x##a : 1;
X(0) X(1) X(2) X(3)
X(4) X(5) X(6) X(7)
X(8) X(9) X(10) X(11)
#undef X
} bits;
int get(bits b, int idx) {
switch(idx){
#define X(a) case a: return b.x##a; break;
X(0) X(1) X(2) X(3)
X(4) X(5) X(6) X(7)
X(8) X(9) X(10) X(11)
#undef X
default: __builtin_unreachable();
}
}
```
with clang 17.0.1 `-target x86_64 -O3`:
```x86asm
get:
mov cl, 15
sub cl, sil
shl edi, cl
movsx eax, di
sar eax, 15
ret
```
but later clang versions don't do this anymore, and instead emit a jump table, with a shift in each case
See: https://godbolt.org/z/c79q7EY4P
(I opened the opt pipeline viewer and noticed that the output of InstCombinerPass is different.
I don't have much knowledge about the internals of llvm tho.
Contributor guide
Research direction
Reproduce the optimization difference using the C example, the Godbolt link, and the stated x86_64 -O3 settings. Compare the output around InstCombinerPass between clang 17.0.1 and later versions to identify the changed transformation. Done means restoring the optimized shift sequence and adding an LLVM regression test for the case.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c
- Domain
- compilers, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100