diff options
author | Martin Liska <mliska@suse.cz> | 2021-08-12 15:20:43 +0200 |
---|---|---|
committer | Martin Liska <mliska@suse.cz> | 2021-09-13 17:24:48 +0200 |
commit | 8ea292591e42aa4d52b4b7a00b86335bfd2e2e85 (patch) | |
tree | fb59f661f30741d2687da3d7196bea8d8673db90 /gcc | |
parent | 03312cbd54f337dfb25be356a1d1abc9925c6c03 (diff) | |
download | gcc-8ea292591e42aa4d52b4b7a00b86335bfd2e2e85.zip gcc-8ea292591e42aa4d52b4b7a00b86335bfd2e2e85.tar.gz gcc-8ea292591e42aa4d52b4b7a00b86335bfd2e2e85.tar.bz2 |
i386: support micro-levels in target{,_clone} attrs [PR101696]
As mentioned in the PR, we do miss supports target micro-architectures
in target and target_clone attribute. While the levels
x86-64 x86-64-v2 x86-64-v3 x86-64-v4 are supported values by -march
option, they are actually only aliases for k8 CPU. That said, they are more
closer to __builtin_cpu_supports function and we decided to implement
it there.
PR target/101696
gcc/ChangeLog:
* common/config/i386/cpuinfo.h (cpu_indicator_init): Add support
for x86-64 micro levels for __builtin_cpu_supports.
* common/config/i386/i386-cpuinfo.h (enum feature_priority):
Add priorities for the micro-arch levels.
(enum processor_features): Add new features.
* common/config/i386/i386-isas.h: Add micro-arch features.
* config/i386/i386-builtins.c (get_builtin_code_for_version):
Support the micro-arch levels by callsing
__builtin_cpu_supports.
* doc/extend.texi: Document that the levels are support by
__builtin_cpu_supports.
gcc/testsuite/ChangeLog:
* g++.target/i386/mv30.C: New test.
* gcc.target/i386/mvc16.c: New test.
* gcc.target/i386/builtin_target.c (CHECK___builtin_cpu_supports):
New.
Co-Authored-By: H.J. Lu <hjl.tools@gmail.com>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/common/config/i386/cpuinfo.h | 48 | ||||
-rw-r--r-- | gcc/common/config/i386/i386-cpuinfo.h | 8 | ||||
-rw-r--r-- | gcc/common/config/i386/i386-isas.h | 5 | ||||
-rw-r--r-- | gcc/config/i386/i386-builtins.c | 22 | ||||
-rw-r--r-- | gcc/doc/extend.texi | 12 | ||||
-rw-r--r-- | gcc/testsuite/g++.target/i386/mv30.C | 50 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/builtin_target.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/mvc16.c | 15 |
8 files changed, 159 insertions, 3 deletions
diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h index 1835ac6..bbf29bdb 100644 --- a/gcc/common/config/i386/cpuinfo.h +++ b/gcc/common/config/i386/cpuinfo.h @@ -46,6 +46,10 @@ struct __processor_model2 # define CHECK___builtin_cpu_is(cpu) #endif +#ifndef CHECK___builtin_cpu_supports +# define CHECK___builtin_cpu_supports(isa) +#endif + /* Return non-zero if the processor has feature F. */ static inline int @@ -933,6 +937,50 @@ cpu_indicator_init (struct __processor_model *cpu_model, else cpu_model->__cpu_vendor = VENDOR_OTHER; + if (has_cpu_feature (cpu_model, cpu_features2, FEATURE_LM) + && has_cpu_feature (cpu_model, cpu_features2, FEATURE_SSE2)) + { + CHECK___builtin_cpu_supports ("x86-64"); + set_cpu_feature (cpu_model, cpu_features2, + FEATURE_X86_64_BASELINE); + if (has_cpu_feature (cpu_model, cpu_features2, FEATURE_CMPXCHG16B) + && has_cpu_feature (cpu_model, cpu_features2, FEATURE_POPCNT) + && has_cpu_feature (cpu_model, cpu_features2, FEATURE_LAHF_LM) + && has_cpu_feature (cpu_model, cpu_features2, FEATURE_SSE4_2)) + { + CHECK___builtin_cpu_supports ("x86-64-v2"); + set_cpu_feature (cpu_model, cpu_features2, + FEATURE_X86_64_V2); + if (has_cpu_feature (cpu_model, cpu_features2, FEATURE_AVX2) + && has_cpu_feature (cpu_model, cpu_features2, FEATURE_BMI) + && has_cpu_feature (cpu_model, cpu_features2, FEATURE_BMI2) + && has_cpu_feature (cpu_model, cpu_features2, FEATURE_F16C) + && has_cpu_feature (cpu_model, cpu_features2, FEATURE_FMA) + && has_cpu_feature (cpu_model, cpu_features2, + FEATURE_LZCNT) + && has_cpu_feature (cpu_model, cpu_features2, + FEATURE_MOVBE)) + { + CHECK___builtin_cpu_supports ("x86-64-v3"); + set_cpu_feature (cpu_model, cpu_features2, + FEATURE_X86_64_V3); + if (has_cpu_feature (cpu_model, cpu_features2, + FEATURE_AVX512BW) + && has_cpu_feature (cpu_model, cpu_features2, + FEATURE_AVX512CD) + && has_cpu_feature (cpu_model, cpu_features2, + FEATURE_AVX512DQ) + && has_cpu_feature (cpu_model, cpu_features2, + FEATURE_AVX512VL)) + { + CHECK___builtin_cpu_supports ("x86-64-v4"); + set_cpu_feature (cpu_model, cpu_features2, + FEATURE_X86_64_V4); + } + } + } + } + gcc_assert (cpu_model->__cpu_vendor < VENDOR_MAX); gcc_assert (cpu_model->__cpu_type < CPU_TYPE_MAX); gcc_assert (cpu_model->__cpu_subtype < CPU_SUBTYPE_MAX); diff --git a/gcc/common/config/i386/i386-cpuinfo.h b/gcc/common/config/i386/i386-cpuinfo.h index 4e0659f..dc1a9fa 100644 --- a/gcc/common/config/i386/i386-cpuinfo.h +++ b/gcc/common/config/i386/i386-cpuinfo.h @@ -102,6 +102,7 @@ enum feature_priority P_MMX, P_SSE, P_SSE2, + P_X86_64_BASELINE, P_SSE3, P_SSSE3, P_PROC_SSSE3, @@ -111,6 +112,7 @@ enum feature_priority P_SSE4_2, P_PROC_SSE4_2, P_POPCNT, + P_X86_64_V2, P_AES, P_PCLMUL, P_AVX, @@ -125,8 +127,10 @@ enum feature_priority P_BMI2, P_AVX2, P_PROC_AVX2, + P_X86_64_V3, P_AVX512F, P_PROC_AVX512F, + P_X86_64_V4, P_PROC_DYNAMIC }; @@ -229,6 +233,10 @@ enum processor_features FEATURE_WIDEKL, FEATURE_AVXVNNI, FEATURE_AVX512FP16, + FEATURE_X86_64_BASELINE, + FEATURE_X86_64_V2, + FEATURE_X86_64_V3, + FEATURE_X86_64_V4, CPU_FEATURE_MAX }; diff --git a/gcc/common/config/i386/i386-isas.h b/gcc/common/config/i386/i386-isas.h index a678366..7784010 100644 --- a/gcc/common/config/i386/i386-isas.h +++ b/gcc/common/config/i386/i386-isas.h @@ -170,4 +170,9 @@ ISA_NAMES_TABLE_START ISA_NAMES_TABLE_ENTRY("widekl", FEATURE_WIDEKL, P_NONE, "-mwidekl") ISA_NAMES_TABLE_ENTRY("avxvnni", FEATURE_AVXVNNI, P_NONE, "-mavxvnni") ISA_NAMES_TABLE_ENTRY("avx512fp16", FEATURE_AVX512FP16, P_NONE, "-mavx512fp16") + ISA_NAMES_TABLE_ENTRY("x86-64", FEATURE_X86_64_BASELINE, P_X86_64_BASELINE, + NULL) + ISA_NAMES_TABLE_ENTRY("x86-64-v2", FEATURE_X86_64_V2, P_X86_64_V2, NULL) + ISA_NAMES_TABLE_ENTRY("x86-64-v3", FEATURE_X86_64_V3, P_X86_64_V3, NULL) + ISA_NAMES_TABLE_ENTRY("x86-64-v4", FEATURE_X86_64_V4, P_X86_64_V4, NULL) ISA_NAMES_TABLE_END diff --git a/gcc/config/i386/i386-builtins.c b/gcc/config/i386/i386-builtins.c index 1799701..11ce58b 100644 --- a/gcc/config/i386/i386-builtins.c +++ b/gcc/config/i386/i386-builtins.c @@ -1927,8 +1927,24 @@ get_builtin_code_for_version (tree decl, tree *predicate_list) return 0; new_target = TREE_TARGET_OPTION (target_node); gcc_assert (new_target); - - if (new_target->arch_specified && new_target->arch > 0) + enum ix86_builtins builtin_fn = IX86_BUILTIN_CPU_IS; + + /* Special case x86-64 micro-level architectures. */ + const char *arch_name = attrs_str + strlen ("arch="); + if (startswith (arch_name, "x86-64")) + { + arg_str = arch_name; + builtin_fn = IX86_BUILTIN_CPU_SUPPORTS; + if (strcmp (arch_name, "x86-64") == 0) + priority = P_X86_64_BASELINE; + else if (strcmp (arch_name, "x86-64-v2") == 0) + priority = P_X86_64_V2; + else if (strcmp (arch_name, "x86-64-v3") == 0) + priority = P_X86_64_V3; + else if (strcmp (arch_name, "x86-64-v4") == 0) + priority = P_X86_64_V4; + } + else if (new_target->arch_specified && new_target->arch > 0) for (i = 0; i < pta_size; i++) if (processor_alias_table[i].processor == new_target->arch) { @@ -1998,7 +2014,7 @@ get_builtin_code_for_version (tree decl, tree *predicate_list) if (predicate_list) { - predicate_decl = ix86_builtins [(int) IX86_BUILTIN_CPU_IS]; + predicate_decl = ix86_builtins [(int) builtin_fn]; /* For a C string literal the length includes the trailing NULL. */ predicate_arg = build_string_literal (strlen (arg_str) + 1, arg_str); predicate_chain = tree_cons (predicate_decl, predicate_arg, diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 8b324a0..9501a60 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -21743,6 +21743,18 @@ AMD Family 19h CPU. @item znver3 AMD Family 19h Zen version 3. + +@item x86-64 +Baseline x86-64 microarchitecture level (as defined in x86-64 psABI). + +@item x86-64-v2 +x86-64-v2 microarchitecture level. + +@item x86-64-v3 +x86-64-v3 microarchitecture level. + +@item x86-64-v4 +x86-64-v4 microarchitecture level. @end table Here is an example: diff --git a/gcc/testsuite/g++.target/i386/mv30.C b/gcc/testsuite/g++.target/i386/mv30.C new file mode 100644 index 0000000..b4947f0 --- /dev/null +++ b/gcc/testsuite/g++.target/i386/mv30.C @@ -0,0 +1,50 @@ +// PR target/101696 +// Test that dispatching can choose the right multiversion +// for x86-64 microarchitecture levels. + +// { dg-do run } +// { dg-require-ifunc "" } +// { dg-options "-O2" } + +#include <assert.h> + +int __attribute__ ((target("default"))) +foo () +{ + return 0; +} + +int __attribute__ ((target("arch=x86-64"))) foo () { + return 1; +} + +int __attribute__ ((target("arch=x86-64-v2"))) foo () { + return 2; +} + +int __attribute__ ((target("arch=x86-64-v3"))) foo () { + return 3; +} + +int __attribute__ ((target("arch=x86-64-v4"))) foo () { + return 4; +} + + +int main () +{ + int val = foo (); + + if (__builtin_cpu_supports ("x86-64-v4")) + assert (val == 4); + else if (__builtin_cpu_supports ("x86-64-v3")) + assert (val == 3); + else if (__builtin_cpu_supports ("x86-64-v2")) + assert (val == 2); + else if (__builtin_cpu_supports ("x86-64")) + assert (val == 1); + else + assert (val == 0); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/builtin_target.c b/gcc/testsuite/gcc.target/i386/builtin_target.c index aa96805..3e7505a 100644 --- a/gcc/testsuite/gcc.target/i386/builtin_target.c +++ b/gcc/testsuite/gcc.target/i386/builtin_target.c @@ -10,6 +10,8 @@ #include <stdlib.h> #include "cpuid.h" #define CHECK___builtin_cpu_is(cpu) assert (__builtin_cpu_is (cpu)) +#define CHECK___builtin_cpu_supports(isa) \ + assert (__builtin_cpu_supports (isa)) #define gcc_assert(a) assert (a) #define gcc_unreachable() abort () #define inline diff --git a/gcc/testsuite/gcc.target/i386/mvc16.c b/gcc/testsuite/gcc.target/i386/mvc16.c new file mode 100644 index 0000000..def6581 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/mvc16.c @@ -0,0 +1,15 @@ +/* { dg-do run } */ +/* { dg-require-ifunc "" } */ + +__attribute__((target_clones("arch=x86-64", "arch=x86-64-v2", "arch=x86-64-v3", "arch=x86-64-v4", "default"))) +int +foo () +{ + return 0; +} + +int +main () +{ + return foo (); +} |