http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51244

--- Comment #4 from Oleg Endo <oleg.e...@t-online.de> 2011-12-27 23:17:03 UTC 
---
(In reply to comment #1)
> 
> >  return a >= 0 && b >= 0 ? c : d;
> 
> x >= 0 is expanded to the sequence like
> 
>   ra = not x
>   rb = -31
>   rc = ra >> (neg rb)
>   T = (rc == 0)
>   conditional jump
> 
> and combine tries to simplify it.  combine simplifies b >= 0
> successfully into shll and bt but fails to simplify a >= 0.
> It seems that combine doesn't do constant propagation well and
> misses the constant -31.

Another simpler fail:

int test_func_22_NG (int a, int b, int c, int d)
{
  return a >= 0;
}

becomes:
        not     r4,r0   ! 9    one_cmplsi2    [length = 2]
        mov     #-31,r1 ! 12    movsi_ie/3    [length = 2]
        rts             ! 31    *return_i    [length = 2]
        shld    r1,r0   ! 13    lshrsi3_d    [length = 2]

which could be:
        cmp/pz    r4
        rts
        movt    r0

>From what I could observe, this is caused by the various shift insns which
leads combine to this result.  For example, the shll, branch sequence that
is used instead of cmp/pz, branch is caused by the ashlsi_c insn, which
defines a lt:SI comparison.  Although that is correct, using cmp/pz could
be better, since it does not modify the reg, and on SH4 it is an MT group
insn.  The ashlsi_c insn / lt:SI picking can be avoided by adjusting the 
rtx costs, for instance (just tried it out briefly).

I think a peephole in this case could fix some of the symptoms but not the
actual cause.  I'll see if I can come up with something that works without a
peephole, even though all the shift stuff looks a bit suspicious ;)

Reply via email to