On Mon, Aug 24, 2020 at 7:55 AM Uros Bizjak <ubiz...@gmail.com> wrote:
>
> On Mon, Aug 24, 2020 at 3:23 PM H.J. Lu <hjl.to...@gmail.com> wrote:
>
> > > Speaking of pragmas, these should be added outside cpuid.h, like:
> > >
> > > #pragma GCC push_options
> > > #pragma GCC target("general-regs-only")
> > >
> > > #include <cpuid.h>
> > >
> > > void cpuid_check ()
> > > ...
> > >
> > > #pragma GCC pop_options
> > >
> > > >footnote
> > >
> > > Nowadays, -march=native is mostly used outside generic target
> > > compilations, so for relevant avx512 targets, we still generate spills
> > > to mask regs. In future, we can review the setting of the tuning flag
> > > for a generic target in the same way as with SSE2 inter-reg moves.
> > >
> >
> > Florian raised an issue that we need to limit <cpuid.h> to the basic ISAs.
> > <cpuid.h> should be handled similarly to other intrinsic header files.
> > That is <cpuid.h> should use
> >
> > #pragma GCC push_options
> > #ifdef __x86_64__
> > #pragma GCC target("arch=x86-64")
> > #else
> > #pragma GCC target("arch=i386")
> > ...
> > #pragma GCC pop_options
> >
> > Here is a patch.  OK for master?
>
> -ENOPATCH
>
> However, how will this affect inlining? Every single function in
> cpuid.h is defined as static __inline, and due to target flags
> mismatch, it won't be inlined anymore. These inline functions are used
> in some bit testing functions, and to keep them inlined, these should
> also use the same options to avoid non-basic ISAs. This is the reason
> cpuid.h should be #included after pragma, together with bit testing
> functions, as shown above.
>

How about target("baseline-isas-only")? All CPUID functions are
inlined.


-- 
H.J.
From 82efbfdc58e6bdcf11a9e09018db6bbc690f77b1 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.to...@gmail.com>
Date: Fri, 21 Aug 2020 09:42:49 -0700
Subject: [PATCH] x86: Use target("baseline-isas-only") in <cpuid.h>

CPUID check should be done only with baseline ISAs, which include FXSR,
MMX, SSE and SSE2 in 64-bit mode.

gcc/

	PR target/96744
	* common/config/i386/i386-common.c (ix86_handle_option): Support
	-mbaseline-isas-only.
	* config/i386/cpuid.h: Add #pragma GCC target("baseline-isas-only").
	* config/i386/i386-options.c (ix86_valid_target_attribute_inner_p):
	Handle baseline-isas-only.
	* config/i386/i386.opt: Add -mbaseline-isas-only.
	* doc/extend.texi: Document target("baseline-isas-only") function
	attribute.
	* doc/invoke.texi: Document -mbaseline-isas-only.

gcc/testsuite/

	PR target/96744
	* gcc.target/i386/avx512-check.h: Add #pragma GCC
	target("baseline-isas-only") for CPUID check.
	* gcc.target/i386/pr96744-10.c: New test.
---
 gcc/common/config/i386/i386-common.c         | 20 +++++++++++++++
 gcc/config/i386/cpuid.h                      | 13 ++++++++++
 gcc/config/i386/i386-options.c               |  7 ++++-
 gcc/config/i386/i386.opt                     |  6 ++++-
 gcc/doc/extend.texi                          |  4 +++
 gcc/doc/invoke.texi                          |  5 ++++
 gcc/testsuite/gcc.target/i386/avx512-check.h |  5 ++++
 gcc/testsuite/gcc.target/i386/pr96744-10.c   | 27 ++++++++++++++++++++
 8 files changed, 85 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr96744-10.c

diff --git a/gcc/common/config/i386/i386-common.c b/gcc/common/config/i386/i386-common.c
index bb14305ad7b..2c0b7f3fe0f 100644
--- a/gcc/common/config/i386/i386-common.c
+++ b/gcc/common/config/i386/i386-common.c
@@ -338,6 +338,26 @@ ix86_handle_option (struct gcc_options *opts,
 	gcc_unreachable ();
       return true;
 
+    case OPT_mbaseline_isas_only:
+      if (value)
+	{
+	  /* Only enable baseline ISAs.  */
+	  if ((opts->x_ix86_isa_flags & OPTION_MASK_ISA_64BIT))
+	    opts->x_ix86_isa_flags = (OPTION_MASK_ISA_64BIT
+				      | OPTION_MASK_ISA_FXSR
+				      | OPTION_MASK_ISA_MMX
+				      | OPTION_MASK_ISA_SSE
+				      | OPTION_MASK_ISA_SSE2);
+	  else
+	    opts->x_ix86_isa_flags = 0;
+	  opts->x_ix86_isa_flags2 = 0;
+	  opts->x_ix86_isa_flags_explicit = -1;
+	  opts->x_ix86_isa_flags2_explicit = -1;
+	}
+      else
+	gcc_unreachable ();
+      return true;
+
     case OPT_mmmx:
       if (value)
 	{
diff --git a/gcc/config/i386/cpuid.h b/gcc/config/i386/cpuid.h
index bca61d620db..dd2ef8f9b30 100644
--- a/gcc/config/i386/cpuid.h
+++ b/gcc/config/i386/cpuid.h
@@ -24,6 +24,17 @@
 #ifndef _CPUID_H_INCLUDED
 #define _CPUID_H_INCLUDED
 
+#pragma GCC push_options
+#if __GNUC__ >= 11
+#pragma GCC target("baseline-isas-only")
+#else
+#ifdef __x86_64__
+#pragma GCC target("arch=x86-64")
+#else
+#pragma GCC target("arch=i386")
+#endif
+#endif
+
 /* %eax */
 #define bit_AVX512BF16	(1 << 5)
 
@@ -324,4 +335,6 @@ __cpuidex (int __cpuid_info[4], int __leaf, int __subleaf)
 		 __cpuid_info[2], __cpuid_info[3]);
 }
 
+#pragma GCC pop_options
+
 #endif /* _CPUID_H_INCLUDED */
diff --git a/gcc/config/i386/i386-options.c b/gcc/config/i386/i386-options.c
index e0fc68c27bf..4a09c1c93ee 100644
--- a/gcc/config/i386/i386-options.c
+++ b/gcc/config/i386/i386-options.c
@@ -1072,6 +1072,10 @@ ix86_valid_target_attribute_inner_p (tree fndecl, tree args, char *p_strings[],
     IX86_ATTR_IX86_YES ("general-regs-only",
 			OPT_mgeneral_regs_only,
 			OPTION_MASK_GENERAL_REGS_ONLY),
+
+    IX86_ATTR_IX86_YES ("baseline-isas-only",
+			OPT_mbaseline_isas_only,
+			OPTION_MASK_BASELINE_ISAS_ONLY),
   };
 
   location_t loc
@@ -1187,7 +1191,8 @@ ix86_valid_target_attribute_inner_p (tree fndecl, tree args, char *p_strings[],
 
       else if (type == ix86_opt_ix86_yes || type == ix86_opt_ix86_no)
 	{
-	  if (mask == OPTION_MASK_GENERAL_REGS_ONLY)
+	  if (mask == OPTION_MASK_GENERAL_REGS_ONLY
+	      || mask == OPTION_MASK_BASELINE_ISAS_ONLY)
 	    {
 	      if (type != ix86_opt_ix86_yes)
 		gcc_unreachable ();
diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
index c9f7195d423..f3a088aaa28 100644
--- a/gcc/config/i386/i386.opt
+++ b/gcc/config/i386/i386.opt
@@ -1015,6 +1015,10 @@ mgeneral-regs-only
 Target Report RejectNegative Mask(GENERAL_REGS_ONLY) Var(ix86_target_flags) Save
 Generate code which uses only the general registers.
 
+mbaseline-isas-only
+Target Report RejectNegative Mask(BASELINE_ISAS_ONLY) Var(ix86_target_flags) Save
+Generate code which uses only the baseline ISAs.
+
 mshstk
 Target Report Mask(ISA_SHSTK) Var(ix86_isa_flags) Save
 Enable shadow stack built-in functions from Control-flow Enforcement
@@ -1114,4 +1118,4 @@ Support SERIALIZE built-in functions and code generation.
 
 mtsxldtrk
 Target Report Mask(ISA2_TSXLDTRK) Var(ix86_isa_flags2) Save
-Support TSXLDTRK built-in functions and code generation.
\ No newline at end of file
+Support TSXLDTRK built-in functions and code generation.
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 2bb9b2f72f5..eadb8dd71a4 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -6660,6 +6660,10 @@ doing a floating-point division.
 @cindex @code{target("general-regs-only")} function attribute, x86
 Generate code which uses only the general registers.
 
+@item baseline-isas-only
+@cindex @code{target("baseline-isas-only")} function attribute, x86
+Generate code which uses only the baseline ISAs.
+
 @item arch=@var{ARCH}
 @cindex @code{target("arch=@var{ARCH}")} function attribute, x86
 Specify the architecture to generate code for in compiling the function.
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 4cf6b204b56..5499bbe809e 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -30579,6 +30579,11 @@ Generate code that uses only the general-purpose registers.  This
 prevents the compiler from using floating-point, vector, mask and bound
 registers.
 
+@item -mbaseline-isas-only
+@opindex mbaseline-isas-only
+Generate code that uses only the baseline ISAs which include FXSR, MMX,
+SSE and SSE2 in 64-bit mode.
+
 @item -mindirect-branch=@var{choice}
 @opindex mindirect-branch
 Convert indirect call and jump with @var{choice}.  The default is
diff --git a/gcc/testsuite/gcc.target/i386/avx512-check.h b/gcc/testsuite/gcc.target/i386/avx512-check.h
index 0a377dba1d5..396a18d377b 100644
--- a/gcc/testsuite/gcc.target/i386/avx512-check.h
+++ b/gcc/testsuite/gcc.target/i386/avx512-check.h
@@ -25,6 +25,9 @@ do_test (void)
 }
 #endif
 
+#pragma GCC push_options
+#pragma GCC target("baseline-isas-only")
+
 static int
 check_osxsave (void)
 {
@@ -110,3 +113,5 @@ main ()
 #endif
   return 0;
 }
+
+#pragma GCC pop_options
diff --git a/gcc/testsuite/gcc.target/i386/pr96744-10.c b/gcc/testsuite/gcc.target/i386/pr96744-10.c
new file mode 100644
index 00000000000..f6f9badde1b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr96744-10.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=skylake" } */
+
+#include <cpuid.h>
+
+int
+main ()
+{
+  unsigned int eax, ebx, ecx, edx;
+  int cpuid_info[4];
+
+  if (!__get_cpuid_count (7, 0, &eax, &ebx, &ecx, &edx))
+    return 0;
+
+  __cpuidex (cpuid_info, 7, 0);
+
+  if (cpuid_info[0] != eax
+      || cpuid_info[1] != ebx
+      || cpuid_info[2] != ecx
+      || cpuid_info[3] != edx)
+    __builtin_abort ();
+
+  return 0;
+}
+
+/* { dg-final { scan-assembler-not {call[ \t]+_?__get_cpuid_count} } } */
+/* { dg-final { scan-assembler-not {call[ \t]+_?__cpuidex} } } */
-- 
2.26.2

Reply via email to