Doing some work on the msp430 failures, I discovered that this patch: > --- gcc/expmed.c.jj 2013-05-07 10:26:46.000000000 +0200 > +++ gcc/expmed.c 2013-05-11 09:11:54.087412982 +0200 > @@ -2181,14 +2182,22 @@ expand_shift_1 (enum tree_code code, enu > rtx temp1; > > new_amount = op1; > - if (CONST_INT_P (op1)) > + if (op1 == const0_rtx) > + return shifted; > + else if (CONST_INT_P (op1)) > other_amount = GEN_INT (GET_MODE_BITSIZE (mode) > - INTVAL (op1)); > else > - other_amount > - = simplify_gen_binary (MINUS, GET_MODE (op1), > - GEN_INT (GET_MODE_PRECISION (mode)), > - op1); > + { > + other_amount > + = simplify_gen_unary (NEG, GET_MODE (op1), > + op1, GET_MODE (op1)); > + other_amount > + = simplify_gen_binary (AND, GET_MODE (op1), > + other_amount, > + GEN_INT (GET_MODE_PRECISION (mode) > + - 1)); > + } > > shifted = force_reg (mode, shifted); >
causes an ICE in gcc.c-torture/execute/20020226-1.c, which we tried to avoid by adding an "addneghi" pattern (which itself has a bug, hence me investigating). It seems like the code creates an (and (neg ...)) RTL pattern in HImode. If you try to do an SImode shift, that pattern (the shift count portion) needs to be converted HI->SI to match the msp430's shift pattern (it's an ABI call, must be SImode). The code that does that hits the "convert by parts" case and just copies the generated RTL to a register, using emit_move, *without* checking to see if it's valid. The result is that the (and (neg ...)) RTL makes it all the way to recog and fails to match anything. Where would/should such validation take place? Reproducible if you take out the "andneghi" pattern in msp430.md