public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Uros Bizjak <ubizjak@gmail.com>
To: "H.J. Lu" <hjl.tools@gmail.com>
Cc: "gcc-patches@gcc.gnu.org" <gcc-patches@gcc.gnu.org>,
	Jakub Jelinek <jakub@redhat.com>,
	 Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>,
	Martin Sebor <msebor@gmail.com>,
	 Richard Biener <richard.guenther@gmail.com>
Subject: Re: [PATCH v4 2/2] x86: Add general_regs_only function attribute
Date: Wed, 21 Apr 2021 09:30:38 +0200	[thread overview]
Message-ID: <CAFULd4ZpMs+5PoWFku2LiM-RWkcACnqBwrUmRJzpLg0vUAffYg@mail.gmail.com> (raw)
In-Reply-To: <20210414223918.230495-3-hjl.tools@gmail.com>

On Thu, Apr 15, 2021 at 12:39 AM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> commit 87c753ac241f25d222d46ba1ac66ceba89d6a200
> Author: H.J. Lu <hjl.tools@gmail.com>
> Date:   Fri Aug 21 09:42:49 2020 -0700
>
>     x86: Add target("general-regs-only") function attribute
>
> is incomplete since it is impossible to call integer intrinsics from
> a function with general-regs-only target attribute.
>
> 1. Add general_regs_only function attribute to inform the compiler that
> functions use only general purpose registers.  When making inlining
> decisions on such functions, non-GPR compiler options are excluded.
> 2. Add general_regs_only attribute to x86 intrinsics which use only
> general purpose registers.

I'd like to ask Richard and Jakub if they agree with the approach.

On a related note, can we declare default attributes like clang does, e.g.:

/* Define the default attributes for the functions.  */
#define __DEFAULT_FN_ATTRS __attribute__((__gnu_inline__,
__always_inline__, __artificial__))
#define __DEFAULT_FN_ATTRS_GRO __attribute__((__gnu_inline__,
__always_inline__, __general_regs_only, __artificial__))

and use these defines throughout header files?

Uros.

>
> gcc/
>
>         PR target/99744
>         * config/i386/i386-options.c (ix86_attribute_table): Add
>         general_regs_only.
>         * config/i386/i386.c (ix86_can_inline_p): Exclude non-integer
>         target options if callee has general_regs_only attribute.
>         * config/i386/adxintrin.h: Add general_regs_only attribute to
>         intrinsics which use only general purpose registers.
>         * config/i386/bmiintrin.h: Likewise.
>         * config/i386/bmi2intrin.h: Likewise.
>         * config/i386/cetintrin.h: Likewise.
>         * config/i386/cldemoteintrin.h: Likewise.
>         * config/i386/clflushoptintrin.h: Likewise.
>         * config/i386/clwbintrin.h: Likewise.
>         * config/i386/clzerointrin.h: Likewise.
>         * config/i386/enqcmdintrin.h: Likewise.
>         * config/i386/fxsrintrin.h: Likewise.
>         * config/i386/hresetintrin.h: Likewise.
>         * config/i386/ia32intrin.h: Likewise.
>         * config/i386/lwpintrin.h: Likewise.
>         * config/i386/lzcntintrin.h: Likewise.
>         * config/i386/movdirintrin.h: Likewise.
>         * config/i386/mwaitxintrin.h: Likewise.
>         * config/i386/pconfigintrin.h: Likewise.
>         * config/i386/pkuintrin.h: Likewise.
>         * config/i386/popcntintrin.h: Likewise.
>         * config/i386/rdseedintrin.h: Likewise.
>         * config/i386/rtmintrin.h: Likewise.
>         * config/i386/serializeintrin.h: Likewise.
>         * config/i386/sgxintrin.h: Likewise.
>         * config/i386/tbmintrin.h: Likewise.
>         * config/i386/tsxldtrkintrin.h: Likewise.
>         * config/i386/uintrintrin.h: Likewise.
>         * config/i386/waitpkgintrin.h: Likewise.
>         * config/i386/wbnoinvdintrin.h: Likewise.
>         * config/i386/x86gprintrin.h: Likewise.
>         * config/i386/xsavecintrin.h: Likewise.
>         * config/i386/xsaveintrin.h: Likewise.
>         * config/i386/xsaveoptintrin.h: Likewise.
>         * config/i386/xsavesintrin.h: Likewise.
>         * config/i386/xtestintrin.h: Likewise.
>         * doc/extend.texi: Document general_regs_only function attribute.
>
> gcc/testsuite/
>
>         PR target/99744
>         * gcc.target/i386/pr99744-3.c: New test.
>         * gcc.target/i386/pr99744-4.c: Likewise.
> ---
>  gcc/config/i386/adxintrin.h               |  18 +-
>  gcc/config/i386/bmi2intrin.h              |  24 +-
>  gcc/config/i386/bmiintrin.h               |  92 ++++--
>  gcc/config/i386/cetintrin.h               |  33 +-
>  gcc/config/i386/cldemoteintrin.h          |   3 +-
>  gcc/config/i386/clflushoptintrin.h        |   3 +-
>  gcc/config/i386/clwbintrin.h              |   3 +-
>  gcc/config/i386/clzerointrin.h            |   4 +-
>  gcc/config/i386/enqcmdintrin.h            |   6 +-
>  gcc/config/i386/fxsrintrin.h              |  12 +-
>  gcc/config/i386/hresetintrin.h            |   3 +-
>  gcc/config/i386/i386-options.c            |   2 +
>  gcc/config/i386/i386.c                    |  29 +-
>  gcc/config/i386/ia32intrin.h              |  82 +++--
>  gcc/config/i386/lwpintrin.h               |  24 +-
>  gcc/config/i386/lzcntintrin.h             |  20 +-
>  gcc/config/i386/movdirintrin.h            |   9 +-
>  gcc/config/i386/mwaitxintrin.h            |   8 +-
>  gcc/config/i386/pconfigintrin.h           |   3 +-
>  gcc/config/i386/pkuintrin.h               |   6 +-
>  gcc/config/i386/popcntintrin.h            |   8 +-
>  gcc/config/i386/rdseedintrin.h            |   9 +-
>  gcc/config/i386/rtmintrin.h               |   9 +-
>  gcc/config/i386/serializeintrin.h         |   8 +-
>  gcc/config/i386/sgxintrin.h               |   9 +-
>  gcc/config/i386/tbmintrin.h               |  80 +++--
>  gcc/config/i386/tsxldtrkintrin.h          |   6 +-
>  gcc/config/i386/uintrintrin.h             |  12 +-
>  gcc/config/i386/waitpkgintrin.h           |   9 +-
>  gcc/config/i386/wbnoinvdintrin.h          |   3 +-
>  gcc/config/i386/x86gprintrin.h            |  45 ++-
>  gcc/config/i386/xsavecintrin.h            |   6 +-
>  gcc/config/i386/xsaveintrin.h             |  18 +-
>  gcc/config/i386/xsaveoptintrin.h          |   6 +-
>  gcc/config/i386/xsavesintrin.h            |  12 +-
>  gcc/config/i386/xtestintrin.h             |   3 +-
>  gcc/doc/extend.texi                       |   5 +
>  gcc/testsuite/gcc.target/i386/pr99744-3.c |  13 +
>  gcc/testsuite/gcc.target/i386/pr99744-4.c | 352 ++++++++++++++++++++++
>  39 files changed, 818 insertions(+), 179 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr99744-3.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr99744-4.c
>
> diff --git a/gcc/config/i386/adxintrin.h b/gcc/config/i386/adxintrin.h
> index e514e741f02..74e3df18dce 100644
> --- a/gcc/config/i386/adxintrin.h
> +++ b/gcc/config/i386/adxintrin.h
> @@ -29,7 +29,8 @@
>  #define _ADXINTRIN_H_INCLUDED
>
>  extern __inline unsigned char
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _subborrow_u32 (unsigned char __CF, unsigned int __X,
>                 unsigned int __Y, unsigned int *__P)
>  {
> @@ -37,7 +38,8 @@ _subborrow_u32 (unsigned char __CF, unsigned int __X,
>  }
>
>  extern __inline unsigned char
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _addcarry_u32 (unsigned char __CF, unsigned int __X,
>                unsigned int __Y, unsigned int *__P)
>  {
> @@ -45,7 +47,8 @@ _addcarry_u32 (unsigned char __CF, unsigned int __X,
>  }
>
>  extern __inline unsigned char
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _addcarryx_u32 (unsigned char __CF, unsigned int __X,
>                 unsigned int __Y, unsigned int *__P)
>  {
> @@ -54,7 +57,8 @@ _addcarryx_u32 (unsigned char __CF, unsigned int __X,
>
>  #ifdef __x86_64__
>  extern __inline unsigned char
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _subborrow_u64 (unsigned char __CF, unsigned long long __X,
>                 unsigned long long __Y, unsigned long long *__P)
>  {
> @@ -62,7 +66,8 @@ _subborrow_u64 (unsigned char __CF, unsigned long long __X,
>  }
>
>  extern __inline unsigned char
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _addcarry_u64 (unsigned char __CF, unsigned long long __X,
>                unsigned long long __Y, unsigned long long *__P)
>  {
> @@ -70,7 +75,8 @@ _addcarry_u64 (unsigned char __CF, unsigned long long __X,
>  }
>
>  extern __inline unsigned char
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _addcarryx_u64 (unsigned char __CF, unsigned long long __X,
>                 unsigned long long __Y, unsigned long long *__P)
>  {
> diff --git a/gcc/config/i386/bmi2intrin.h b/gcc/config/i386/bmi2intrin.h
> index 6b23e4e98a1..7f64e5a8ff1 100644
> --- a/gcc/config/i386/bmi2intrin.h
> +++ b/gcc/config/i386/bmi2intrin.h
> @@ -35,21 +35,24 @@
>  #endif /* __BMI2__ */
>
>  extern __inline unsigned int
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _bzhi_u32 (unsigned int __X, unsigned int __Y)
>  {
>    return __builtin_ia32_bzhi_si (__X, __Y);
>  }
>
>  extern __inline unsigned int
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _pdep_u32 (unsigned int __X, unsigned int __Y)
>  {
>    return __builtin_ia32_pdep_si (__X, __Y);
>  }
>
>  extern __inline unsigned int
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _pext_u32 (unsigned int __X, unsigned int __Y)
>  {
>    return __builtin_ia32_pext_si (__X, __Y);
> @@ -58,28 +61,32 @@ _pext_u32 (unsigned int __X, unsigned int __Y)
>  #ifdef  __x86_64__
>
>  extern __inline unsigned long long
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _bzhi_u64 (unsigned long long __X, unsigned long long __Y)
>  {
>    return __builtin_ia32_bzhi_di (__X, __Y);
>  }
>
>  extern __inline unsigned long long
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _pdep_u64 (unsigned long long __X, unsigned long long __Y)
>  {
>    return __builtin_ia32_pdep_di (__X, __Y);
>  }
>
>  extern __inline unsigned long long
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _pext_u64 (unsigned long long __X, unsigned long long __Y)
>  {
>    return __builtin_ia32_pext_di (__X, __Y);
>  }
>
>  extern __inline unsigned long long
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _mulx_u64 (unsigned long long __X, unsigned long long __Y,
>            unsigned long long *__P)
>  {
> @@ -91,7 +98,8 @@ _mulx_u64 (unsigned long long __X, unsigned long long __Y,
>  #else /* !__x86_64__ */
>
>  extern __inline unsigned int
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _mulx_u32 (unsigned int __X, unsigned int __Y, unsigned int *__P)
>  {
>    unsigned long long __res = (unsigned long long) __X * __Y;
> diff --git a/gcc/config/i386/bmiintrin.h b/gcc/config/i386/bmiintrin.h
> index 439d81cba11..18b5d7b0734 100644
> --- a/gcc/config/i386/bmiintrin.h
> +++ b/gcc/config/i386/bmiintrin.h
> @@ -34,73 +34,97 @@
>  #define __DISABLE_BMI__
>  #endif /* __BMI__ */
>
> -extern __inline unsigned short __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned short
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __tzcnt_u16 (unsigned short __X)
>  {
>    return __builtin_ia32_tzcnt_u16 (__X);
>  }
>
> -extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned int
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __andn_u32 (unsigned int __X, unsigned int __Y)
>  {
>    return ~__X & __Y;
>  }
>
> -extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned int
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __bextr_u32 (unsigned int __X, unsigned int __Y)
>  {
>    return __builtin_ia32_bextr_u32 (__X, __Y);
>  }
>
> -extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned int
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _bextr_u32 (unsigned int __X, unsigned int __Y, unsigned __Z)
>  {
>    return __builtin_ia32_bextr_u32 (__X, ((__Y & 0xff) | ((__Z & 0xff) << 8)));
>  }
>
> -extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned int
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __blsi_u32 (unsigned int __X)
>  {
>    return __X & -__X;
>  }
>
> -extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned int
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _blsi_u32 (unsigned int __X)
>  {
>    return __blsi_u32 (__X);
>  }
>
> -extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned int
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __blsmsk_u32 (unsigned int __X)
>  {
>    return __X ^ (__X - 1);
>  }
>
> -extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned int
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _blsmsk_u32 (unsigned int __X)
>  {
>    return __blsmsk_u32 (__X);
>  }
>
> -extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned int
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __blsr_u32 (unsigned int __X)
>  {
>    return __X & (__X - 1);
>  }
>
> -extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned int
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _blsr_u32 (unsigned int __X)
>  {
>    return __blsr_u32 (__X);
>  }
>
> -extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned int
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __tzcnt_u32 (unsigned int __X)
>  {
>    return __builtin_ia32_tzcnt_u32 (__X);
>  }
>
> -extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned int
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _tzcnt_u32 (unsigned int __X)
>  {
>    return __builtin_ia32_tzcnt_u32 (__X);
> @@ -108,67 +132,89 @@ _tzcnt_u32 (unsigned int __X)
>
>
>  #ifdef  __x86_64__
> -extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned long long
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __andn_u64 (unsigned long long __X, unsigned long long __Y)
>  {
>    return ~__X & __Y;
>  }
>
> -extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned long long
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __bextr_u64 (unsigned long long __X, unsigned long long __Y)
>  {
>    return __builtin_ia32_bextr_u64 (__X, __Y);
>  }
>
> -extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned long long
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _bextr_u64 (unsigned long long __X, unsigned int __Y, unsigned int __Z)
>  {
>    return __builtin_ia32_bextr_u64 (__X, ((__Y & 0xff) | ((__Z & 0xff) << 8)));
>  }
>
> -extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned long long
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __blsi_u64 (unsigned long long __X)
>  {
>    return __X & -__X;
>  }
>
> -extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned long long
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _blsi_u64 (unsigned long long __X)
>  {
>    return __blsi_u64 (__X);
>  }
>
> -extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned long long
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __blsmsk_u64 (unsigned long long __X)
>  {
>    return __X ^ (__X - 1);
>  }
>
> -extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned long long
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _blsmsk_u64 (unsigned long long __X)
>  {
>    return __blsmsk_u64 (__X);
>  }
>
> -extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned long long
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __blsr_u64 (unsigned long long __X)
>  {
>    return __X & (__X - 1);
>  }
>
> -extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned long long
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _blsr_u64 (unsigned long long __X)
>  {
>    return __blsr_u64 (__X);
>  }
>
> -extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned long long
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __tzcnt_u64 (unsigned long long __X)
>  {
>    return __builtin_ia32_tzcnt_u64 (__X);
>  }
>
> -extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned long long
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _tzcnt_u64 (unsigned long long __X)
>  {
>    return __builtin_ia32_tzcnt_u64 (__X);
> diff --git a/gcc/config/i386/cetintrin.h b/gcc/config/i386/cetintrin.h
> index 803c6283bec..145bd3ce7d2 100644
> --- a/gcc/config/i386/cetintrin.h
> +++ b/gcc/config/i386/cetintrin.h
> @@ -36,14 +36,16 @@
>
>  #ifdef __x86_64__
>  extern __inline unsigned long long
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _get_ssp (void)
>  {
>    return __builtin_ia32_rdsspq ();
>  }
>  #else
>  extern __inline unsigned int
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _get_ssp (void)
>  {
>    return __builtin_ia32_rdsspd ();
> @@ -51,7 +53,8 @@ _get_ssp (void)
>  #endif
>
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _inc_ssp (unsigned int __B)
>  {
>  #ifdef __x86_64__
> @@ -62,21 +65,24 @@ _inc_ssp (unsigned int __B)
>  }
>
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _saveprevssp (void)
>  {
>    __builtin_ia32_saveprevssp ();
>  }
>
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _rstorssp (void *__B)
>  {
>    __builtin_ia32_rstorssp (__B);
>  }
>
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _wrssd (unsigned int __B, void *__C)
>  {
>    __builtin_ia32_wrssd (__B, __C);
> @@ -84,7 +90,8 @@ _wrssd (unsigned int __B, void *__C)
>
>  #ifdef __x86_64__
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _wrssq (unsigned long long __B, void *__C)
>  {
>    __builtin_ia32_wrssq (__B, __C);
> @@ -92,7 +99,8 @@ _wrssq (unsigned long long __B, void *__C)
>  #endif
>
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _wrussd (unsigned int __B, void *__C)
>  {
>    __builtin_ia32_wrussd (__B, __C);
> @@ -100,7 +108,8 @@ _wrussd (unsigned int __B, void *__C)
>
>  #ifdef __x86_64__
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _wrussq (unsigned long long __B, void *__C)
>  {
>    __builtin_ia32_wrussq (__B, __C);
> @@ -108,14 +117,16 @@ _wrussq (unsigned long long __B, void *__C)
>  #endif
>
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _setssbsy (void)
>  {
>    __builtin_ia32_setssbsy ();
>  }
>
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _clrssbsy (void *__B)
>  {
>    __builtin_ia32_clrssbsy (__B);
> diff --git a/gcc/config/i386/cldemoteintrin.h b/gcc/config/i386/cldemoteintrin.h
> index 67dddaf2b89..897a2db9e41 100644
> --- a/gcc/config/i386/cldemoteintrin.h
> +++ b/gcc/config/i386/cldemoteintrin.h
> @@ -34,7 +34,8 @@
>  #define __DISABLE_CLDEMOTE__
>  #endif /* __CLDEMOTE__ */
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _cldemote (void *__A)
>  {
>    __builtin_ia32_cldemote (__A);
> diff --git a/gcc/config/i386/clflushoptintrin.h b/gcc/config/i386/clflushoptintrin.h
> index d8b55762158..3bd91d00681 100644
> --- a/gcc/config/i386/clflushoptintrin.h
> +++ b/gcc/config/i386/clflushoptintrin.h
> @@ -35,7 +35,8 @@
>  #endif /* __CLFLUSHOPT__ */
>
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _mm_clflushopt (void *__A)
>  {
>    __builtin_ia32_clflushopt (__A);
> diff --git a/gcc/config/i386/clwbintrin.h b/gcc/config/i386/clwbintrin.h
> index 21134429a40..2ff40066ef9 100644
> --- a/gcc/config/i386/clwbintrin.h
> +++ b/gcc/config/i386/clwbintrin.h
> @@ -35,7 +35,8 @@
>  #endif /* __CLWB__ */
>
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _mm_clwb (void *__A)
>  {
>    __builtin_ia32_clwb (__A);
> diff --git a/gcc/config/i386/clzerointrin.h b/gcc/config/i386/clzerointrin.h
> index f9095160409..12930e387c3 100644
> --- a/gcc/config/i386/clzerointrin.h
> +++ b/gcc/config/i386/clzerointrin.h
> @@ -30,7 +30,9 @@
>  #define __DISABLE_CLZERO__
>  #endif /* __CLZERO__ */
>
> -extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline void
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _mm_clzero (void * __I)
>  {
>    __builtin_ia32_clzero (__I);
> diff --git a/gcc/config/i386/enqcmdintrin.h b/gcc/config/i386/enqcmdintrin.h
> index 2518df18db1..7f3d769c23f 100644
> --- a/gcc/config/i386/enqcmdintrin.h
> +++ b/gcc/config/i386/enqcmdintrin.h
> @@ -35,14 +35,16 @@
>  #endif /* __ENQCMD__ */
>
>  extern __inline int
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _enqcmd (void * __P, const void * __Q)
>  {
>    return __builtin_ia32_enqcmd (__P, __Q);
>  }
>
>  extern __inline int
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _enqcmds (void * __P, const void * __Q)
>  {
>    return __builtin_ia32_enqcmds (__P, __Q);
> diff --git a/gcc/config/i386/fxsrintrin.h b/gcc/config/i386/fxsrintrin.h
> index fd2e538eb9c..a80654968eb 100644
> --- a/gcc/config/i386/fxsrintrin.h
> +++ b/gcc/config/i386/fxsrintrin.h
> @@ -35,14 +35,16 @@
>  #endif /* __FXSR__ */
>
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _fxsave (void *__P)
>  {
>    __builtin_ia32_fxsave (__P);
>  }
>
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _fxrstor (void *__P)
>  {
>    __builtin_ia32_fxrstor (__P);
> @@ -50,14 +52,16 @@ _fxrstor (void *__P)
>
>  #ifdef __x86_64__
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _fxsave64 (void *__P)
>  {
>    __builtin_ia32_fxsave64 (__P);
>  }
>
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _fxrstor64 (void *__P)
>  {
>    __builtin_ia32_fxrstor64 (__P);
> diff --git a/gcc/config/i386/hresetintrin.h b/gcc/config/i386/hresetintrin.h
> index 500618825c9..eba09a9010f 100644
> --- a/gcc/config/i386/hresetintrin.h
> +++ b/gcc/config/i386/hresetintrin.h
> @@ -35,7 +35,8 @@
>  #endif /* __HRESET__ */
>
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _hreset (unsigned int __EAX)
>  {
>    __builtin_ia32_hreset (__EAX);
> diff --git a/gcc/config/i386/i386-options.c b/gcc/config/i386/i386-options.c
> index 91da2849c49..559f9357811 100644
> --- a/gcc/config/i386/i386-options.c
> +++ b/gcc/config/i386/i386-options.c
> @@ -3961,6 +3961,8 @@ const struct attribute_spec ix86_attribute_table[] =
>      ix86_handle_fentry_name, NULL },
>    { "cf_check", 0, 0, true, false, false, false,
>      ix86_handle_fndecl_attribute, NULL },
> +  { "general_regs_only", 0, 0, true, false, false, false,
> +    ix86_handle_fndecl_attribute, NULL },
>
>    /* End element.  */
>    { NULL, 0, 0, false, false, false, false, NULL, NULL }
> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
> index 7c41302c75b..201a001e95a 100644
> --- a/gcc/config/i386/i386.c
> +++ b/gcc/config/i386/i386.c
> @@ -553,7 +553,7 @@ ix86_can_inline_p (tree caller, tree callee)
>
>    /* Changes of those flags can be tolerated for always inlines. Lets hope
>       user knows what he is doing.  */
> -  const unsigned HOST_WIDE_INT always_inline_safe_mask
> +  unsigned HOST_WIDE_INT always_inline_safe_mask
>          = (MASK_USE_8BIT_IDIV | MASK_ACCUMULATE_OUTGOING_ARGS
>             | MASK_NO_ALIGN_STRINGOPS | MASK_AVX256_SPLIT_UNALIGNED_LOAD
>             | MASK_AVX256_SPLIT_UNALIGNED_STORE | MASK_CLD
> @@ -579,13 +579,32 @@ ix86_can_inline_p (tree caller, tree callee)
>                             DECL_ATTRIBUTES (callee)));
>
>    cgraph_node *callee_node = cgraph_node::get (callee);
> +
> +  HOST_WIDE_INT callee_integer_isa_flags
> +    = callee_opts->x_ix86_isa_flags;
> +  HOST_WIDE_INT callee_integer_isa_flags2
> +    = callee_opts->x_ix86_isa_flags2;
> +
> +  if (lookup_attribute ("general_regs_only",
> +                       DECL_ATTRIBUTES (callee)))
> +    {
> +      /* For general purpose register only function, callee's
> +        integer ISA options should be a subset of the caller's
> +        integer ISA options.  */
> +      always_inline_safe_mask |= MASK_80387;
> +      callee_integer_isa_flags
> +       &= ~OPTION_MASK_ISA_GENERAL_REGS_ONLY_UNSET;
> +      callee_integer_isa_flags2
> +       &= ~OPTION_MASK_ISA2_GENERAL_REGS_ONLY_UNSET;
> +    }
> +
>    /* Callee's isa options should be a subset of the caller's, i.e. a SSE4
>       function can inline a SSE2 function but a SSE2 function can't inline
>       a SSE4 function.  */
> -  if (((caller_opts->x_ix86_isa_flags & callee_opts->x_ix86_isa_flags)
> -       != callee_opts->x_ix86_isa_flags)
> -      || ((caller_opts->x_ix86_isa_flags2 & callee_opts->x_ix86_isa_flags2)
> -         != callee_opts->x_ix86_isa_flags2))
> +  if (((caller_opts->x_ix86_isa_flags & callee_integer_isa_flags)
> +       != callee_integer_isa_flags)
> +      || ((caller_opts->x_ix86_isa_flags2 & callee_integer_isa_flags2)
> +         != callee_integer_isa_flags2))
>      ret = false;
>
>    /* See if we have the same non-isa options.  */
> diff --git a/gcc/config/i386/ia32intrin.h b/gcc/config/i386/ia32intrin.h
> index 591394076cc..908eb44b0d7 100644
> --- a/gcc/config/i386/ia32intrin.h
> +++ b/gcc/config/i386/ia32intrin.h
> @@ -27,7 +27,8 @@
>
>  /* 32bit bsf */
>  extern __inline int
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __bsfd (int __X)
>  {
>    return __builtin_ctz (__X);
> @@ -35,7 +36,8 @@ __bsfd (int __X)
>
>  /* 32bit bsr */
>  extern __inline int
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __bsrd (int __X)
>  {
>    return __builtin_ia32_bsrsi (__X);
> @@ -43,7 +45,8 @@ __bsrd (int __X)
>
>  /* 32bit bswap */
>  extern __inline int
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __bswapd (int __X)
>  {
>    return __builtin_bswap32 (__X);
> @@ -88,7 +91,8 @@ __crc32d (unsigned int __C, unsigned int __V)
>
>  /* 32bit popcnt */
>  extern __inline int
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __popcntd (unsigned int __X)
>  {
>    return __builtin_popcount (__X);
> @@ -98,7 +102,8 @@ __popcntd (unsigned int __X)
>
>  /* rdpmc */
>  extern __inline unsigned long long
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __rdpmc (int __S)
>  {
>    return __builtin_ia32_rdpmc (__S);
> @@ -107,18 +112,31 @@ __rdpmc (int __S)
>  #endif /* __iamcu__ */
>
>  /* rdtsc */
> -#define __rdtsc()              __builtin_ia32_rdtsc ()
> +extern __inline unsigned long long
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
> +__rdtsc (void)
> +{
> +  return __builtin_ia32_rdtsc ();
> +}
>
>  #ifndef __iamcu__
>
>  /* rdtscp */
> -#define __rdtscp(a)            __builtin_ia32_rdtscp (a)
> +extern __inline unsigned long long
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
> +__rdtscp (unsigned int *__A)
> +{
> +  return __builtin_ia32_rdtscp (__A);
> +}
>
>  #endif /* __iamcu__ */
>
>  /* 8bit rol */
>  extern __inline unsigned char
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __rolb (unsigned char __X, int __C)
>  {
>    return __builtin_ia32_rolqi (__X, __C);
> @@ -126,7 +144,8 @@ __rolb (unsigned char __X, int __C)
>
>  /* 16bit rol */
>  extern __inline unsigned short
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __rolw (unsigned short __X, int __C)
>  {
>    return __builtin_ia32_rolhi (__X, __C);
> @@ -134,7 +153,8 @@ __rolw (unsigned short __X, int __C)
>
>  /* 32bit rol */
>  extern __inline unsigned int
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __rold (unsigned int __X, int __C)
>  {
>    __C &= 31;
> @@ -143,7 +163,8 @@ __rold (unsigned int __X, int __C)
>
>  /* 8bit ror */
>  extern __inline unsigned char
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __rorb (unsigned char __X, int __C)
>  {
>    return __builtin_ia32_rorqi (__X, __C);
> @@ -151,7 +172,8 @@ __rorb (unsigned char __X, int __C)
>
>  /* 16bit ror */
>  extern __inline unsigned short
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __rorw (unsigned short __X, int __C)
>  {
>    return __builtin_ia32_rorhi (__X, __C);
> @@ -159,7 +181,8 @@ __rorw (unsigned short __X, int __C)
>
>  /* 32bit ror */
>  extern __inline unsigned int
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __rord (unsigned int __X, int __C)
>  {
>    __C &= 31;
> @@ -168,7 +191,8 @@ __rord (unsigned int __X, int __C)
>
>  /* Pause */
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __pause (void)
>  {
>    __builtin_ia32_pause ();
> @@ -177,7 +201,8 @@ __pause (void)
>  #ifdef __x86_64__
>  /* 64bit bsf */
>  extern __inline int
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __bsfq (long long __X)
>  {
>    return __builtin_ctzll (__X);
> @@ -185,7 +210,8 @@ __bsfq (long long __X)
>
>  /* 64bit bsr */
>  extern __inline int
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __bsrq (long long __X)
>  {
>    return __builtin_ia32_bsrdi (__X);
> @@ -193,7 +219,8 @@ __bsrq (long long __X)
>
>  /* 64bit bswap */
>  extern __inline long long
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __bswapq (long long __X)
>  {
>    return __builtin_bswap64 (__X);
> @@ -220,7 +247,8 @@ __crc32q (unsigned long long __C, unsigned long long __V)
>
>  /* 64bit popcnt */
>  extern __inline long long
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __popcntq (unsigned long long __X)
>  {
>    return __builtin_popcountll (__X);
> @@ -228,7 +256,8 @@ __popcntq (unsigned long long __X)
>
>  /* 64bit rol */
>  extern __inline unsigned long long
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __rolq (unsigned long long __X, int __C)
>  {
>    __C &= 63;
> @@ -237,7 +266,8 @@ __rolq (unsigned long long __X, int __C)
>
>  /* 64bit ror */
>  extern __inline unsigned long long
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __rorq (unsigned long long __X, int __C)
>  {
>    __C &= 63;
> @@ -246,7 +276,8 @@ __rorq (unsigned long long __X, int __C)
>
>  /* Read flags register */
>  extern __inline unsigned long long
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __readeflags (void)
>  {
>    return __builtin_ia32_readeflags_u64 ();
> @@ -254,7 +285,8 @@ __readeflags (void)
>
>  /* Write flags register */
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __writeeflags (unsigned long long __X)
>  {
>    __builtin_ia32_writeeflags_u64 (__X);
> @@ -266,7 +298,8 @@ __writeeflags (unsigned long long __X)
>
>  /* Read flags register */
>  extern __inline unsigned int
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __readeflags (void)
>  {
>    return __builtin_ia32_readeflags_u32 ();
> @@ -274,7 +307,8 @@ __readeflags (void)
>
>  /* Write flags register */
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __writeeflags (unsigned int __X)
>  {
>    __builtin_ia32_writeeflags_u32 (__X);
> diff --git a/gcc/config/i386/lwpintrin.h b/gcc/config/i386/lwpintrin.h
> index 1a7465b2f22..893a4313a68 100644
> --- a/gcc/config/i386/lwpintrin.h
> +++ b/gcc/config/i386/lwpintrin.h
> @@ -34,27 +34,35 @@
>  #define __DISABLE_LWP__
>  #endif /* __LWP__ */
>
> -extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline void
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __llwpcb (void *__pcbAddress)
>  {
>    __builtin_ia32_llwpcb (__pcbAddress);
>  }
>
> -extern __inline void * __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline void *
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __slwpcb (void)
>  {
>    return __builtin_ia32_slwpcb ();
>  }
>
>  #ifdef __OPTIMIZE__
> -extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline void
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __lwpval32 (unsigned int __data2, unsigned int __data1, unsigned int __flags)
>  {
>    __builtin_ia32_lwpval32 (__data2, __data1, __flags);
>  }
>
>  #ifdef __x86_64__
> -extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline void
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __lwpval64 (unsigned long long __data2, unsigned int __data1,
>             unsigned int __flags)
>  {
> @@ -74,14 +82,18 @@ __lwpval64 (unsigned long long __data2, unsigned int __data1,
>
>
>  #ifdef __OPTIMIZE__
> -extern __inline unsigned char __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned char
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __lwpins32 (unsigned int __data2, unsigned int __data1, unsigned int __flags)
>  {
>    return __builtin_ia32_lwpins32 (__data2, __data1, __flags);
>  }
>
>  #ifdef __x86_64__
> -extern __inline unsigned char __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned char
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __lwpins64 (unsigned long long __data2, unsigned int __data1,
>             unsigned int __flags)
>  {
> diff --git a/gcc/config/i386/lzcntintrin.h b/gcc/config/i386/lzcntintrin.h
> index cfa2719c044..864bdf67698 100644
> --- a/gcc/config/i386/lzcntintrin.h
> +++ b/gcc/config/i386/lzcntintrin.h
> @@ -35,32 +35,42 @@
>  #define __DISABLE_LZCNT__
>  #endif /* __LZCNT__ */
>
> -extern __inline unsigned short __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned short
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __lzcnt16 (unsigned short __X)
>  {
>    return __builtin_ia32_lzcnt_u16 (__X);
>  }
>
> -extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned int
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __lzcnt32 (unsigned int __X)
>  {
>    return __builtin_ia32_lzcnt_u32 (__X);
>  }
>
> -extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned int
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _lzcnt_u32 (unsigned int __X)
>  {
>    return __builtin_ia32_lzcnt_u32 (__X);
>  }
>
>  #ifdef __x86_64__
> -extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned long long
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __lzcnt64 (unsigned long long __X)
>  {
>    return __builtin_ia32_lzcnt_u64 (__X);
>  }
>
> -extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned long long
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _lzcnt_u64 (unsigned long long __X)
>  {
>    return __builtin_ia32_lzcnt_u64 (__X);
> diff --git a/gcc/config/i386/movdirintrin.h b/gcc/config/i386/movdirintrin.h
> index c50fe40b937..e6ba84f39c8 100644
> --- a/gcc/config/i386/movdirintrin.h
> +++ b/gcc/config/i386/movdirintrin.h
> @@ -35,14 +35,16 @@
>  #endif /* __MOVDIRI__ */
>
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _directstoreu_u32 (void * __P, unsigned int __A)
>  {
>    __builtin_ia32_directstoreu_u32 ((unsigned int *)__P, __A);
>  }
>  #ifdef __x86_64__
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _directstoreu_u64 (void * __P, unsigned long long __A)
>  {
>    __builtin_ia32_directstoreu_u64 ((unsigned long long *)__P, __A);
> @@ -61,7 +63,8 @@ _directstoreu_u64 (void * __P, unsigned long long __A)
>  #endif /* __MOVDIR64B__ */
>
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _movdir64b (void * __P, const void * __Q)
>  {
>    __builtin_ia32_movdir64b (__P, __Q);
> diff --git a/gcc/config/i386/mwaitxintrin.h b/gcc/config/i386/mwaitxintrin.h
> index ad8afba4c28..0c9505bb2f6 100644
> --- a/gcc/config/i386/mwaitxintrin.h
> +++ b/gcc/config/i386/mwaitxintrin.h
> @@ -30,13 +30,17 @@
>  #define __DISABLE_MWAITX__
>  #endif /* __MWAITX__ */
>
> -extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline void
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _mm_monitorx (void const * __P, unsigned int __E, unsigned int __H)
>  {
>    __builtin_ia32_monitorx (__P, __E, __H);
>  }
>
> -extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline void
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _mm_mwaitx (unsigned int __E, unsigned int __H, unsigned int __C)
>  {
>    __builtin_ia32_mwaitx (__E, __H, __C);
> diff --git a/gcc/config/i386/pconfigintrin.h b/gcc/config/i386/pconfigintrin.h
> index 5346cbd78cb..f8f6279c586 100644
> --- a/gcc/config/i386/pconfigintrin.h
> +++ b/gcc/config/i386/pconfigintrin.h
> @@ -47,7 +47,8 @@
>         : "cc")
>
>  extern __inline unsigned int
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _pconfig_u32 (const unsigned int __L, size_t __D[])
>  {
>    enum __pconfig_type
> diff --git a/gcc/config/i386/pkuintrin.h b/gcc/config/i386/pkuintrin.h
> index cd5638fa035..6e59617a0ce 100644
> --- a/gcc/config/i386/pkuintrin.h
> +++ b/gcc/config/i386/pkuintrin.h
> @@ -35,14 +35,16 @@
>  #endif /* __PKU__ */
>
>  extern __inline unsigned int
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _rdpkru_u32 (void)
>  {
>    return __builtin_ia32_rdpkru ();
>  }
>
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _wrpkru (unsigned int __key)
>  {
>    __builtin_ia32_wrpkru (__key);
> diff --git a/gcc/config/i386/popcntintrin.h b/gcc/config/i386/popcntintrin.h
> index 84876562640..640de9db733 100644
> --- a/gcc/config/i386/popcntintrin.h
> +++ b/gcc/config/i386/popcntintrin.h
> @@ -31,14 +31,18 @@
>  #endif /* __POPCNT__ */
>
>  /* Calculate a number of bits set to 1.  */
> -extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline int
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _mm_popcnt_u32 (unsigned int __X)
>  {
>    return __builtin_popcount (__X);
>  }
>
>  #ifdef __x86_64__
> -extern __inline long long  __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline long long
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _mm_popcnt_u64 (unsigned long long __X)
>  {
>    return __builtin_popcountll (__X);
> diff --git a/gcc/config/i386/rdseedintrin.h b/gcc/config/i386/rdseedintrin.h
> index 1badab7018c..0dc5fadce6a 100644
> --- a/gcc/config/i386/rdseedintrin.h
> +++ b/gcc/config/i386/rdseedintrin.h
> @@ -36,14 +36,16 @@
>
>
>  extern __inline int
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _rdseed16_step (unsigned short *__p)
>  {
>    return __builtin_ia32_rdseed_hi_step (__p);
>  }
>
>  extern __inline int
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _rdseed32_step (unsigned int *__p)
>  {
>    return __builtin_ia32_rdseed_si_step (__p);
> @@ -51,7 +53,8 @@ _rdseed32_step (unsigned int *__p)
>
>  #ifdef __x86_64__
>  extern __inline int
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _rdseed64_step (unsigned long long *__p)
>  {
>    return __builtin_ia32_rdseed_di_step (__p);
> diff --git a/gcc/config/i386/rtmintrin.h b/gcc/config/i386/rtmintrin.h
> index 5b2ac767737..33aadcfec61 100644
> --- a/gcc/config/i386/rtmintrin.h
> +++ b/gcc/config/i386/rtmintrin.h
> @@ -46,7 +46,8 @@
>  /* Start an RTM code region.  Return _XBEGIN_STARTED on success and the
>     abort condition otherwise.  */
>  extern __inline unsigned int
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _xbegin (void)
>  {
>    return __builtin_ia32_xbegin ();
> @@ -57,7 +58,8 @@ _xbegin (void)
>     commit fails, then control is transferred to the outermost transaction
>     fallback handler.  */
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _xend (void)
>  {
>    __builtin_ia32_xend ();
> @@ -67,7 +69,8 @@ _xend (void)
>     outermost transaction fallback handler with the abort condition IMM.  */
>  #ifdef __OPTIMIZE__
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _xabort (const unsigned int __imm)
>  {
>    __builtin_ia32_xabort (__imm);
> diff --git a/gcc/config/i386/serializeintrin.h b/gcc/config/i386/serializeintrin.h
> index e280250b198..dd27e6c7a81 100644
> --- a/gcc/config/i386/serializeintrin.h
> +++ b/gcc/config/i386/serializeintrin.h
> @@ -34,7 +34,13 @@
>  #define __DISABLE_SERIALIZE__
>  #endif /* __SERIALIZE__ */
>
> -#define _serialize()   __builtin_ia32_serialize ()
> +extern __inline void
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
> +_serialize (void)
> +{
> +  __builtin_ia32_serialize ();
> +}
>
>  #ifdef __DISABLE_SERIALIZE__
>  #undef __DISABLE_SERIALIZE__
> diff --git a/gcc/config/i386/sgxintrin.h b/gcc/config/i386/sgxintrin.h
> index 152be6a37ed..264214af972 100644
> --- a/gcc/config/i386/sgxintrin.h
> +++ b/gcc/config/i386/sgxintrin.h
> @@ -108,7 +108,8 @@
>            : "cc")
>
>  extern __inline unsigned int
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _encls_u32 (const unsigned int __L, size_t __D[])
>  {
>    enum __encls_type
> @@ -175,7 +176,8 @@ _encls_u32 (const unsigned int __L, size_t __D[])
>  }
>
>  extern __inline unsigned int
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _enclu_u32 (const unsigned int __L, size_t __D[])
>  {
>    enum __enclu_type
> @@ -218,7 +220,8 @@ _enclu_u32 (const unsigned int __L, size_t __D[])
>  }
>
>  extern __inline unsigned int
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _enclv_u32 (const unsigned int __L, size_t __D[])
>  {
>    enum __enclv_type
> diff --git a/gcc/config/i386/tbmintrin.h b/gcc/config/i386/tbmintrin.h
> index 971d1f36aff..bc9d3269515 100644
> --- a/gcc/config/i386/tbmintrin.h
> +++ b/gcc/config/i386/tbmintrin.h
> @@ -35,7 +35,9 @@
>  #endif /* __TBM__ */
>
>  #ifdef __OPTIMIZE__
> -extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned int
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __bextri_u32 (unsigned int __X, const unsigned int __I)
>  {
>    return __builtin_ia32_bextri_u32 (__X, __I);
> @@ -46,55 +48,73 @@ __bextri_u32 (unsigned int __X, const unsigned int __I)
>                                             (unsigned int)(I)))
>  #endif /*__OPTIMIZE__ */
>
> -extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned int
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __blcfill_u32 (unsigned int __X)
>  {
>    return __X & (__X + 1);
>  }
>
> -extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned int
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __blci_u32 (unsigned int __X)
>  {
>    return __X | ~(__X + 1);
>  }
>
> -extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned int
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __blcic_u32 (unsigned int __X)
>  {
>    return ~__X & (__X + 1);
>  }
>
> -extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned int
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __blcmsk_u32 (unsigned int __X)
>  {
>    return __X ^ (__X + 1);
>  }
>
> -extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned int
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __blcs_u32 (unsigned int __X)
>  {
>    return __X | (__X + 1);
>  }
>
> -extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned int
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __blsfill_u32 (unsigned int __X)
>  {
>    return __X | (__X - 1);
>  }
>
> -extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned int
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __blsic_u32 (unsigned int __X)
>  {
>    return ~__X | (__X - 1);
>  }
>
> -extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned int
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __t1mskc_u32 (unsigned int __X)
>  {
>    return ~__X | (__X + 1);
>  }
>
> -extern __inline unsigned int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned int
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __tzmsk_u32 (unsigned int __X)
>  {
>    return ~__X & (__X - 1);
> @@ -104,7 +124,9 @@ __tzmsk_u32 (unsigned int __X)
>
>  #ifdef __x86_64__
>  #ifdef __OPTIMIZE__
> -extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned long long
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __bextri_u64 (unsigned long long __X, const unsigned int __I)
>  {
>    return __builtin_ia32_bextri_u64 (__X, __I);
> @@ -115,55 +137,73 @@ __bextri_u64 (unsigned long long __X, const unsigned int __I)
>                                                   (unsigned long long)(I)))
>  #endif /*__OPTIMIZE__ */
>
> -extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned long long
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __blcfill_u64 (unsigned long long __X)
>  {
>    return __X & (__X + 1);
>  }
>
> -extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned long long
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __blci_u64 (unsigned long long __X)
>  {
>    return __X | ~(__X + 1);
>  }
>
> -extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned long long
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __blcic_u64 (unsigned long long __X)
>  {
>    return ~__X & (__X + 1);
>  }
>
> -extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned long long
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __blcmsk_u64 (unsigned long long __X)
>  {
>    return __X ^ (__X + 1);
>  }
>
> -extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned long long
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __blcs_u64 (unsigned long long __X)
>  {
>    return __X | (__X + 1);
>  }
>
> -extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned long long
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __blsfill_u64 (unsigned long long __X)
>  {
>    return __X | (__X - 1);
>  }
>
> -extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned long long
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __blsic_u64 (unsigned long long __X)
>  {
>    return ~__X | (__X - 1);
>  }
>
> -extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned long long
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __t1mskc_u64 (unsigned long long __X)
>  {
>    return ~__X | (__X + 1);
>  }
>
> -extern __inline unsigned long long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +extern __inline unsigned long long
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  __tzmsk_u64 (unsigned long long __X)
>  {
>    return ~__X & (__X - 1);
> diff --git a/gcc/config/i386/tsxldtrkintrin.h b/gcc/config/i386/tsxldtrkintrin.h
> index bb42a8e89b9..32a0b87c43a 100644
> --- a/gcc/config/i386/tsxldtrkintrin.h
> +++ b/gcc/config/i386/tsxldtrkintrin.h
> @@ -35,14 +35,16 @@
>  #endif /* __TSXLDTRK__ */
>
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _xsusldtrk (void)
>  {
>    __builtin_ia32_xsusldtrk ();
>  }
>
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _xresldtrk (void)
>  {
>    __builtin_ia32_xresldtrk ();
> diff --git a/gcc/config/i386/uintrintrin.h b/gcc/config/i386/uintrintrin.h
> index 2ff0cce9b49..d424bc22ba8 100644
> --- a/gcc/config/i386/uintrintrin.h
> +++ b/gcc/config/i386/uintrintrin.h
> @@ -47,28 +47,32 @@ struct __uintr_frame
>  };
>
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _clui (void)
>  {
>    __builtin_ia32_clui ();
>  }
>
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _stui (void)
>  {
>    __builtin_ia32_stui ();
>  }
>
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _senduipi (unsigned long long __R)
>  {
>    __builtin_ia32_senduipi (__R);
>  }
>
>  extern __inline unsigned char
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _testui (void)
>  {
>    return __builtin_ia32_testui ();
> diff --git a/gcc/config/i386/waitpkgintrin.h b/gcc/config/i386/waitpkgintrin.h
> index a7a4d6a927d..a2d7b004545 100644
> --- a/gcc/config/i386/waitpkgintrin.h
> +++ b/gcc/config/i386/waitpkgintrin.h
> @@ -35,21 +35,24 @@
>  #endif /* __WAITPKG__ */
>
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _umonitor (void *__A)
>  {
>    __builtin_ia32_umonitor (__A);
>  }
>
>  extern __inline unsigned char
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _umwait (unsigned int __A, unsigned long long __B)
>  {
>    return __builtin_ia32_umwait (__A, __B);
>  }
>
>  extern __inline unsigned char
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _tpause (unsigned int __A, unsigned long long __B)
>  {
>    return __builtin_ia32_tpause (__A, __B);
> diff --git a/gcc/config/i386/wbnoinvdintrin.h b/gcc/config/i386/wbnoinvdintrin.h
> index 71dc1b6accb..6ba9ca01f27 100644
> --- a/gcc/config/i386/wbnoinvdintrin.h
> +++ b/gcc/config/i386/wbnoinvdintrin.h
> @@ -35,7 +35,8 @@
>  #endif /* __WBNOINVD__ */
>
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _wbnoinvd (void)
>  {
>    __builtin_ia32_wbnoinvd ();
> diff --git a/gcc/config/i386/x86gprintrin.h b/gcc/config/i386/x86gprintrin.h
> index ceda501252c..4289ff66cfd 100644
> --- a/gcc/config/i386/x86gprintrin.h
> +++ b/gcc/config/i386/x86gprintrin.h
> @@ -95,7 +95,8 @@
>  #include <hresetintrin.h>
>
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _wbinvd (void)
>  {
>    __builtin_ia32_wbinvd ();
> @@ -107,14 +108,16 @@ _wbinvd (void)
>  #define __DISABLE_RDRND__
>  #endif /* __RDRND__ */
>  extern __inline int
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _rdrand16_step (unsigned short *__P)
>  {
>    return __builtin_ia32_rdrand16_step (__P);
>  }
>
>  extern __inline int
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _rdrand32_step (unsigned int *__P)
>  {
>    return __builtin_ia32_rdrand32_step (__P);
> @@ -130,7 +133,8 @@ _rdrand32_step (unsigned int *__P)
>  #define __DISABLE_RDPID__
>  #endif /* __RDPID__ */
>  extern __inline unsigned int
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _rdpid_u32 (void)
>  {
>    return __builtin_ia32_rdpid ();
> @@ -148,56 +152,64 @@ _rdpid_u32 (void)
>  #define __DISABLE_FSGSBASE__
>  #endif /* __FSGSBASE__ */
>  extern __inline unsigned int
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _readfsbase_u32 (void)
>  {
>    return __builtin_ia32_rdfsbase32 ();
>  }
>
>  extern __inline unsigned long long
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _readfsbase_u64 (void)
>  {
>    return __builtin_ia32_rdfsbase64 ();
>  }
>
>  extern __inline unsigned int
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _readgsbase_u32 (void)
>  {
>    return __builtin_ia32_rdgsbase32 ();
>  }
>
>  extern __inline unsigned long long
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _readgsbase_u64 (void)
>  {
>    return __builtin_ia32_rdgsbase64 ();
>  }
>
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _writefsbase_u32 (unsigned int __B)
>  {
>    __builtin_ia32_wrfsbase32 (__B);
>  }
>
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _writefsbase_u64 (unsigned long long __B)
>  {
>    __builtin_ia32_wrfsbase64 (__B);
>  }
>
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _writegsbase_u32 (unsigned int __B)
>  {
>    __builtin_ia32_wrgsbase32 (__B);
>  }
>
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _writegsbase_u64 (unsigned long long __B)
>  {
>    __builtin_ia32_wrgsbase64 (__B);
> @@ -213,7 +225,8 @@ _writegsbase_u64 (unsigned long long __B)
>  #define __DISABLE_RDRND__
>  #endif /* __RDRND__ */
>  extern __inline int
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _rdrand64_step (unsigned long long *__P)
>  {
>    return __builtin_ia32_rdrand64_step (__P);
> @@ -233,7 +246,8 @@ _rdrand64_step (unsigned long long *__P)
>
>  #ifdef __x86_64__
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _ptwrite64 (unsigned long long __B)
>  {
>    __builtin_ia32_ptwrite64 (__B);
> @@ -241,7 +255,8 @@ _ptwrite64 (unsigned long long __B)
>  #endif /* __x86_64__ */
>
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _ptwrite32 (unsigned __B)
>  {
>    __builtin_ia32_ptwrite32 (__B);
> diff --git a/gcc/config/i386/xsavecintrin.h b/gcc/config/i386/xsavecintrin.h
> index 45751a087bb..d0739cbd1cc 100644
> --- a/gcc/config/i386/xsavecintrin.h
> +++ b/gcc/config/i386/xsavecintrin.h
> @@ -35,7 +35,8 @@
>  #endif /* __XSAVEC__ */
>
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _xsavec (void *__P, long long __M)
>  {
>    __builtin_ia32_xsavec (__P, __M);
> @@ -43,7 +44,8 @@ _xsavec (void *__P, long long __M)
>
>  #ifdef __x86_64__
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _xsavec64 (void *__P, long long __M)
>  {
>    __builtin_ia32_xsavec64 (__P, __M);
> diff --git a/gcc/config/i386/xsaveintrin.h b/gcc/config/i386/xsaveintrin.h
> index 56e6a1e527b..50d174fa2b0 100644
> --- a/gcc/config/i386/xsaveintrin.h
> +++ b/gcc/config/i386/xsaveintrin.h
> @@ -35,28 +35,32 @@
>  #endif /* __XSAVE__ */
>
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _xsave (void *__P, long long __M)
>  {
>    __builtin_ia32_xsave (__P, __M);
>  }
>
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _xrstor (void *__P, long long __M)
>  {
>    __builtin_ia32_xrstor (__P, __M);
>  }
>
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _xsetbv (unsigned int __A, long long __V)
>  {
>    __builtin_ia32_xsetbv (__A, __V);
>  }
>
>  extern __inline long long
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _xgetbv (unsigned int __A)
>  {
>    return __builtin_ia32_xgetbv (__A);
> @@ -64,14 +68,16 @@ _xgetbv (unsigned int __A)
>
>  #ifdef __x86_64__
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _xsave64 (void *__P, long long __M)
>  {
>    __builtin_ia32_xsave64 (__P, __M);
>  }
>
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _xrstor64 (void *__P, long long __M)
>  {
>    __builtin_ia32_xrstor64 (__P, __M);
> diff --git a/gcc/config/i386/xsaveoptintrin.h b/gcc/config/i386/xsaveoptintrin.h
> index ba076cea51a..b5c25f94f95 100644
> --- a/gcc/config/i386/xsaveoptintrin.h
> +++ b/gcc/config/i386/xsaveoptintrin.h
> @@ -35,7 +35,8 @@
>  #endif /* __XSAVEOPT__ */
>
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _xsaveopt (void *__P, long long __M)
>  {
>    __builtin_ia32_xsaveopt (__P, __M);
> @@ -43,7 +44,8 @@ _xsaveopt (void *__P, long long __M)
>
>  #ifdef __x86_64__
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _xsaveopt64 (void *__P, long long __M)
>  {
>    __builtin_ia32_xsaveopt64 (__P, __M);
> diff --git a/gcc/config/i386/xsavesintrin.h b/gcc/config/i386/xsavesintrin.h
> index 969835fed64..27cec8370ad 100644
> --- a/gcc/config/i386/xsavesintrin.h
> +++ b/gcc/config/i386/xsavesintrin.h
> @@ -35,14 +35,16 @@
>  #endif /* __XSAVES__ */
>
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _xsaves (void *__P, long long __M)
>  {
>    __builtin_ia32_xsaves (__P, __M);
>  }
>
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _xrstors (void *__P, long long __M)
>  {
>    __builtin_ia32_xrstors (__P, __M);
> @@ -50,14 +52,16 @@ _xrstors (void *__P, long long __M)
>
>  #ifdef __x86_64__
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _xrstors64 (void *__P, long long __M)
>  {
>    __builtin_ia32_xrstors64 (__P, __M);
>  }
>
>  extern __inline void
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _xsaves64 (void *__P, long long __M)
>  {
>    __builtin_ia32_xsaves64 (__P, __M);
> diff --git a/gcc/config/i386/xtestintrin.h b/gcc/config/i386/xtestintrin.h
> index 39d18af6536..0eae87a1d43 100644
> --- a/gcc/config/i386/xtestintrin.h
> +++ b/gcc/config/i386/xtestintrin.h
> @@ -37,7 +37,8 @@
>  /* Return non-zero if the instruction executes inside an RTM or HLE code
>     region.  Return zero otherwise.   */
>  extern __inline int
> -__attribute__((__gnu_inline__, __always_inline__, __artificial__))
> +__attribute__((__gnu_inline__, __always_inline__, __artificial__,
> +              __general_regs_only__))
>  _xtest (void)
>  {
>    return __builtin_ia32_xtest ();
> diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
> index 1ddafb3ff2c..7111eca62ff 100644
> --- a/gcc/doc/extend.texi
> +++ b/gcc/doc/extend.texi
> @@ -7066,6 +7066,11 @@ On x86 targets, the @code{fentry_section} attribute sets the name
>  of the section to record function entry instrumentation calls in when
>  enabled with @option{-pg -mrecord-mcount}
>
> +@item general_regs_only
> +@cindex @code{general_regs_only} function attribute, x86
> +The @code{general_regs_only} attribute on functions is used to
> +inform the compiler that functions use only general purpose registers.
> +
>  @end table
>
>  @node Xstormy16 Function Attributes
> diff --git a/gcc/testsuite/gcc.target/i386/pr99744-3.c b/gcc/testsuite/gcc.target/i386/pr99744-3.c
> new file mode 100644
> index 00000000000..6c505816ceb
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr99744-3.c
> @@ -0,0 +1,13 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -mno-serialize" } */
> +
> +#include <x86intrin.h>
> +
> +__attribute__ ((target("general-regs-only")))
> +void
> +foo1 (void)
> +{
> +  _serialize ();
> +}
> +
> +/* { dg-error "target specific option mismatch" "" { target *-*-* } 0 } */
> diff --git a/gcc/testsuite/gcc.target/i386/pr99744-4.c b/gcc/testsuite/gcc.target/i386/pr99744-4.c
> new file mode 100644
> index 00000000000..a17d4a2139b
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr99744-4.c
> @@ -0,0 +1,352 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -mbmi -mbmi2 -mcldemote -mclflushopt -mclwb -mclzero -menqcmd -mfsgsbase -mfxsr -mhreset -mlzcnt -mlwp -mmovdir64b -mmovdiri -mmwaitx -mpconfig -mpku -mpopcnt -mptwrite -mrdpid -mrdrnd -mrdseed -mrtm -msgx -mshstk -mtbm -mtsxldtrk -mxsave -mxsavec -mxsaveopt -mxsaves -mwaitpkg -mwbnoinvd" } */
> +/* { dg-additional-options "-muintr" { target { ! ia32 } } }  */
> +
> +/* Test calling GPR intrinsics from functions with general-regs-only
> +   target attribue.  */
> +
> +#include <x86gprintrin.h>
> +
> +#define _CONCAT(x,y) x ## y
> +
> +#define test_0(func, type)                                             \
> +  __attribute__ ((target("general-regs-only")))                                \
> +  type _CONCAT(do_,func) (void)                                                \
> +  { return func (); }
> +
> +#define test_0_i1(func, type, imm)                                     \
> +  __attribute__ ((target("general-regs-only")))                                \
> +  type _CONCAT(do_,func) (void)                                                \
> +  { return func (imm); }
> +
> +#define test_1(func, type, op1_type)                                   \
> +  __attribute__ ((target("general-regs-only")))                                \
> +  type _CONCAT(do_,func) (op1_type A)                                  \
> +  { return func (A); }
> +
> +#define test_1_i1(func, type, op1_type, imm)                           \
> +  __attribute__ ((target("general-regs-only")))                                \
> +  type _CONCAT(do_,func) (op1_type A)                                  \
> +  { return func (A, imm); }
> +
> +#define test_2(func, type, op1_type, op2_type)                         \
> +  __attribute__ ((target("general-regs-only")))                                \
> +  type _CONCAT(do_,func) (op1_type A, op2_type B)                      \
> +  { return func (A, B); }
> +
> +#define test_2_i1(func, type, op1_type, op2_type, imm)                 \
> +  __attribute__ ((target("general-regs-only")))                                \
> +  type _CONCAT(do_,func) (op1_type A, op2_type B)                      \
> +  { return func (A, B, imm); }
> +
> +#define test_3(func, type, op1_type, op2_type, op3_type)               \
> +  __attribute__ ((target("general-regs-only")))                                \
> +  type _CONCAT(do_,func) (op1_type A, op2_type B, op3_type C)          \
> +  { return func (A, B, C); }
> +
> +#define test_4(func, type, op1_type, op2_type, op3_type, op4_type)     \
> +  __attribute__ ((target("general-regs-only")))                                \
> +  type _CONCAT(do_,func) (op1_type A, op2_type B, op3_type C,          \
> +                         op4_type D)                                   \
> +  { return func (A, B, C, D); }
> +
> +/* ia32intrin.h  */
> +test_1 (__bsfd, int, int)
> +test_1 (__bsrd, int, int)
> +test_1 (__bswapd, int, int)
> +test_1 (__popcntd, int, unsigned int)
> +test_2 (__rolb, unsigned char, unsigned char, int)
> +test_2 (__rolw, unsigned short, unsigned short, int)
> +test_2 (__rold, unsigned int, unsigned int, int)
> +test_2 (__rorb, unsigned char, unsigned char, int)
> +test_2 (__rorw, unsigned short, unsigned short, int)
> +test_2 (__rord, unsigned int, unsigned int, int)
> +
> +#ifndef __iamcu__
> +/* ia32intrin.h  */
> +test_1 (__rdpmc, unsigned long long, int)
> +test_0 (__rdtsc, unsigned long long)
> +test_1 (__rdtscp, unsigned long long, unsigned int *)
> +test_0 (__pause, void)
> +
> +/* adxintrin.h */
> +test_4 (_subborrow_u32, unsigned char, unsigned char, unsigned int,
> +       unsigned int, unsigned int *)
> +test_4 (_addcarry_u32, unsigned char, unsigned char, unsigned int,
> +       unsigned int, unsigned int *)
> +test_4 (_addcarryx_u32, unsigned char, unsigned char, unsigned int,
> +       unsigned int, unsigned int *)
> +
> +/* bmiintrin.h */
> +test_1 (__tzcnt_u16, unsigned short, unsigned short)
> +test_2 (__andn_u32, unsigned int, unsigned int, unsigned int)
> +test_2 (__bextr_u32, unsigned int, unsigned int, unsigned int)
> +test_3 (_bextr_u32, unsigned int, unsigned int, unsigned int,
> +       unsigned int)
> +test_1 (__blsi_u32, unsigned int, unsigned int)
> +test_1 (_blsi_u32, unsigned int, unsigned int)
> +test_1 (__blsmsk_u32, unsigned int, unsigned int)
> +test_1 (_blsmsk_u32, unsigned int, unsigned int)
> +test_1 (__blsr_u32, unsigned int, unsigned int)
> +test_1 (_blsr_u32, unsigned int, unsigned int)
> +test_1 (__tzcnt_u32, unsigned int, unsigned int)
> +test_1 (_tzcnt_u32, unsigned int, unsigned int)
> +
> +/* bmi2intrin.h */
> +test_2 (_bzhi_u32, unsigned int, unsigned int, unsigned int)
> +test_2 (_pdep_u32, unsigned int, unsigned int, unsigned int)
> +test_2 (_pext_u32, unsigned int, unsigned int, unsigned int)
> +
> +/* cetintrin.h */
> +test_1 (_inc_ssp, void, unsigned int)
> +test_0 (_saveprevssp, void)
> +test_1 (_rstorssp, void, void *)
> +test_2 (_wrssd, void, unsigned int, void *)
> +test_2 (_wrussd, void, unsigned int, void *)
> +test_0 (_setssbsy, void)
> +test_1 (_clrssbsy, void, void *)
> +
> +/* cldemoteintrin.h */
> +test_1 (_cldemote, void, void *)
> +
> +/* clflushoptintrin.h */
> +test_1 (_mm_clflushopt, void, void *)
> +
> +/* clwbintrin.h */
> +test_1 (_mm_clwb, void, void *)
> +
> +/* clzerointrin.h */
> +test_1 (_mm_clzero, void, void *)
> +
> +/* enqcmdintrin.h */
> +test_2 (_enqcmd, int, void *, const void *)
> +test_2 (_enqcmds, int, void *, const void *)
> +
> +/* fxsrintrin.h */
> +test_1 (_fxsave, void, void *)
> +test_1 (_fxrstor, void, void *)
> +
> +/* hresetintrin.h */
> +test_1 (_hreset, void, unsigned int)
> +
> +/* lzcntintrin.h */
> +test_1 (__lzcnt16, unsigned short, unsigned short)
> +test_1 (__lzcnt32, unsigned int, unsigned int)
> +test_1 (_lzcnt_u32, unsigned int, unsigned int)
> +
> +/* lwpintrin.h */
> +test_1 (__llwpcb, void, void *)
> +test_0 (__slwpcb, void *)
> +test_2_i1 (__lwpval32, void, unsigned int, unsigned int, 1)
> +test_2_i1 (__lwpins32, unsigned char, unsigned int, unsigned int, 1)
> +
> +/* movdirintrin.h */
> +test_2 (_directstoreu_u32, void, void *, unsigned int)
> +test_2 (_movdir64b, void, void *, const void *)
> +
> +/* mwaitxintrin.h */
> +test_3 (_mm_monitorx, void, void const *, unsigned int, unsigned int)
> +test_3 (_mm_mwaitx, void, unsigned int, unsigned int, unsigned int)
> +
> +/* pconfigintrin.h */
> +test_2 (_pconfig_u32, unsigned int, const unsigned int, size_t *)
> +
> +/* pkuintrin.h */
> +test_0 (_rdpkru_u32, unsigned int)
> +test_1 (_wrpkru, void, unsigned int)
> +
> +/* popcntintrin.h */
> +test_1 (_mm_popcnt_u32, int, unsigned int)
> +
> +/* rdseedintrin.h */
> +test_1 (_rdseed16_step, int, unsigned short *)
> +test_1 (_rdseed32_step, int, unsigned int *)
> +
> +/* rtmintrin.h */
> +test_0 (_xbegin, unsigned int)
> +test_0 (_xend, void)
> +test_0_i1 (_xabort, void, 1)
> +
> +/* sgxintrin.h */
> +test_2 (_encls_u32, unsigned int, const unsigned int, size_t *)
> +test_2 (_enclu_u32, unsigned int, const unsigned int, size_t *)
> +test_2 (_enclv_u32, unsigned int, const unsigned int, size_t *)
> +
> +/* tbmintrin.h */
> +test_1_i1 (__bextri_u32, unsigned int, unsigned int, 1)
> +test_1 (__blcfill_u32, unsigned int, unsigned int)
> +test_1 (__blci_u32, unsigned int, unsigned int)
> +test_1 (__blcic_u32, unsigned int, unsigned int)
> +test_1 (__blcmsk_u32, unsigned int, unsigned int)
> +test_1 (__blcs_u32, unsigned int, unsigned int)
> +test_1 (__blsfill_u32, unsigned int, unsigned int)
> +test_1 (__blsic_u32, unsigned int, unsigned int)
> +test_1 (__t1mskc_u32, unsigned int, unsigned int)
> +test_1 (__tzmsk_u32, unsigned int, unsigned int)
> +
> +/* tsxldtrkintrin.h */
> +test_0 (_xsusldtrk, void)
> +test_0 (_xresldtrk, void)
> +
> +/* x86gprintrin.h */
> +test_1 (_ptwrite32, void, unsigned int)
> +test_1 (_rdrand16_step, int, unsigned short *)
> +test_1 (_rdrand32_step, int, unsigned int *)
> +test_0 (_wbinvd, void)
> +
> +/* xtestintrin.h */
> +test_0 (_xtest, int)
> +
> +/* xsaveintrin.h */
> +test_2 (_xsave, void, void *, long long)
> +test_2 (_xrstor, void, void *, long long)
> +test_2 (_xsetbv, void, unsigned int, long long)
> +test_1 (_xgetbv, long long, unsigned int)
> +
> +/* xsavecintrin.h */
> +test_2 (_xsavec, void, void *, long long)
> +
> +/* xsaveoptintrin.h */
> +test_2 (_xsaveopt, void, void *, long long)
> +
> +/* xsavesintrin.h */
> +test_2 (_xsaves, void, void *, long long)
> +test_2 (_xrstors, void, void *, long long)
> +
> +/* wbnoinvdintrin.h */
> +test_0 (_wbnoinvd, void)
> +
> +#ifdef __x86_64__
> +/* adxintrin.h */
> +test_4 (_subborrow_u64, unsigned char, unsigned char,
> +       unsigned long long, unsigned long long,
> +       unsigned long long *)
> +test_4 (_addcarry_u64, unsigned char, unsigned char,
> +       unsigned long long, unsigned long long,
> +       unsigned long long *)
> +test_4 (_addcarryx_u64, unsigned char, unsigned char,
> +       unsigned long long, unsigned long long,
> +       unsigned long long *)
> +
> +/* bmiintrin.h */
> +test_2 (__andn_u64, unsigned long long, unsigned long long,
> +       unsigned long long)
> +test_2 (__bextr_u64, unsigned long long, unsigned long long,
> +       unsigned long long)
> +test_3 (_bextr_u64, unsigned long long, unsigned long long,
> +       unsigned long long, unsigned long long)
> +test_1 (__blsi_u64, unsigned long long, unsigned long long)
> +test_1 (_blsi_u64, unsigned long long, unsigned long long)
> +test_1 (__blsmsk_u64, unsigned long long, unsigned long long)
> +test_1 (_blsmsk_u64, unsigned long long, unsigned long long)
> +test_1 (__blsr_u64, unsigned long long, unsigned long long)
> +test_1 (_blsr_u64, unsigned long long, unsigned long long)
> +test_1 (__tzcnt_u64, unsigned long long, unsigned long long)
> +test_1 (_tzcnt_u64, unsigned long long, unsigned long long)
> +
> +/* bmi2intrin.h */
> +test_2 (_bzhi_u64, unsigned long long, unsigned long long,
> +       unsigned long long)
> +test_2 (_pdep_u64, unsigned long long, unsigned long long,
> +       unsigned long long)
> +test_2 (_pext_u64, unsigned long long, unsigned long long,
> +       unsigned long long)
> +test_3 (_mulx_u64, unsigned long long, unsigned long long,
> +       unsigned long long, unsigned long long *)
> +
> +/* cetintrin.h */
> +test_0 (_get_ssp, unsigned long long)
> +test_2 (_wrssq, void, unsigned long long, void *)
> +test_2 (_wrussq, void, unsigned long long, void *)
> +
> +/* fxsrintrin.h */
> +test_1 (_fxsave64, void, void *)
> +test_1 (_fxrstor64, void, void *)
> +
> +/* ia32intrin.h  */
> +test_1 (__bsfq, int, long long)
> +test_1 (__bsrq, int, long long)
> +test_1 (__bswapq, long long, long long)
> +test_1 (__popcntq, long long, unsigned long long)
> +test_2 (__rolq, unsigned long long, unsigned long long, int)
> +test_2 (__rorq, unsigned long long, unsigned long long, int)
> +test_0 (__readeflags, unsigned long long)
> +test_1 (__writeeflags, void, unsigned int)
> +
> +/* lzcntintrin.h */
> +test_1 (__lzcnt64, unsigned long long, unsigned long long)
> +test_1 (_lzcnt_u64, unsigned long long, unsigned long long)
> +
> +/* lwpintrin.h */
> +test_2_i1 (__lwpval64, void, unsigned long long, unsigned int, 1)
> +test_2_i1 (__lwpins64, unsigned char, unsigned long long,
> +          unsigned int, 1)
> +
> +/* movdirintrin.h */
> +test_2 (_directstoreu_u64, void, void *, unsigned long long)
> +
> +/* popcntintrin.h */
> +test_1 (_mm_popcnt_u64, long long, unsigned long long)
> +
> +/* rdseedintrin.h */
> +test_1 (_rdseed64_step, int, unsigned long long *)
> +
> +/* tbmintrin.h */
> +test_1_i1 (__bextri_u64, unsigned long long, unsigned long long, 1)
> +test_1 (__blcfill_u64, unsigned long long, unsigned long long)
> +test_1 (__blci_u64, unsigned long long, unsigned long long)
> +test_1 (__blcic_u64, unsigned long long, unsigned long long)
> +test_1 (__blcmsk_u64, unsigned long long, unsigned long long)
> +test_1 (__blcs_u64, unsigned long long, unsigned long long)
> +test_1 (__blsfill_u64, unsigned long long, unsigned long long)
> +test_1 (__blsic_u64, unsigned long long, unsigned long long)
> +test_1 (__t1mskc_u64, unsigned long long, unsigned long long)
> +test_1 (__tzmsk_u64, unsigned long long, unsigned long long)
> +
> +/* uintrintrin.h */
> +test_0 (_clui, void)
> +test_1 (_senduipi, void, unsigned long long)
> +test_0 (_stui, void)
> +test_0 (_testui, unsigned char)
> +
> +/* x86gprintrin.h */
> +test_1 (_ptwrite64, void, unsigned long long)
> +test_0 (_readfsbase_u32, unsigned int)
> +test_0 (_readfsbase_u64, unsigned long long)
> +test_0 (_readgsbase_u32, unsigned int)
> +test_0 (_readgsbase_u64, unsigned long long)
> +test_1 (_rdrand64_step, int, unsigned long long *)
> +test_1 (_writefsbase_u32, void, unsigned int)
> +test_1 (_writefsbase_u64, void, unsigned long long)
> +test_1 (_writegsbase_u32, void, unsigned int)
> +test_1 (_writegsbase_u64, void, unsigned long long)
> +
> +/* xsaveintrin.h */
> +test_2 (_xsave64, void, void *, long long)
> +test_2 (_xrstor64, void, void *, long long)
> +
> +/* xsavecintrin.h */
> +test_2 (_xsavec64, void, void *, long long)
> +
> +/* xsaveoptintrin.h */
> +test_2 (_xsaveopt64, void, void *, long long)
> +
> +/* xsavesintrin.h */
> +test_2 (_xsaves64, void, void *, long long)
> +test_2 (_xrstors64, void, void *, long long)
> +
> +/* waitpkgintrin.h */
> +test_1 (_umonitor, void, void *)
> +test_2 (_umwait, unsigned char, unsigned int, unsigned long long)
> +test_2 (_tpause, unsigned char, unsigned int, unsigned long long)
> +
> +#else /* !__x86_64__ */
> +/* bmi2intrin.h */
> +test_3 (_mulx_u32, unsigned int, unsigned int, unsigned int,
> +       unsigned int *)
> +
> +/* cetintrin.h */
> +test_0 (_get_ssp, unsigned int)
> +#endif /* __x86_64__ */
> +
> +#endif
> --
> 2.30.2
>

  reply	other threads:[~2021-04-21  7:30 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-14 22:39 [PATCH v4 0/2] " H.J. Lu
2021-04-14 22:39 ` [PATCH v4 1/2] x86: Move OPTION_MASK_* to i386-common.h H.J. Lu
2021-04-14 22:39 ` [PATCH v4 2/2] x86: Add general_regs_only function attribute H.J. Lu
2021-04-21  7:30   ` Uros Bizjak [this message]
2021-04-21 13:47     ` H.J. Lu
2021-04-21 16:54     ` Martin Sebor
2021-04-21 17:09   ` Martin Sebor
2021-04-21 20:58     ` H.J. Lu
2021-04-21 23:23       ` Martin Sebor
2021-04-22  1:01         ` H.J. Lu
2021-04-22  8:27           ` Richard Biener
2021-04-22  9:02           ` Jakub Jelinek
2021-04-22 11:23             ` Richard Biener
2021-04-22 11:57               ` H.J. Lu
2021-04-22 12:16                 ` Richard Biener
2021-04-22 12:22               ` Jakub Jelinek
2021-04-22 12:52                 ` Richard Biener
2021-04-22 12:55                   ` Richard Biener
2021-07-18  1:45                     ` [PATCH v5] <x86gprintrin.h>: Add pragma GCC target("general-regs-only") H.J. Lu
2021-07-31 15:35                       ` PING^1 " H.J. Lu
2021-08-03 11:47                       ` Richard Biener
2021-08-03 14:45                         ` [PATCH v6] " H.J. Lu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAFULd4ZpMs+5PoWFku2LiM-RWkcACnqBwrUmRJzpLg0vUAffYg@mail.gmail.com \
    --to=ubizjak@gmail.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=hjl.tools@gmail.com \
    --cc=jakub@redhat.com \
    --cc=msebor@gmail.com \
    --cc=rep.dot.nop@gmail.com \
    --cc=richard.guenther@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).