llvm / llvm/llvm-project

Optimization regression after llvm 17

Open
#162,832 1 comment 0 reactions 0 assignees View on GitHub
llvm:optimizations missed-optimization
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.