https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85585
--- Comment #1 from Peter Cordes <peter at cordes dot ca> ---
By comparison, the no-PIE table of pointers only needs one instruction:
movq CSWTCH.4(,%rdi,8), %rax
So all my suggestions cost 1 extra instruction on x86 in no-PIE mode, but at a
massive savings in data size.
clang -fPIE compiles the plain switch to the obvious / sane 2 instruction
sequence which should be our baseline for normal cases.
# clang6.0 -fPIE -O3 (switch compilers on the Godbolt link)
leaq .Lswitch.table.phy_modes(%rip), %rcx
movq (%rcx,%rax,8), %rax
Clang is willing to make a table that needs relocations for the entries. (My
suggestions all avoid that because they're based on offsets, not a table of
pointers. Avoiding rodata relocations that dirty a page and prevent sharing
has some non-zero value, although it's low on many architectures where memory
is cheap.)