On Tue, 18 Nov 2014, Jakub Jelinek wrote:

> Hi!
> 
> OImode/XImode on i?86/x86_64 are not <= MAX_BITSIZE_MODE_ANY_INT, because
> they are never used for integer arithmetics (and there is no way
> to represent all their values in RTL if not using CONST_WIDE_INT).
> As the following testcase shows, simplify_immed_subreg can be called
> with such modes though, e.g. trying to forward propagate a CONST_VECTOR
> (i?86/x86_64 handles all zeros and all ones as CONST_VECTORs that can appear
> in the IL directly) into a SUBREG_REG.

So we have (subreg:OI (reg:V4DF ...) ...) for example?  What do we
end doing with that OI mode subreg?  (why can't we simply use the
V4DF one?)

> The following patch instead of ICE handles the most common cases (all 0
> and all 1 CONST_VECTORs) and returns NULL otherwise.
> 
> Before wide-int got merged, the testcase worked, though the code didn't
> bother checking anything, just created 0 or constm1_rtx for the two cases
> that could happen and if something else appeared, could just return what
> matched low TImode (or DImode for -m32).
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Looks ok to me.  Not sure if the zero/all-ones case really happens that
much to be worth special-casing - I think you could use
fixed_wide_int<proper-size> and simply see if the result is representable
in a CONST_INT/CONST_DOUBLE?  Can you try if that works?  It looks like
the patch may be smaller for that.

Thanks,
Richard.

> 2014-11-18  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR target/63910
>       * simplify-rtx.c (simplify_immed_subreg): For integer modes
>       wider than MAX_BITSIZE_MODE_ANY_INT, handle all zeros and all ones
>       and for other values return NULL_RTX.
> 
>       * gcc.target/i386/pr63910.c: New test.
> 
> --- gcc/simplify-rtx.c.jj     2014-11-11 00:06:19.000000000 +0100
> +++ gcc/simplify-rtx.c        2014-11-18 10:17:01.198668555 +0100
> @@ -5505,6 +5505,21 @@ simplify_immed_subreg (machine_mode oute
>           HOST_WIDE_INT tmp[MAX_BITSIZE_MODE_ANY_INT / 
> HOST_BITS_PER_WIDE_INT];
>           wide_int r;
>  
> +         if (GET_MODE_PRECISION (outer_submode) > MAX_BITSIZE_MODE_ANY_INT)
> +           {
> +             /* Handle just all zeros and all ones CONST_VECTORs in
> +                this case.  */
> +             if ((vp[0] & value_mask) == 0)
> +               elems[elem] = const0_rtx;
> +             else if ((vp[0] & value_mask) == value_mask)
> +               elems[elem] = constm1_rtx;
> +             else
> +               return NULL_RTX;
> +             for (i = value_bit; i < elem_bitsize; i += value_bit)
> +               if ((vp[i / value_bit] & value_mask) != (vp[0] & value_mask))
> +                 return NULL_RTX;
> +             break;
> +           }
>           for (u = 0; u < units; u++)
>             {
>               unsigned HOST_WIDE_INT buf = 0;
> @@ -5516,8 +5531,6 @@ simplify_immed_subreg (machine_mode oute
>               tmp[u] = buf;
>               base += HOST_BITS_PER_WIDE_INT;
>             }
> -         gcc_assert (GET_MODE_PRECISION (outer_submode)
> -                     <= MAX_BITSIZE_MODE_ANY_INT);
>           r = wide_int::from_array (tmp, units,
>                                     GET_MODE_PRECISION (outer_submode));
>           elems[elem] = immed_wide_int_const (r, outer_submode);
> --- gcc/testsuite/gcc.target/i386/pr63910.c.jj        2014-11-18 
> 10:12:24.282659318 +0100
> +++ gcc/testsuite/gcc.target/i386/pr63910.c   2014-11-18 10:12:00.000000000 
> +0100
> @@ -0,0 +1,12 @@
> +/* PR target/63910 */
> +/* { dg-do compile } */
> +/* { dg-options "-O -mstringop-strategy=vector_loop -mavx512f" } */
> +
> +extern void bar (float *c);
> +
> +void
> +foo (void)
> +{
> +  float c[1024] = { };
> +  bar (c);
> +}
> 
>       Jakub
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE LINUX GmbH, GF: Jeff Hawn, Jennifer Guild, Felix Imendoerffer, HRB 21284
(AG Nuernberg)
Maxfeldstrasse 5, 90409 Nuernberg, Germany

Reply via email to