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 ;)