On Tue, Feb 8, 2022 at 12:25 PM Jakub Jelinek <ja...@redhat.com> wrote:
>
> Hi!
>
> The following testcase ICEs, because
> (const_vector:V4SI [
>                 (const_int 0 [0]) repeated x3
>                 (const_int -2147483648 [0xffffffff80000000])
>             ])
> is recognized as valid easy_vector_constant in between split1 pass and
> end of RA.
> The problem is that such constants need to be split, and the only
> splitter for that is:
> (define_split
>   [(set (match_operand:VM 0 "altivec_register_operand")
>         (match_operand:VM 1 "easy_vector_constant_vsldoi"))]
>   "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && can_create_pseudo_p ()"
> There is only a single splitting pass before RA, so after that finishes,
> if something gets matched in between that and end of RA (after that
> can_create_pseudo_p () would be no longer true), it will never be
> successfully split and we ICE at final.cc time or earlier.
>
> The i386 backend (and a few others) already use
> (cfun->curr_properties & PROP_rtl_split_insns)
> as a test for split1 pass finished, so that some insns that should be split
> during split1 and shouldn't be matched afterwards are properly guarded.
>
> So, the following patch does that for vspltis_shifted too.
>
> Bootstrapped/regtested on powerpc64le-linux, ok for trunk?

Okay.

Thanks, David

>
> 2022-02-08  Jakub Jelinek  <ja...@redhat.com>
>
>         PR target/102140
>         * config/rs6000/rs6000.cc (vspltis_shifted): Return false also if
>         split1 pass has finished already.
>
>         * gcc.dg/pr102140.c: New test.
>
> --- gcc/config/rs6000/rs6000.cc.jj      2022-02-07 17:38:20.873123915 +0100
> +++ gcc/config/rs6000/rs6000.cc 2022-02-08 14:15:31.619505410 +0100
> @@ -6257,8 +6257,11 @@ vspltis_shifted (rtx op)
>      return false;
>
>    /* We need to create pseudo registers to do the shift, so don't recognize
> -     shift vector constants after reload.  */
> -  if (!can_create_pseudo_p ())
> +     shift vector constants after reload.  Don't match it even before RA
> +     after split1 is done, because there won't be further splitting pass
> +     before RA to do the splitting.  */
> +  if (!can_create_pseudo_p ()
> +      || (cfun->curr_properties & PROP_rtl_split_insns))
>      return false;
>
>    nunits = GET_MODE_NUNITS (mode);
> --- gcc/testsuite/gcc.dg/pr102140.c.jj  2022-02-08 14:24:25.839041166 +0100
> +++ gcc/testsuite/gcc.dg/pr102140.c     2022-02-08 14:24:03.038359745 +0100
> @@ -0,0 +1,23 @@
> +/* PR target/102140 */
> +/* { dg-do compile { target int128 } } */
> +/* { dg-options "-Og -fipa-cp -fno-tree-ccp -fno-tree-ter -Wno-psabi" } */
> +
> +typedef int __attribute__((__vector_size__ (64))) U;
> +typedef __int128 __attribute__((__vector_size__ (64))) V;
> +
> +int a, b;
> +
> +static void
> +bar (char c, V v)
> +{
> +  v *= c;
> +  U u = a + (U) v;
> +  (union { U b; }) { u };
> +  b = 0;
> +}
> +
> +void
> +foo (void)
> +{
> +  bar (1, (V){((__int128) 9223372036854775808ULL) << 64});
> +}
>
>         Jakub
>

Reply via email to