Hi, The attached patch is to fix PR 49238 which is an ice-on-valid-code with an unrecognizable insn like:
(insn 61 60 62 3 (set (reg:SI 147 t) (geu:SI (reg:SI 3 r3) (const_int -1 [0xffffffffffffffff]))) (nil)) SH has GEU comparison only with register operands and we used a scratch register in that case after reload. expand_cbranchdi4 forgot it in the problematic situation. The patch is tested on sh4-unknown-linux-gnu with no new failures. The testsuite hunk is tested also on i686-pc-linux-gnu. Applied on trunk. Since this PR is a 4.5/4.6 regression, I'll backport it on those branches later. Regards, kaz -- 2011-06-01 Kaz Kojima <kkoj...@gcc.gnu.org> PR target/49238 * config/sh/sh.c (expand_cbranchdi4): Use a scratch register if needed when original operands are used for msw_skip comparison. [testsuite] * gcc.c-torture/compile/pr49238.c: New. diff -uprN ORIG/trunk/gcc/config/sh/sh.c trunk/gcc/config/sh/sh.c --- ORIG/trunk/gcc/config/sh/sh.c 2011-05-31 12:06:18.000000000 +0900 +++ trunk/gcc/config/sh/sh.c 2011-05-31 23:14:33.000000000 +0900 @@ -2199,6 +2199,13 @@ expand_cbranchdi4 (rtx *operands, enum r { operands[1] = op1h; operands[2] = op2h; + if (reload_completed + && ! arith_reg_or_0_operand (op2h, SImode) + && (true_regnum (op1h) || (comparison != EQ && comparison != NE))) + { + emit_move_insn (scratch, operands[2]); + operands[2] = scratch; + } } operands[3] = skip_label = gen_label_rtx (); diff -uprN ORIG/trunk/gcc/testsuite/gcc.c-torture/compile/pr49238.c trunk/gcc/testsuite/gcc.c-torture/compile/pr49238.c --- ORIG/trunk/gcc/testsuite/gcc.c-torture/compile/pr49238.c 1970-01-01 09:00:00.000000000 +0900 +++ trunk/gcc/testsuite/gcc.c-torture/compile/pr49238.c 2011-06-01 08:19:03.000000000 +0900 @@ -0,0 +1,18 @@ +/* PR target/49238 */ +extern int bar (void); + +void +foo (unsigned long long a, int b) +{ + int i; + + if (b) + for (a = -12; a >= 10; a = bar ()) + break; + else + return; + + for (i = 0; i < 10; i += 10) + if ((i == bar ()) | (bar () >= a)) + bar (); +}