On Mon, Feb 15, 2016 at 08:43:22PM +0100, Richard Biener wrote: > On February 15, 2016 7:15:35 PM GMT+01:00, Jakub Jelinek <ja...@redhat.com> > wrote: > >On Mon, Feb 15, 2016 at 06:58:45PM +0100, Richard Biener wrote: > >> We could also force_reg those at expansion or apply > >SHIFT_COUNT_TRUNCATED to those invalid constants there. > > > >Sure, but for force_reg we'd still need the gen_int_mode anyway. > >As for SHIFT_COUNT_TRUNCATED, it should have been applied already from > >the > >caller - expand_shift_1. > > But then no out of bound values should remain. > Until we get 256bit ints where your workaround wouldn't work either?
Of course it would work, because in that case mode would be OImode, not QImode, and thus the code would ensure the shift count is valid OImode constant. Anyway, the patch I've posted has been broken for vector shifts, the last argument to gen_int_mode should have been GET_MODE_INNER (mode). Here is a variant of that patch with force_reg, seems to work on aarch64 and x86_64. 2016-02-16 Jakub Jelinek <ja...@redhat.com> PR rtl-optimization/69764 PR rtl-optimization/69771 * optabs.c (expand_binop): Ensure for shift optabs invalid CONST_INT op1 is valid for GET_MODE_INNER (mode) and force it into a reg. --- gcc/optabs.c.jj 2016-02-15 22:22:46.161674598 +0100 +++ gcc/optabs.c 2016-02-16 08:20:01.206889067 +0100 @@ -1125,6 +1125,16 @@ expand_binop (machine_mode mode, optab b op1 = negate_rtx (mode, op1); binoptab = add_optab; } + /* For shifts, constant invalid op1 might be expanded from different + mode than MODE. As those are invalid, force them to a register + to avoid further problems during expansion. */ + else if (CONST_INT_P (op1) + && shift_optab_p (binoptab) + && UINTVAL (op1) >= GET_MODE_BITSIZE (GET_MODE_INNER (mode))) + { + op1 = gen_int_mode (INTVAL (op1), GET_MODE_INNER (mode)); + op1 = force_reg (GET_MODE_INNER (mode), op1); + } /* Record where to delete back to if we backtrack. */ last = get_last_insn (); Jakub