On Mon, Aug 24, 2020 at 7:55 AM Uros Bizjak <[email protected]> wrote:
>
> On Mon, Aug 24, 2020 at 3:23 PM H.J. Lu <[email protected]> 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" <[email protected]>
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