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

Reply via email to