On Fri, Feb 17, 2017 at 7:49 PM, Jakub Jelinek <ja...@redhat.com> wrote:
> Hi!
>
> The masks for builtins seems to be quite messy.  Most of
> the builtins have a single OPTION_MASK_ISA_* in there and that is
> clear (i.e. that the builtin is only enabled/usable if that isa
> bit is on).  Then we have 0 and that is meant for always enabled builtins.
> Then there is OPTION_MASK_ISA_xxx | OPTION_MASK_ISA_64BIT and that
> means (according to def_builtin code and comments) that we enable
> only if TARGET_64BIT and the rest without the  | OPTION_MASK_ISA_64BIT
> needs to be satisfied.  Then there is
> OPTION_MASK_ISA_xxx | OPTION_MASK_ISA_AVX512VL and that is again
> in def_builtin code and comments documented to be only enabled if
> -mavx512vl and the rest without the | OPTION_MASK_ISA_AVX512VL
> needs to be satisfied.  Then we have
> OPTION_MASK_ISA_FMA | OPTION_MASK_ISA_FMA4
> OPTION_MASK_ISA_SSE4_2 | OPTION_MASK_ISA_CRC32
> OPTION_MASK_ISA_SSE | OPTION_MASK_ISA_3DNOW_A
> def_builtin here as well as ix86_expand_builtin suggest here that it
> is either SSE or 3dNOWa etc. (I believe at least the last one
> is meant to be that, no idea about the other two).
> And finally various builtins use ~OPTION_MASK_ISA_64BIT, which I have
> no idea what people adding those really meant to express.  At least
> for e.g. __builtin_ia32_pause I'd expect it wants to be enabled
> everywhere (that is 0 though), while what both def_builtin and
> ix86_expand_builtin actually implement for ~OPTION_MASK_ISA_64BIT
> is that it is enabled whenever any ISA (other than OPTION_MASK_ISA_64BIT)
> is set and disabled otherwise.  So, e.g. -m32 -march=i386 -mno-sahf -mno-mmx
> -mno-sse disables __builtin_ia32_pause, __builtin_ia32_rdtsc,
> __builtin_ia32_rolhi etc.
>
> For OPTION_MASK_ISA_64BIT and OPTION_MASK_ISA_AVX512VL, while
> def_builtin implements something documented (and what makes sense),
> ix86_expand_builtin actually takes it as any of the ISAs enabled,
> so if you manage to define the builtin earlier (e.g. through including
> x86intrin.h), then one can use
> OPTION_MASK_ISA_AVX512BW | OPTION_MASK_ISA_AVX512VL
> builtin (meant to be enabled if both are on) in a function where just one
> of them is on (-mavx512bw or -mavx512vl), if both aren't on, that will ICE.
> Similarly, for OPTION_MASK_ISA_LWP | OPTION_MASK_ISA_64BIT, if the
> builtin is defined earlier, it will be enabled even in -mno-lwp -m64
> function and ICE (not for -m32 -mlwp, because -m64 is a global TU option
> and so nothing will define the builtin).
>
> This patch attempts to resolve it by changing all ~OPTION_MASK_ISA_64BIT
> builtins to 0, handling xxx | OPTION_MASK_ISA_64BIT
> as must satisfy TARGET_64BIT and xxx, handling yyy |
> OPTION_MASK_ISA_AVX512VL as must satisfy -mavx512vl and yyy and for the
> rest, if 0, enabling always, otherwise requiring at least one of the ISAs
> enabled from the bitmask.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
> Or do we want a different behavior (then what and why)?

Thanks for the detailed analysis. After some thinking, I think that
the above is the correct approach.

> 2017-02-17  Jakub Jelinek  <ja...@redhat.com>
>
>         PR target/79568
>         * config/i386/i386.c (ix86_expand_builtin): Handle
>         OPTION_MASK_ISA_AVX512VL and OPTION_MASK_ISA_64BIT in
>         ix86_builtins_isa[fcode].isa as a requirement of those
>         flags and any other flag in the bitmask.
>         (ix86_init_mmx_sse_builtins): Use 0 instead of
>         ~OPTION_MASK_ISA_64BIT as mask.
>         * config/i386/i386-builtin.def (__builtin_ia32_rdtsc,
>         __builtin_ia32_rdtscp, __builtin_ia32_pause, __builtin_ia32_bsrsi,
>         __builtin_ia32_rdpmc, __builtin_ia32_rolqi, __builtin_ia32_rolhi,
>         __builtin_ia32_rorqi, __builtin_ia32_rorhi): Likewise.
>
>         * gcc.target/i386/pr79568-1.c: New test.
>         * gcc.target/i386/pr79568-2.c: New test.
>         * gcc.target/i386/pr79568-3.c: New test.

OK for mainline and eventually branches.

Thanks,
Uros.

> --- gcc/config/i386/i386.c.jj   2017-02-17 11:11:27.000000000 +0100
> +++ gcc/config/i386/i386.c      2017-02-17 17:10:07.899194674 +0100
> @@ -32075,11 +32075,11 @@ ix86_init_mmx_sse_builtins (void)
>                IX86_BUILTIN_SBB64);
>
>    /* Read/write FLAGS.  */
> -  def_builtin (~OPTION_MASK_ISA_64BIT, "__builtin_ia32_readeflags_u32",
> +  def_builtin (0, "__builtin_ia32_readeflags_u32",
>                 UNSIGNED_FTYPE_VOID, IX86_BUILTIN_READ_FLAGS);
>    def_builtin (OPTION_MASK_ISA_64BIT, "__builtin_ia32_readeflags_u64",
>                 UINT64_FTYPE_VOID, IX86_BUILTIN_READ_FLAGS);
> -  def_builtin (~OPTION_MASK_ISA_64BIT, "__builtin_ia32_writeeflags_u32",
> +  def_builtin (0, "__builtin_ia32_writeeflags_u32",
>                 VOID_FTYPE_UNSIGNED, IX86_BUILTIN_WRITE_FLAGS);
>    def_builtin (OPTION_MASK_ISA_64BIT, "__builtin_ia32_writeeflags_u64",
>                 VOID_FTYPE_UINT64, IX86_BUILTIN_WRITE_FLAGS);
> @@ -36723,9 +36723,18 @@ ix86_expand_builtin (tree exp, rtx targe
>       Originally the builtin was not created if it wasn't applicable to the
>       current ISA based on the command line switches.  With function specific
>       options, we need to check in the context of the function making the call
> -     whether it is supported.  */
> -  if ((ix86_builtins_isa[fcode].isa
> -       && !(ix86_builtins_isa[fcode].isa & ix86_isa_flags))
> +     whether it is supported.  Treat AVX512VL specially.  For other flags,
> +     if isa includes more than one ISA bit, treat those are requiring any
> +     of them.  For AVX512VL, require both AVX512VL and the non-AVX512VL
> +     ISAs.  Similarly for 64BIT, but we shouldn't be building such builtins
> +     at all, -m64 is a whole TU option.  */
> +  if (((ix86_builtins_isa[fcode].isa
> +       & ~(OPTION_MASK_ISA_AVX512VL | OPTION_MASK_ISA_64BIT))
> +       && !(ix86_builtins_isa[fcode].isa
> +           & ~(OPTION_MASK_ISA_AVX512VL | OPTION_MASK_ISA_64BIT)
> +           & ix86_isa_flags))
> +      || ((ix86_builtins_isa[fcode].isa & OPTION_MASK_ISA_AVX512VL)
> +         && !(ix86_isa_flags & OPTION_MASK_ISA_AVX512VL))
>        || (ix86_builtins_isa[fcode].isa2
>           && !(ix86_builtins_isa[fcode].isa2 & ix86_isa_flags2)))
>      {
> --- gcc/config/i386/i386-builtin.def.jj 2017-01-26 13:22:55.000000000 +0100
> +++ gcc/config/i386/i386-builtin.def    2017-02-17 17:07:20.771407936 +0100
> @@ -88,9 +88,9 @@ BDESC_END (PCMPISTR, SPECIAL_ARGS)
>
>  /* Special builtins with variable number of arguments.  */
>  BDESC_FIRST (special_args, SPECIAL_ARGS,
> -       ~OPTION_MASK_ISA_64BIT, CODE_FOR_nothing, "__builtin_ia32_rdtsc", 
> IX86_BUILTIN_RDTSC, UNKNOWN, (int) UINT64_FTYPE_VOID)
> -BDESC (~OPTION_MASK_ISA_64BIT, CODE_FOR_nothing, "__builtin_ia32_rdtscp", 
> IX86_BUILTIN_RDTSCP, UNKNOWN, (int) UINT64_FTYPE_PUNSIGNED)
> -BDESC (~OPTION_MASK_ISA_64BIT, CODE_FOR_pause, "__builtin_ia32_pause", 
> IX86_BUILTIN_PAUSE, UNKNOWN, (int) VOID_FTYPE_VOID)
> +       0, CODE_FOR_nothing, "__builtin_ia32_rdtsc", IX86_BUILTIN_RDTSC, 
> UNKNOWN, (int) UINT64_FTYPE_VOID)
> +BDESC (0, CODE_FOR_nothing, "__builtin_ia32_rdtscp", IX86_BUILTIN_RDTSCP, 
> UNKNOWN, (int) UINT64_FTYPE_PUNSIGNED)
> +BDESC (0, CODE_FOR_pause, "__builtin_ia32_pause", IX86_BUILTIN_PAUSE, 
> UNKNOWN, (int) VOID_FTYPE_VOID)
>
>  /* 80387 (for use internally for atomic compound assignment).  */
>  BDESC (0, CODE_FOR_fnstenv, "__builtin_ia32_fnstenv", IX86_BUILTIN_FNSTENV, 
> UNKNOWN, (int) VOID_FTYPE_PVOID)
> @@ -385,13 +385,13 @@ BDESC_END (SPECIAL_ARGS, ARGS)
>
>  /* Builtins with variable number of arguments.  */
>  BDESC_FIRST (args, ARGS,
> -       ~OPTION_MASK_ISA_64BIT, CODE_FOR_bsr, "__builtin_ia32_bsrsi", 
> IX86_BUILTIN_BSRSI, UNKNOWN, (int) INT_FTYPE_INT)
> +       0, CODE_FOR_bsr, "__builtin_ia32_bsrsi", IX86_BUILTIN_BSRSI, UNKNOWN, 
> (int) INT_FTYPE_INT)
>  BDESC (OPTION_MASK_ISA_64BIT, CODE_FOR_bsr_rex64, "__builtin_ia32_bsrdi", 
> IX86_BUILTIN_BSRDI, UNKNOWN, (int) INT64_FTYPE_INT64)
> -BDESC (~OPTION_MASK_ISA_64BIT, CODE_FOR_nothing, "__builtin_ia32_rdpmc", 
> IX86_BUILTIN_RDPMC, UNKNOWN, (int) UINT64_FTYPE_INT)
> -BDESC (~OPTION_MASK_ISA_64BIT, CODE_FOR_rotlqi3, "__builtin_ia32_rolqi", 
> IX86_BUILTIN_ROLQI, UNKNOWN, (int) UINT8_FTYPE_UINT8_INT)
> -BDESC (~OPTION_MASK_ISA_64BIT, CODE_FOR_rotlhi3, "__builtin_ia32_rolhi", 
> IX86_BUILTIN_ROLHI, UNKNOWN, (int) UINT16_FTYPE_UINT16_INT)
> -BDESC (~OPTION_MASK_ISA_64BIT, CODE_FOR_rotrqi3, "__builtin_ia32_rorqi", 
> IX86_BUILTIN_RORQI, UNKNOWN, (int) UINT8_FTYPE_UINT8_INT)
> -BDESC (~OPTION_MASK_ISA_64BIT, CODE_FOR_rotrhi3, "__builtin_ia32_rorhi", 
> IX86_BUILTIN_RORHI, UNKNOWN, (int) UINT16_FTYPE_UINT16_INT)
> +BDESC (0, CODE_FOR_nothing, "__builtin_ia32_rdpmc", IX86_BUILTIN_RDPMC, 
> UNKNOWN, (int) UINT64_FTYPE_INT)
> +BDESC (0, CODE_FOR_rotlqi3, "__builtin_ia32_rolqi", IX86_BUILTIN_ROLQI, 
> UNKNOWN, (int) UINT8_FTYPE_UINT8_INT)
> +BDESC (0, CODE_FOR_rotlhi3, "__builtin_ia32_rolhi", IX86_BUILTIN_ROLHI, 
> UNKNOWN, (int) UINT16_FTYPE_UINT16_INT)
> +BDESC (0, CODE_FOR_rotrqi3, "__builtin_ia32_rorqi", IX86_BUILTIN_RORQI, 
> UNKNOWN, (int) UINT8_FTYPE_UINT8_INT)
> +BDESC (0, CODE_FOR_rotrhi3, "__builtin_ia32_rorhi", IX86_BUILTIN_RORHI, 
> UNKNOWN, (int) UINT16_FTYPE_UINT16_INT)
>
>  /* MMX */
>  BDESC (OPTION_MASK_ISA_MMX, CODE_FOR_mmx_addv8qi3, "__builtin_ia32_paddb", 
> IX86_BUILTIN_PADDB, UNKNOWN, (int) V8QI_FTYPE_V8QI_V8QI)
> --- gcc/testsuite/gcc.target/i386/pr79568-1.c.jj        2017-02-17 
> 13:15:54.801490187 +0100
> +++ gcc/testsuite/gcc.target/i386/pr79568-1.c   2017-02-17 13:12:05.000000000 
> +0100
> @@ -0,0 +1,18 @@
> +/* PR target/79568 */
> +/* { dg-do compile } */
> +/* { dg-options "-mno-avx512vl -mavx512bw -O2" } */
> +
> +#pragma GCC push_options
> +#pragma GCC target ("avx512vl,avx512bw")
> +void
> +foo (char *x, char __attribute__ ((__vector_size__(32))) *y, int z)
> +{
> +  __builtin_ia32_storedquqi256_mask (x, *y, z);
> +}
> +#pragma GCC pop_options
> +
> +void
> +bar (char *x, char __attribute__ ((__vector_size__(32))) *y, int z)
> +{
> +  __builtin_ia32_storedquqi256_mask (x, *y, z); /* { dg-error "needs isa 
> option" } */
> +}
> --- gcc/testsuite/gcc.target/i386/pr79568-2.c.jj        2017-02-17 
> 13:15:58.252443786 +0100
> +++ gcc/testsuite/gcc.target/i386/pr79568-2.c   2017-02-17 13:12:31.000000000 
> +0100
> @@ -0,0 +1,18 @@
> +/* PR target/79568 */
> +/* { dg-do compile { target lp64 } } */
> +/* { dg-options "-mno-lwp" } */
> +
> +#pragma GCC push_options
> +#pragma GCC target ("lwp")
> +void
> +foo (unsigned long x, unsigned int y)
> +{
> +  __builtin_ia32_lwpval64 (x, y, 1);
> +}
> +#pragma GCC pop_options
> +
> +void
> +bar (unsigned long x, unsigned int y)
> +{
> +  __builtin_ia32_lwpval64 (x, y, 1);    /* { dg-error "needs isa option" } */
> +}
> --- gcc/testsuite/gcc.target/i386/pr79568-3.c.jj        2017-02-17 
> 17:13:49.066265772 +0100
> +++ gcc/testsuite/gcc.target/i386/pr79568-3.c   2017-02-17 17:05:49.000000000 
> +0100
> @@ -0,0 +1,19 @@
> +/* PR target/79568 */
> +/* { dg-do compile } */
> +/* { dg-options "-mno-sahf -mno-mmx -mno-sse" } */
> +/* { dg-additional-options "-march=i386" { target ia32 } } */
> +
> +#pragma GCC push_options
> +#pragma GCC target ("sse")
> +void
> +foo (void)
> +{
> +  __builtin_ia32_pause ();
> +}
> +#pragma GCC pop_options
> +
> +void
> +bar (void)
> +{
> +  __builtin_ia32_pause ();
> +}
>
>         Jakub

Reply via email to