On Tue, Jun 16, 2020 at 10:09:08AM +0800, Hongtao Liu via Gcc-patches wrote:
> > +  machine_mode qimode, himode;
> > +  unsigned int shift_constant, and_constant, xor_constant;
> > +  rtx vec_const_and, vec_const_xor;
> > +  rtx tmp, op1_subreg;
> > +  rtx (*gen_shift) (rtx, rtx, rtx);
> > +  rtx (*gen_and) (rtx, rtx, rtx);
> > +  rtx (*gen_xor) (rtx, rtx, rtx);
> > +  rtx (*gen_sub) (rtx, rtx, rtx);
> > +
> > +  /* Only optimize shift by constant.  */
> > +  if (!CONST_INT_P (op2))
> > +    return false;
> > +
> > +  qimode = GET_MODE (dest);
> > +  shift_constant = INTVAL (op2);
> >
> > I wonder if shift_constant shouldn't be unsigned HOST_WIDE_INT
> i don't think there would be some usage with shift_constant greater
> than UINT_MAX(4294967295),
> shouldn't unsigned int enough here?

What I mean is that op2 is a CONST_INT, which in theory can have any
HOST_WIDE_INT values.
By assigning that to unsigned int variable, you are effectively
testing shift % 0x100000000ULL instead of the shift.

So, it is fine to use unsigned int (or even unsigned char) var for the
shift_constant (shouldn't that be shift_amount?), but the test if it is
outside of range then should be performed on if (UINTVAL (op2) > 7).
And perhaps just don't bother with the out of bounds shifts, so just
  if (UINTVAL (op2) > 7)
    return false;
because that is just UB and no need to optimize invalid code.

        Jakub

Reply via email to