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 65bb0bbab95..2a8c5a5f522 100644
--- a/gcc/config/i386/i386-options.c
+++ b/gcc/config/i386/i386-options.c
@@ -3971,6 +3971,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 5422b0fc9e0..4c33781defa 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);
@@ -59,21 +62,24 @@ __bswapd (int __X)
 
 /* 32bit accumulate CRC32 (polynomial 0x11EDC6F41) value.  */
 extern __inline unsigned int
-__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__attribute__((__gnu_inline__, __always_inline__, __artificial__,
+	       __general_regs_only__))
 __crc32b (unsigned int __C, unsigned char __V)
 {
   return __builtin_ia32_crc32qi (__C, __V);
 }
 
 extern __inline unsigned int
-__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__attribute__((__gnu_inline__, __always_inline__, __artificial__,
+	       __general_regs_only__))
 __crc32w (unsigned int __C, unsigned short __V)
 {
   return __builtin_ia32_crc32hi (__C, __V);
 }
 
 extern __inline unsigned int
-__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__attribute__((__gnu_inline__, __always_inline__, __artificial__,
+	       __general_regs_only__))
 __crc32d (unsigned int __C, unsigned int __V)
 {
   return __builtin_ia32_crc32si (__C, __V);
@@ -88,7 +94,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 +105,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 +115,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 +147,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 +156,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 +166,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 +175,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 +184,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 +194,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 +204,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 +213,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 +222,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);
@@ -207,7 +237,8 @@ __bswapq (long long __X)
 
 /* 64bit accumulate CRC32 (polynomial 0x11EDC6F41) value.  */
 extern __inline unsigned long long
-__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__attribute__((__gnu_inline__, __always_inline__, __artificial__,
+	       __general_regs_only__))
 __crc32q (unsigned long long __C, unsigned long long __V)
 {
   return __builtin_ia32_crc32di (__C, __V);
@@ -220,7 +251,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 +260,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 +270,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 +280,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 +289,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 +302,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 +311,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 7793032ba90..957fc15277d 100644
--- a/gcc/config/i386/x86gprintrin.h
+++ b/gcc/config/i386/x86gprintrin.h
@@ -97,7 +97,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 ();
@@ -109,14 +110,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);
@@ -132,7 +135,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 ();
@@ -150,56 +154,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);
@@ -215,7 +227,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);
@@ -235,7 +248,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);
@@ -243,7 +257,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 c8caf36f293..79a89255179 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -7071,6 +7071,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..9196e62d955
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr99744-4.c
@@ -0,0 +1,357 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mbmi -mbmi2 -mcldemote -mclflushopt -mclwb -mclzero -mcrc32 -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 attribute.  */
+
+#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__
+/* 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)
+
+/* ia32intrin.h  */
+test_2 (__crc32b, unsigned int, unsigned char, unsigned char)
+test_2 (__crc32w, unsigned int, unsigned short, unsigned short)
+test_2 (__crc32d, unsigned int, unsigned int, unsigned int)
+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)
+
+/* 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_2 (__crc32q, unsigned long long, unsigned long long,
+	unsigned 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
