public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Martin Sebor <msebor@gmail.com>
To: Uros Bizjak <ubizjak@gmail.com>, "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>,
	Richard Biener <richard.guenther@gmail.com>
Subject: Re: [PATCH v4 2/2] x86: Add general_regs_only function attribute
Date: Wed, 21 Apr 2021 10:54:37 -0600	[thread overview]
Message-ID: <a252da7e-aef6-4fb2-9de0-e0ea53183a3b@gmail.com> (raw)
In-Reply-To: <CAFULd4ZpMs+5PoWFku2LiM-RWkcACnqBwrUmRJzpLg0vUAffYg@mail.gmail.com>

On 4/21/21 1:30 AM, Uros Bizjak wrote:
> 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?

FWIW, the sequence of attributes contributes measurably to
the amount of time it takes to parse all the declarations.  Since
they're the same for most of the thousands of functions declared
in these headers it might be worth considering either adding
a new attribute that "expands" to all of these, or using some
other mechanism to speed things up.  (This came up recenetly
in pr100099.)

Martin

> 
> 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
>>


  parent reply	other threads:[~2021-04-21 16:54 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
2021-04-21 13:47     ` H.J. Lu
2021-04-21 16:54     ` Martin Sebor [this message]
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=a252da7e-aef6-4fb2-9de0-e0ea53183a3b@gmail.com \
    --to=msebor@gmail.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=hjl.tools@gmail.com \
    --cc=jakub@redhat.com \
    --cc=rep.dot.nop@gmail.com \
    --cc=richard.guenther@gmail.com \
    --cc=ubizjak@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).