Fix __builtin_ia32_rdpmc (PR target/87550)

Message ID 20181010090907.GS11625@tucnak
State New
Headers show
Series
  • Fix __builtin_ia32_rdpmc (PR target/87550)
Related show

Commit Message

Jakub Jelinek Oct. 10, 2018, 9:09 a.m.
Hi!

The following testcase shows that we incorrectly handle __builtin_ia32_rdpmc
as a const function, so we e.g. CSE it.  The problem is that all bdesc_args
functions are registered using def_builtin_const.  The patch fixes this by
moving it to the bdesc_special_args category, which is registered with
def_builtin, similarly to e.g. rdtsc builtin.  The expansion is handled
specially before we decide whether to call args or special_args expansion,
and doesn't fall through, so from that POV it doesn't really matter which
category it is.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2018-10-10  Jakub Jelinek  <jakub@redhat.com>

	PR target/87550
	* config/i386/i386-builtin.def (IX86_BUILTIN_RDPMC): Move from args set
	to special_args set.

	* gcc.target/i386/pr87550.c: New test.


	Jakub

Comments

Uros Bizjak Oct. 10, 2018, 9:17 a.m. | #1
On Wed, Oct 10, 2018 at 11:09 AM Jakub Jelinek <jakub@redhat.com> wrote:
>
> Hi!
>
> The following testcase shows that we incorrectly handle __builtin_ia32_rdpmc
> as a const function, so we e.g. CSE it.  The problem is that all bdesc_args
> functions are registered using def_builtin_const.  The patch fixes this by
> moving it to the bdesc_special_args category, which is registered with
> def_builtin, similarly to e.g. rdtsc builtin.  The expansion is handled
> specially before we decide whether to call args or special_args expansion,
> and doesn't fall through, so from that POV it doesn't really matter which
> category it is.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>
> 2018-10-10  Jakub Jelinek  <jakub@redhat.com>
>
>         PR target/87550
>         * config/i386/i386-builtin.def (IX86_BUILTIN_RDPMC): Move from args set
>         to special_args set.
>
>         * gcc.target/i386/pr87550.c: New test.

OK.

Thanks,
Uros.

> --- gcc/config/i386/i386-builtin.def.jj 2018-06-13 10:05:54.816128362 +0200
> +++ gcc/config/i386/i386-builtin.def    2018-10-09 09:28:10.199072944 +0200
> @@ -90,6 +90,7 @@ BDESC_END (PCMPISTR, SPECIAL_ARGS)
>  BDESC_FIRST (special_args, SPECIAL_ARGS,
>         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_nothing, "__builtin_ia32_rdpmc", IX86_BUILTIN_RDPMC, UNKNOWN, (int) UINT64_FTYPE_INT)
>  BDESC (0, CODE_FOR_pause, "__builtin_ia32_pause", IX86_BUILTIN_PAUSE, UNKNOWN, (int) VOID_FTYPE_VOID)
>
>  /* 80387 (for use internally for atomic compound assignment).  */
> @@ -427,7 +428,6 @@ BDESC_END (SPECIAL_ARGS, ARGS)
>  BDESC_FIRST (args, ARGS,
>         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 (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)
> --- gcc/testsuite/gcc.target/i386/pr87550.c.jj  2018-10-09 09:36:33.470600220 +0200
> +++ gcc/testsuite/gcc.target/i386/pr87550.c     2018-10-09 09:37:30.384642051 +0200
> @@ -0,0 +1,21 @@
> +/* PR target/87550 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2" } */
> +
> +#include <x86intrin.h>
> +
> +int
> +foo (int x)
> +{
> +  return __rdtsc () + __rdtsc ();
> +}
> +
> +/* { dg-final { scan-assembler-times "\trdtsc\[\n\r]" 2 } } */
> +
> +int
> +bar (int x)
> +{
> +  return __rdpmc (0) + __rdpmc (0);
> +}
> +
> +/* { dg-final { scan-assembler-times "\trdpmc\[\n\r]" 2 } } */
>
>         Jakub

Patch

--- gcc/config/i386/i386-builtin.def.jj	2018-06-13 10:05:54.816128362 +0200
+++ gcc/config/i386/i386-builtin.def	2018-10-09 09:28:10.199072944 +0200
@@ -90,6 +90,7 @@  BDESC_END (PCMPISTR, SPECIAL_ARGS)
 BDESC_FIRST (special_args, SPECIAL_ARGS,
        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_nothing, "__builtin_ia32_rdpmc", IX86_BUILTIN_RDPMC, UNKNOWN, (int) UINT64_FTYPE_INT)
 BDESC (0, CODE_FOR_pause, "__builtin_ia32_pause", IX86_BUILTIN_PAUSE, UNKNOWN, (int) VOID_FTYPE_VOID)
 
 /* 80387 (for use internally for atomic compound assignment).  */
@@ -427,7 +428,6 @@  BDESC_END (SPECIAL_ARGS, ARGS)
 BDESC_FIRST (args, ARGS,
        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 (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)
--- gcc/testsuite/gcc.target/i386/pr87550.c.jj	2018-10-09 09:36:33.470600220 +0200
+++ gcc/testsuite/gcc.target/i386/pr87550.c	2018-10-09 09:37:30.384642051 +0200
@@ -0,0 +1,21 @@ 
+/* PR target/87550 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+#include <x86intrin.h>
+
+int
+foo (int x)
+{
+  return __rdtsc () + __rdtsc ();
+}
+
+/* { dg-final { scan-assembler-times "\trdtsc\[\n\r]" 2 } } */
+
+int
+bar (int x)
+{
+  return __rdpmc (0) + __rdpmc (0);
+}
+
+/* { dg-final { scan-assembler-times "\trdpmc\[\n\r]" 2 } } */