On Wed, Nov 6, 2013 at 2:24 PM, Tejas Belagod <tbela...@arm.com> wrote:
>
> Hi,
>
> The attached patch eliminates moves of the form
>
>         set( (reg:DI n) vec_select:DI ( (reg:V2DI n) (parallel [const 0]))))
>
> i.e. eliminates lower lane moves between src and dst where src and dst are
> the same register and this causes rtl to instead use the destination
> register in the required mode.
>
> Also, if my understanding of Big-Endian is correct, this should be safe for
> big-endian targets as well.
>
> I've bootstrapped this on x64_64, regressed on aarch64-none-elf,
> aarch64_be-none-elf.
>
> OK for trunk?

It looks good to me (but I'm also wondering about bigendian).  Bill?

Can you add a testcase where this has an effect on code generation?

Thanks,
Richard.

> Thanks,
> Tejas Belagod
> ARM.
>
> 2013-11-06  Tejas Belagod  <tejas.bela...@arm.com>
>
> gcc/
>         * rtlanal.c (set_noop_p): Return nonzero in case of redundant
> vec_select
>         for same src and dst.
> diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
> index 9769b69..3e434cd 100644
> --- a/gcc/rtlanal.c
> +++ b/gcc/rtlanal.c
> @@ -1180,6 +1180,25 @@ set_noop_p (const_rtx set)
>        dst = SUBREG_REG (dst);
>      }
>
> +  /* This is big-endian-safe because the elements are kept in target
> +     memory order.  So, for eg. PARALLEL element value of 2 is the same in
> +     either endian-ness.  */
> +  if (GET_CODE (src) == VEC_SELECT
> +      && REG_P (XEXP (src, 0)) && REG_P (dst)
> +      && REGNO (XEXP (src, 0)) == REGNO (dst))
> +    {
> +      rtx par = XEXP (src, 1);
> +      int i;
> +
> +      for (i = 0; i < XVECLEN (par, 0); i++)
> +       {
> +         rtx tem = XVECEXP (par, 0, i);
> +         if (!CONST_INT_P (tem) || INTVAL (tem) != i)
> +           return 0;
> +       }
> +      return 1;
> +    }
> +
>    return (REG_P (src) && REG_P (dst)
>           && REGNO (src) == REGNO (dst));
>  }

Reply via email to