On Tue, 16 Feb 2016, Jakub Jelinek wrote: > 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.
Ah, yes - here we're still using op0 mode. For OImode wouldn't we get a CONST_DOUBLE or CONST_WIDE_INT though? > 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. Works for me. Thanks, Richard. > 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 > > -- Richard Biener <rguent...@suse.de> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)