https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87245
Bug ID: 87245 Summary: [missed optimization] switching on indices of struct members Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: herring at lanl dot gov Target Milestone: --- Consider a simple struct whose members can be accessed by name or by index: struct vec {double x,y,z;}; double get(const struct vec *v,unsigned long i) { switch(i) { case 0: return v->x; case 1: return v->y; case 2: return v->z; } } Godbolt's trunk x86_64 build produces at -O3 get: cmpq $1, %rsi ja .L2 je .L11 movsd (%rdi), %xmm0 ret .L2: cmpq $2, %rsi jne .L12 movsd 16(%rdi), %xmm0 ret .L11: movsd 8(%rdi), %xmm0 ret .L12: ret when of course get: movsd (%rdi,%rsi,8), %xmm0 ret would suffice. (Apologies if I picked the wrong -optimization component.) Bonus points for collapsing double get(const struct vec *arr,unsigned long i) { arr+=i/3; switch(i%3) { case 0: return arr->x; case 1: return arr->y; case 2: return arr->z; } } to the same two instructions.