-
Notifications
You must be signed in to change notification settings - Fork 14.8k
Open
Description
All clang versions on godbolt after 17.0.1 fail to optimize this lookup table into simple shift instructions
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
:
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.