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.