Here's a strange case of poor code generation with -Os. unsigned short foo2 (unsigned char on_off, unsigned short *puls) { return puls[on_off-1]; }
With -O2, it's fine: movzbl %dil, %edi movzwl -2(%rsi,%rdi,2), %eax ret With -Os it's really weird: movzbl %dil, %eax movl $1, %edi subq %rax, %rdi imulq $-2, %rdi, %rdi movw (%rdi,%rsi), %ax ret The problem here seems to be that the FE (or the GIMPLE generation) transforms addr + ((on_off-1)*2) into addr + ((1-on_off)*-2) and nothing in -Os has the wit to recover. This badly affects targets with no hardware multiplier, which end up calling libgcc to do the multiply. Is this a well-known problem? Andrew.