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)

Reply via email to