https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92985
--- Comment #1 from Peter Dimov <pdimov at gmail dot com> --- Reformulating the switch in terms of integral offsets struct X2 { int x, y, z; int operator[]( std::size_t i ) const noexcept { std::ptrdiff_t k0 = &x - &x; std::ptrdiff_t k1 = &y - &x; std::ptrdiff_t k2 = &z - &x; std::ptrdiff_t k; switch( i ) { case 0: k = k0; break; case 1: k = k1; break; case 2: k = k2; break; default: __builtin_unreachable(); } return *( &x + k ); } }; results in the desired f2(X2 const&, unsigned long): mov eax, DWORD PTR [rdi+rsi*4] ret (https://godbolt.org/z/YxhNSx)