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.


Reply via email to