* [PATCH] i386: support micro-levels in target{,_clone} attrs [PR101696]
@ 2021-08-12 14:12 Martin Liška
2021-08-12 14:25 ` [PATCH] i386: support micro-levels in target{, _clone} " H.J. Lu
0 siblings, 1 reply; 12+ messages in thread
From: Martin Liška @ 2021-08-12 14:12 UTC (permalink / raw)
To: gcc-patches
Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
I modified the H.J. patch draft.
@H.J. Can you please verify the newly added 'feature_priority'?
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.
Co-Authored-By: H.J. Lu <hjl.tools@gmail.com>
---
gcc/common/config/i386/cpuinfo.h | 38 ++++++++++++++++++++
gcc/common/config/i386/i386-cpuinfo.h | 8 +++++
gcc/common/config/i386/i386-isas.h | 4 +++
gcc/config/i386/i386-builtins.c | 22 ++++++++++--
gcc/doc/extend.texi | 12 +++++++
gcc/testsuite/g++.target/i386/mv30.C | 50 +++++++++++++++++++++++++++
gcc/testsuite/gcc.target/i386/mvc16.c | 15 ++++++++
7 files changed, 146 insertions(+), 3 deletions(-)
create mode 100644 gcc/testsuite/g++.target/i386/mv30.C
create mode 100644 gcc/testsuite/gcc.target/i386/mvc16.c
diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h
index 458f41de776..f3b60920c81 100644
--- a/gcc/common/config/i386/cpuinfo.h
+++ b/gcc/common/config/i386/cpuinfo.h
@@ -931,6 +931,44 @@ 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))
+ {
+ 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))
+ {
+ 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))
+ {
+ 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))
+ 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 e68dd656046..1b1846d59b8 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
};
@@ -228,6 +232,10 @@ enum processor_features
FEATURE_AESKLE,
FEATURE_WIDEKL,
FEATURE_AVXVNNI,
+ 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 898c18f3dda..cd9523b8fbc 100644
--- a/gcc/common/config/i386/i386-isas.h
+++ b/gcc/common/config/i386/i386-isas.h
@@ -169,4 +169,8 @@ ISA_NAMES_TABLE_START
ISA_NAMES_TABLE_ENTRY("aeskle", FEATURE_AESKLE, P_NONE, NULL)
ISA_NAMES_TABLE_ENTRY("widekl", FEATURE_WIDEKL, P_NONE, "-mwidekl")
ISA_NAMES_TABLE_ENTRY("avxvnni", FEATURE_AVXVNNI, P_NONE, "-mavxvnni")
+ ISA_NAMES_TABLE_ENTRY("x86-64", FEATURE_X86_64_BASELINE, P_NONE, NULL)
+ ISA_NAMES_TABLE_ENTRY("x86-64-v2", FEATURE_X86_64_V2, P_NONE, NULL)
+ ISA_NAMES_TABLE_ENTRY("x86-64-v3", FEATURE_X86_64_V3, P_NONE, NULL)
+ ISA_NAMES_TABLE_ENTRY("x86-64-v4", FEATURE_X86_64_V4, P_NONE, NULL)
ISA_NAMES_TABLE_END
diff --git a/gcc/config/i386/i386-builtins.c b/gcc/config/i386/i386-builtins.c
index 204e2903126..492873bb076 100644
--- a/gcc/config/i386/i386-builtins.c
+++ b/gcc/config/i386/i386-builtins.c
@@ -1904,8 +1904,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)
{
@@ -1975,7 +1991,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 49df8e6dc38..d2c695f8dab 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -21644,6 +21644,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 00000000000..b4947f0b481
--- /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/mvc16.c b/gcc/testsuite/gcc.target/i386/mvc16.c
new file mode 100644
index 00000000000..def6581f7e7
--- /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 ();
+}
--
2.32.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] i386: support micro-levels in target{, _clone} attrs [PR101696]
2021-08-12 14:12 [PATCH] i386: support micro-levels in target{,_clone} attrs [PR101696] Martin Liška
@ 2021-08-12 14:25 ` H.J. Lu
2021-08-12 14:39 ` [PATCH] i386: support micro-levels in target{,_clone} " Martin Liška
0 siblings, 1 reply; 12+ messages in thread
From: H.J. Lu @ 2021-08-12 14:25 UTC (permalink / raw)
To: Martin Liška; +Cc: GCC Patches
[-- Attachment #1: Type: text/plain, Size: 11145 bytes --]
On Thu, Aug 12, 2021 at 7:12 AM Martin Liška <mliska@suse.cz> wrote:
>
> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
> I modified the H.J. patch draft.
Please send out the v2 patch with the enclosed patch. I added some tests.
> @H.J. Can you please verify the newly added 'feature_priority'?
>
I will take a look at the v2 patch.
> 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.
>
> Co-Authored-By: H.J. Lu <hjl.tools@gmail.com>
> ---
> gcc/common/config/i386/cpuinfo.h | 38 ++++++++++++++++++++
> gcc/common/config/i386/i386-cpuinfo.h | 8 +++++
> gcc/common/config/i386/i386-isas.h | 4 +++
> gcc/config/i386/i386-builtins.c | 22 ++++++++++--
> gcc/doc/extend.texi | 12 +++++++
> gcc/testsuite/g++.target/i386/mv30.C | 50 +++++++++++++++++++++++++++
> gcc/testsuite/gcc.target/i386/mvc16.c | 15 ++++++++
> 7 files changed, 146 insertions(+), 3 deletions(-)
> create mode 100644 gcc/testsuite/g++.target/i386/mv30.C
> create mode 100644 gcc/testsuite/gcc.target/i386/mvc16.c
>
> diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h
> index 458f41de776..f3b60920c81 100644
> --- a/gcc/common/config/i386/cpuinfo.h
> +++ b/gcc/common/config/i386/cpuinfo.h
> @@ -931,6 +931,44 @@ 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))
> + {
> + 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))
> + {
> + 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))
> + {
> + 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))
> + 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 e68dd656046..1b1846d59b8 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
> };
>
> @@ -228,6 +232,10 @@ enum processor_features
> FEATURE_AESKLE,
> FEATURE_WIDEKL,
> FEATURE_AVXVNNI,
> + 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 898c18f3dda..cd9523b8fbc 100644
> --- a/gcc/common/config/i386/i386-isas.h
> +++ b/gcc/common/config/i386/i386-isas.h
> @@ -169,4 +169,8 @@ ISA_NAMES_TABLE_START
> ISA_NAMES_TABLE_ENTRY("aeskle", FEATURE_AESKLE, P_NONE, NULL)
> ISA_NAMES_TABLE_ENTRY("widekl", FEATURE_WIDEKL, P_NONE, "-mwidekl")
> ISA_NAMES_TABLE_ENTRY("avxvnni", FEATURE_AVXVNNI, P_NONE, "-mavxvnni")
> + ISA_NAMES_TABLE_ENTRY("x86-64", FEATURE_X86_64_BASELINE, P_NONE, NULL)
> + ISA_NAMES_TABLE_ENTRY("x86-64-v2", FEATURE_X86_64_V2, P_NONE, NULL)
> + ISA_NAMES_TABLE_ENTRY("x86-64-v3", FEATURE_X86_64_V3, P_NONE, NULL)
> + ISA_NAMES_TABLE_ENTRY("x86-64-v4", FEATURE_X86_64_V4, P_NONE, NULL)
> ISA_NAMES_TABLE_END
> diff --git a/gcc/config/i386/i386-builtins.c b/gcc/config/i386/i386-builtins.c
> index 204e2903126..492873bb076 100644
> --- a/gcc/config/i386/i386-builtins.c
> +++ b/gcc/config/i386/i386-builtins.c
> @@ -1904,8 +1904,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)
> {
> @@ -1975,7 +1991,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 49df8e6dc38..d2c695f8dab 100644
> --- a/gcc/doc/extend.texi
> +++ b/gcc/doc/extend.texi
> @@ -21644,6 +21644,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 00000000000..b4947f0b481
> --- /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/mvc16.c b/gcc/testsuite/gcc.target/i386/mvc16.c
> new file mode 100644
> index 00000000000..def6581f7e7
> --- /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 ();
> +}
> --
> 2.32.0
>
--
H.J.
[-- Attachment #2: 0001-x86-Update-__builtin_cpu_supports-for-x86-64-x86-64-.patch --]
[-- Type: text/x-patch, Size: 5568 bytes --]
From dca8ac4416c84268202bf108cabfda468247b625 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Wed, 11 Aug 2021 08:06:13 -0700
Subject: [PATCH] x86: Update __builtin_cpu_supports for x86-64/x86-64-v[2-4]
There are no x86-64, x86-64-v2, x86-64-v3 and x86-64-v4 processors. Add
x86-64, x86-64-v2, x86-64-v3 and x86-64-v4 to processor features. Update
__builtin_cpu_supports to support them.
gcc/
PR target/101696
* common/config/i386/cpuinfo.h (CHECK___builtin_cpu_supports):
New.
(cpu_indicator_init): Handle FEATURE_X86_64_BASELINE,
FEATURE_X86_64_V2, FEATURE_X86_64_V3 and FEATURE_X86_64_V4.
* common/config/i386/i386-cpuinfo.h (processor_features): Add
FEATURE_X86_64_BASELINE, FEATURE_X86_64_V2, FEATURE_X86_64_V3
and FEATURE_X86_64_V4.
* common/config/i386/i386-isas.h (isa_names_table): Add
x86-64, x86-64-v2, x86-64-v3 and x86-64-v4.
gcc/testsuite/
PR target/101696
* gcc.target/i386/builtin_target.c (CHECK___builtin_cpu_supports):
New.
---
gcc/common/config/i386/cpuinfo.h | 48 +++++++++++++++++++
gcc/common/config/i386/i386-cpuinfo.h | 4 ++
gcc/common/config/i386/i386-isas.h | 4 ++
.../gcc.target/i386/builtin_target.c | 2 +
4 files changed, 58 insertions(+)
diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h
index 458f41de776..89158597c1f 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
@@ -931,6 +935,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 e68dd656046..1e2e2938460 100644
--- a/gcc/common/config/i386/i386-cpuinfo.h
+++ b/gcc/common/config/i386/i386-cpuinfo.h
@@ -228,6 +228,10 @@ enum processor_features
FEATURE_AESKLE,
FEATURE_WIDEKL,
FEATURE_AVXVNNI,
+ 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 898c18f3dda..cd9523b8fbc 100644
--- a/gcc/common/config/i386/i386-isas.h
+++ b/gcc/common/config/i386/i386-isas.h
@@ -169,4 +169,8 @@ ISA_NAMES_TABLE_START
ISA_NAMES_TABLE_ENTRY("aeskle", FEATURE_AESKLE, P_NONE, NULL)
ISA_NAMES_TABLE_ENTRY("widekl", FEATURE_WIDEKL, P_NONE, "-mwidekl")
ISA_NAMES_TABLE_ENTRY("avxvnni", FEATURE_AVXVNNI, P_NONE, "-mavxvnni")
+ ISA_NAMES_TABLE_ENTRY("x86-64", FEATURE_X86_64_BASELINE, P_NONE, NULL)
+ ISA_NAMES_TABLE_ENTRY("x86-64-v2", FEATURE_X86_64_V2, P_NONE, NULL)
+ ISA_NAMES_TABLE_ENTRY("x86-64-v3", FEATURE_X86_64_V3, P_NONE, NULL)
+ ISA_NAMES_TABLE_ENTRY("x86-64-v4", FEATURE_X86_64_V4, P_NONE, NULL)
ISA_NAMES_TABLE_END
diff --git a/gcc/testsuite/gcc.target/i386/builtin_target.c b/gcc/testsuite/gcc.target/i386/builtin_target.c
index aa9680544d8..3e7505a8c3a 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
--
2.31.1
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] i386: support micro-levels in target{,_clone} attrs [PR101696]
2021-08-12 14:25 ` [PATCH] i386: support micro-levels in target{, _clone} " H.J. Lu
@ 2021-08-12 14:39 ` Martin Liška
2021-08-12 14:51 ` [PATCH] i386: support micro-levels in target{, _clone} " H.J. Lu
0 siblings, 1 reply; 12+ messages in thread
From: Martin Liška @ 2021-08-12 14:39 UTC (permalink / raw)
To: H.J. Lu; +Cc: GCC Patches
[-- Attachment #1: Type: text/plain, Size: 172 bytes --]
On 8/12/21 4:25 PM, H.J. Lu wrote:
> Please send out the v2 patch with the enclosed patch. I added some tests.
Thanks, there's patch which includes your changes.
Martin
[-- Attachment #2: 0001-i386-support-micro-levels-in-target-_clone-attrs-PR1.patch --]
[-- Type: text/x-patch, Size: 10684 bytes --]
From 22ab27eab643d99addd00c11f62eca891e11ac08 Mon Sep 17 00:00:00 2001
From: Martin Liska <mliska@suse.cz>
Date: Thu, 12 Aug 2021 15:20:43 +0200
Subject: [PATCH] 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>
---
gcc/common/config/i386/cpuinfo.h | 48 ++++++++++++++++++
gcc/common/config/i386/i386-cpuinfo.h | 8 +++
gcc/common/config/i386/i386-isas.h | 4 ++
gcc/config/i386/i386-builtins.c | 22 ++++++--
gcc/doc/extend.texi | 12 +++++
gcc/testsuite/g++.target/i386/mv30.C | 50 +++++++++++++++++++
.../gcc.target/i386/builtin_target.c | 2 +
gcc/testsuite/gcc.target/i386/mvc16.c | 15 ++++++
8 files changed, 158 insertions(+), 3 deletions(-)
create mode 100644 gcc/testsuite/g++.target/i386/mv30.C
create mode 100644 gcc/testsuite/gcc.target/i386/mvc16.c
diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h
index 458f41de776..89158597c1f 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
@@ -931,6 +935,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 e68dd656046..1b1846d59b8 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
};
@@ -228,6 +232,10 @@ enum processor_features
FEATURE_AESKLE,
FEATURE_WIDEKL,
FEATURE_AVXVNNI,
+ 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 898c18f3dda..cd9523b8fbc 100644
--- a/gcc/common/config/i386/i386-isas.h
+++ b/gcc/common/config/i386/i386-isas.h
@@ -169,4 +169,8 @@ ISA_NAMES_TABLE_START
ISA_NAMES_TABLE_ENTRY("aeskle", FEATURE_AESKLE, P_NONE, NULL)
ISA_NAMES_TABLE_ENTRY("widekl", FEATURE_WIDEKL, P_NONE, "-mwidekl")
ISA_NAMES_TABLE_ENTRY("avxvnni", FEATURE_AVXVNNI, P_NONE, "-mavxvnni")
+ ISA_NAMES_TABLE_ENTRY("x86-64", FEATURE_X86_64_BASELINE, P_NONE, NULL)
+ ISA_NAMES_TABLE_ENTRY("x86-64-v2", FEATURE_X86_64_V2, P_NONE, NULL)
+ ISA_NAMES_TABLE_ENTRY("x86-64-v3", FEATURE_X86_64_V3, P_NONE, NULL)
+ ISA_NAMES_TABLE_ENTRY("x86-64-v4", FEATURE_X86_64_V4, P_NONE, NULL)
ISA_NAMES_TABLE_END
diff --git a/gcc/config/i386/i386-builtins.c b/gcc/config/i386/i386-builtins.c
index 204e2903126..492873bb076 100644
--- a/gcc/config/i386/i386-builtins.c
+++ b/gcc/config/i386/i386-builtins.c
@@ -1904,8 +1904,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)
{
@@ -1975,7 +1991,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 49df8e6dc38..d2c695f8dab 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -21644,6 +21644,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 00000000000..b4947f0b481
--- /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 aa9680544d8..3e7505a8c3a 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 00000000000..def6581f7e7
--- /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 ();
+}
--
2.32.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] i386: support micro-levels in target{, _clone} attrs [PR101696]
2021-08-12 14:39 ` [PATCH] i386: support micro-levels in target{,_clone} " Martin Liška
@ 2021-08-12 14:51 ` H.J. Lu
2021-08-12 15:22 ` [PATCH] i386: support micro-levels in target{,_clone} " Martin Liška
0 siblings, 1 reply; 12+ messages in thread
From: H.J. Lu @ 2021-08-12 14:51 UTC (permalink / raw)
To: Martin Liška; +Cc: GCC Patches
On Thu, Aug 12, 2021 at 7:39 AM Martin Liška <mliska@suse.cz> wrote:
>
> On 8/12/21 4:25 PM, H.J. Lu wrote:
> > Please send out the v2 patch with the enclosed patch. I added some tests.
>
> Thanks, there's patch which includes your changes.
>
> Martin
diff --git a/gcc/common/config/i386/i386-isas.h
b/gcc/common/config/i386/i386-isas.h
index 898c18f3dda..cd9523b8fbc 100644
--- a/gcc/common/config/i386/i386-isas.h
+++ b/gcc/common/config/i386/i386-isas.h
@@ -169,4 +169,8 @@ ISA_NAMES_TABLE_START
ISA_NAMES_TABLE_ENTRY("aeskle", FEATURE_AESKLE, P_NONE, NULL)
ISA_NAMES_TABLE_ENTRY("widekl", FEATURE_WIDEKL, P_NONE, "-mwidekl")
ISA_NAMES_TABLE_ENTRY("avxvnni", FEATURE_AVXVNNI, P_NONE, "-mavxvnni")
+ ISA_NAMES_TABLE_ENTRY("x86-64", FEATURE_X86_64_BASELINE, P_NONE, NULL)
+ ISA_NAMES_TABLE_ENTRY("x86-64-v2", FEATURE_X86_64_V2, P_NONE, NULL)
+ ISA_NAMES_TABLE_ENTRY("x86-64-v3", FEATURE_X86_64_V3, P_NONE, NULL)
+ ISA_NAMES_TABLE_ENTRY("x86-64-v4", FEATURE_X86_64_V4, P_NONE, NULL)
If they have proper feature_priority, can you avoid
iff --git a/gcc/config/i386/i386-builtins.c b/gcc/config/i386/i386-builtins.c
index 204e2903126..492873bb076 100644
--- a/gcc/config/i386/i386-builtins.c
+++ b/gcc/config/i386/i386-builtins.c
@@ -1904,8 +1904,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;
+ }
if (predicate_list)
{
- predicate_decl = ix86_builtins [(int) IX86_BUILTIN_CPU_IS];
+ predicate_decl = ix86_builtins [(int) builtin_fn];
Is this required?
--
H.J.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] i386: support micro-levels in target{,_clone} attrs [PR101696]
2021-08-12 14:51 ` [PATCH] i386: support micro-levels in target{, _clone} " H.J. Lu
@ 2021-08-12 15:22 ` Martin Liška
2021-08-12 15:26 ` [PATCH] i386: support micro-levels in target{, _clone} " H.J. Lu
0 siblings, 1 reply; 12+ messages in thread
From: Martin Liška @ 2021-08-12 15:22 UTC (permalink / raw)
To: H.J. Lu; +Cc: GCC Patches
On 8/12/21 4:51 PM, H.J. Lu wrote:
> On Thu, Aug 12, 2021 at 7:39 AM Martin Liška <mliska@suse.cz> wrote:
>>
>> On 8/12/21 4:25 PM, H.J. Lu wrote:
>>> Please send out the v2 patch with the enclosed patch. I added some tests.
>>
>> Thanks, there's patch which includes your changes.
>>
>> Martin
>
> diff --git a/gcc/common/config/i386/i386-isas.h
> b/gcc/common/config/i386/i386-isas.h
> index 898c18f3dda..cd9523b8fbc 100644
> --- a/gcc/common/config/i386/i386-isas.h
> +++ b/gcc/common/config/i386/i386-isas.h
> @@ -169,4 +169,8 @@ ISA_NAMES_TABLE_START
> ISA_NAMES_TABLE_ENTRY("aeskle", FEATURE_AESKLE, P_NONE, NULL)
> ISA_NAMES_TABLE_ENTRY("widekl", FEATURE_WIDEKL, P_NONE, "-mwidekl")
> ISA_NAMES_TABLE_ENTRY("avxvnni", FEATURE_AVXVNNI, P_NONE, "-mavxvnni")
> + ISA_NAMES_TABLE_ENTRY("x86-64", FEATURE_X86_64_BASELINE, P_NONE, NULL)
> + ISA_NAMES_TABLE_ENTRY("x86-64-v2", FEATURE_X86_64_V2, P_NONE, NULL)
> + ISA_NAMES_TABLE_ENTRY("x86-64-v3", FEATURE_X86_64_V3, P_NONE, NULL)
> + ISA_NAMES_TABLE_ENTRY("x86-64-v4", FEATURE_X86_64_V4, P_NONE, NULL)
>
> If they have proper feature_priority, can you avoid
I don't think so. First we likely want supporting "arch=x86-64-v3" rather than
"x86-64-v3" in e.g. 'target' attribute. That means a special handling by the code
I added.
The following fails as there's no corresponding -m$option.
pr101696.c:5:45: error: attribute ‘x86-64-v4’ argument ‘target’ is unknown
5 | __attribute__ ((target ("x86-64-v4"))) void foo () { __builtin_printf ("arch=x86-64-v4\n"); }
| ^~~
Or do I miss something and we can do it in a simpler way?
Cheers,
Martin
>
> iff --git a/gcc/config/i386/i386-builtins.c b/gcc/config/i386/i386-builtins.c
> index 204e2903126..492873bb076 100644
> --- a/gcc/config/i386/i386-builtins.c
> +++ b/gcc/config/i386/i386-builtins.c
> @@ -1904,8 +1904,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;
> + }
>
> if (predicate_list)
> {
> - predicate_decl = ix86_builtins [(int) IX86_BUILTIN_CPU_IS];
> + predicate_decl = ix86_builtins [(int) builtin_fn];
>
> Is this required?
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] i386: support micro-levels in target{, _clone} attrs [PR101696]
2021-08-12 15:22 ` [PATCH] i386: support micro-levels in target{,_clone} " Martin Liška
@ 2021-08-12 15:26 ` H.J. Lu
2021-08-12 15:31 ` [PATCH] i386: support micro-levels in target{,_clone} " Martin Liška
0 siblings, 1 reply; 12+ messages in thread
From: H.J. Lu @ 2021-08-12 15:26 UTC (permalink / raw)
To: Martin Liška; +Cc: GCC Patches
On Thu, Aug 12, 2021 at 8:22 AM Martin Liška <mliska@suse.cz> wrote:
>
> On 8/12/21 4:51 PM, H.J. Lu wrote:
> > On Thu, Aug 12, 2021 at 7:39 AM Martin Liška <mliska@suse.cz> wrote:
> >>
> >> On 8/12/21 4:25 PM, H.J. Lu wrote:
> >>> Please send out the v2 patch with the enclosed patch. I added some tests.
> >>
> >> Thanks, there's patch which includes your changes.
> >>
> >> Martin
> >
> > diff --git a/gcc/common/config/i386/i386-isas.h
> > b/gcc/common/config/i386/i386-isas.h
> > index 898c18f3dda..cd9523b8fbc 100644
> > --- a/gcc/common/config/i386/i386-isas.h
> > +++ b/gcc/common/config/i386/i386-isas.h
> > @@ -169,4 +169,8 @@ ISA_NAMES_TABLE_START
> > ISA_NAMES_TABLE_ENTRY("aeskle", FEATURE_AESKLE, P_NONE, NULL)
> > ISA_NAMES_TABLE_ENTRY("widekl", FEATURE_WIDEKL, P_NONE, "-mwidekl")
> > ISA_NAMES_TABLE_ENTRY("avxvnni", FEATURE_AVXVNNI, P_NONE, "-mavxvnni")
> > + ISA_NAMES_TABLE_ENTRY("x86-64", FEATURE_X86_64_BASELINE, P_NONE, NULL)
> > + ISA_NAMES_TABLE_ENTRY("x86-64-v2", FEATURE_X86_64_V2, P_NONE, NULL)
> > + ISA_NAMES_TABLE_ENTRY("x86-64-v3", FEATURE_X86_64_V3, P_NONE, NULL)
> > + ISA_NAMES_TABLE_ENTRY("x86-64-v4", FEATURE_X86_64_V4, P_NONE, NULL)
> >
> > If they have proper feature_priority, can you avoid
>
> I don't think so. First we likely want supporting "arch=x86-64-v3" rather than
> "x86-64-v3" in e.g. 'target' attribute. That means a special handling by the code
> I added.
Will it hurt if they have proper feature_priorities you added?
> The following fails as there's no corresponding -m$option.
>
> pr101696.c:5:45: error: attribute ‘x86-64-v4’ argument ‘target’ is unknown
>
> 5 | __attribute__ ((target ("x86-64-v4"))) void foo () { __builtin_printf ("arch=x86-64-v4\n"); }
>
> | ^~~
>
>
> Or do I miss something and we can do it in a simpler way?
>
> Cheers,
> Martin
>
> >
> > iff --git a/gcc/config/i386/i386-builtins.c b/gcc/config/i386/i386-builtins.c
> > index 204e2903126..492873bb076 100644
> > --- a/gcc/config/i386/i386-builtins.c
> > +++ b/gcc/config/i386/i386-builtins.c
> > @@ -1904,8 +1904,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;
> > + }
> >
> > if (predicate_list)
> > {
> > - predicate_decl = ix86_builtins [(int) IX86_BUILTIN_CPU_IS];
> > + predicate_decl = ix86_builtins [(int) builtin_fn];
> >
> > Is this required?
> >
>
--
H.J.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] i386: support micro-levels in target{,_clone} attrs [PR101696]
2021-08-12 15:26 ` [PATCH] i386: support micro-levels in target{, _clone} " H.J. Lu
@ 2021-08-12 15:31 ` Martin Liška
2021-08-12 17:35 ` [PATCH] i386: support micro-levels in target{, _clone} " H.J. Lu
2021-09-13 14:36 ` [PATCH] i386: support micro-levels in target{, _clone} " Uros Bizjak
0 siblings, 2 replies; 12+ messages in thread
From: Martin Liška @ 2021-08-12 15:31 UTC (permalink / raw)
To: H.J. Lu; +Cc: GCC Patches
[-- Attachment #1: Type: text/plain, Size: 170 bytes --]
On 8/12/21 5:26 PM, H.J. Lu wrote:
> Will it hurt if they have proper feature_priorities you added?
No. They are unused, by we should use the proper priorities.
Martin
[-- Attachment #2: 0001-i386-support-micro-levels-in-target-_clone-attrs-PR1.patch --]
[-- Type: text/x-patch, Size: 10714 bytes --]
From 5a2f40394390f8bfca0724d6e371b5105d01c027 Mon Sep 17 00:00:00 2001
From: Martin Liska <mliska@suse.cz>
Date: Thu, 12 Aug 2021 15:20:43 +0200
Subject: [PATCH] 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>
---
gcc/common/config/i386/cpuinfo.h | 48 ++++++++++++++++++
gcc/common/config/i386/i386-cpuinfo.h | 8 +++
gcc/common/config/i386/i386-isas.h | 5 ++
gcc/config/i386/i386-builtins.c | 22 ++++++--
gcc/doc/extend.texi | 12 +++++
gcc/testsuite/g++.target/i386/mv30.C | 50 +++++++++++++++++++
.../gcc.target/i386/builtin_target.c | 2 +
gcc/testsuite/gcc.target/i386/mvc16.c | 15 ++++++
8 files changed, 159 insertions(+), 3 deletions(-)
create mode 100644 gcc/testsuite/g++.target/i386/mv30.C
create mode 100644 gcc/testsuite/gcc.target/i386/mvc16.c
diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h
index 458f41de776..89158597c1f 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
@@ -931,6 +935,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 e68dd656046..1b1846d59b8 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
};
@@ -228,6 +232,10 @@ enum processor_features
FEATURE_AESKLE,
FEATURE_WIDEKL,
FEATURE_AVXVNNI,
+ 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 898c18f3dda..1cc87a5aaf1 100644
--- a/gcc/common/config/i386/i386-isas.h
+++ b/gcc/common/config/i386/i386-isas.h
@@ -169,4 +169,9 @@ ISA_NAMES_TABLE_START
ISA_NAMES_TABLE_ENTRY("aeskle", FEATURE_AESKLE, P_NONE, NULL)
ISA_NAMES_TABLE_ENTRY("widekl", FEATURE_WIDEKL, P_NONE, "-mwidekl")
ISA_NAMES_TABLE_ENTRY("avxvnni", FEATURE_AVXVNNI, P_NONE, "-mavxvnni")
+ 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 204e2903126..492873bb076 100644
--- a/gcc/config/i386/i386-builtins.c
+++ b/gcc/config/i386/i386-builtins.c
@@ -1904,8 +1904,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)
{
@@ -1975,7 +1991,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 49df8e6dc38..d2c695f8dab 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -21644,6 +21644,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 00000000000..b4947f0b481
--- /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 aa9680544d8..3e7505a8c3a 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 00000000000..def6581f7e7
--- /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 ();
+}
--
2.32.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] i386: support micro-levels in target{, _clone} attrs [PR101696]
2021-08-12 15:31 ` [PATCH] i386: support micro-levels in target{,_clone} " Martin Liška
@ 2021-08-12 17:35 ` H.J. Lu
2021-08-13 8:10 ` [PATCH] i386: support micro-levels in target{,_clone} " Martin Liška
2021-09-13 14:36 ` [PATCH] i386: support micro-levels in target{, _clone} " Uros Bizjak
1 sibling, 1 reply; 12+ messages in thread
From: H.J. Lu @ 2021-08-12 17:35 UTC (permalink / raw)
To: Martin Liška; +Cc: GCC Patches
On Thu, Aug 12, 2021 at 8:31 AM Martin Liška <mliska@suse.cz> wrote:
>
> On 8/12/21 5:26 PM, H.J. Lu wrote:
> > Will it hurt if they have proper feature_priorities you added?
>
> No. They are unused, by we should use the proper priorities.
>
> Martin
+ 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;
What happens for arch=x86-64-v5?
+ }
--
H.J.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] i386: support micro-levels in target{,_clone} attrs [PR101696]
2021-08-12 17:35 ` [PATCH] i386: support micro-levels in target{, _clone} " H.J. Lu
@ 2021-08-13 8:10 ` Martin Liška
2021-08-13 13:41 ` [PATCH] i386: support micro-levels in target{, _clone} " H.J. Lu
0 siblings, 1 reply; 12+ messages in thread
From: Martin Liška @ 2021-08-13 8:10 UTC (permalink / raw)
To: H.J. Lu; +Cc: GCC Patches
On 8/12/21 7:35 PM, H.J. Lu wrote:
> What happens for arch=x86-64-v5?
pr101696.c:5:55: error: bad value (‘x86-64-v5’) for ‘target("arch=")’ attribute
5 | __attribute__ ((target ("arch=x86-64-v5"))) void foo () { __builtin_printf ("arch=x86-64-v4\n"); }
| ^
pr101696.c:5:55: note: valid arguments to ‘target("arch=")’ attribute are: nocona core2 nehalem corei7 westmere sandybridge corei7-avx ivybridge core-avx-i haswell core-avx2 broadwell skylake skylake-avx512 cannonlake icelake-client rocketlake icelake-server cascadelake tigerlake cooperlake sapphirerapids alderlake bonnell atom silvermont slm goldmont goldmont-plus tremont knl knm x86-64 x86-64-v2 x86-64-v3 x86-64-v4 eden-x2 nano nano-1000 nano-2000 nano-3000 nano-x2 eden-x4 nano-x4 k8 k8-sse3 opteron opteron-sse3 athlon64 athlon64-sse3 athlon-fx amdfam10 barcelona bdver1 bdver2 bdver3 bdver4 znver1 znver2 znver3 btver1 btver2 native; did you mean ‘x86-64-v2’?
Which seems to me a reasonable error message.
Martin
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] i386: support micro-levels in target{, _clone} attrs [PR101696]
2021-08-13 8:10 ` [PATCH] i386: support micro-levels in target{,_clone} " Martin Liška
@ 2021-08-13 13:41 ` H.J. Lu
2021-09-13 13:28 ` [PATCH] i386: support micro-levels in target{,_clone} " Martin Liška
0 siblings, 1 reply; 12+ messages in thread
From: H.J. Lu @ 2021-08-13 13:41 UTC (permalink / raw)
To: Martin Liška; +Cc: GCC Patches
On Fri, Aug 13, 2021 at 1:10 AM Martin Liška <mliska@suse.cz> wrote:
>
> On 8/12/21 7:35 PM, H.J. Lu wrote:
> > What happens for arch=x86-64-v5?
>
> pr101696.c:5:55: error: bad value (‘x86-64-v5’) for ‘target("arch=")’ attribute
>
> 5 | __attribute__ ((target ("arch=x86-64-v5"))) void foo () { __builtin_printf ("arch=x86-64-v4\n"); }
>
> | ^
>
> pr101696.c:5:55: note: valid arguments to ‘target("arch=")’ attribute are: nocona core2 nehalem corei7 westmere sandybridge corei7-avx ivybridge core-avx-i haswell core-avx2 broadwell skylake skylake-avx512 cannonlake icelake-client rocketlake icelake-server cascadelake tigerlake cooperlake sapphirerapids alderlake bonnell atom silvermont slm goldmont goldmont-plus tremont knl knm x86-64 x86-64-v2 x86-64-v3 x86-64-v4 eden-x2 nano nano-1000 nano-2000 nano-3000 nano-x2 eden-x4 nano-x4 k8 k8-sse3 opteron opteron-sse3 athlon64 athlon64-sse3 athlon-fx amdfam10 barcelona bdver1 bdver2 bdver3 bdver4 znver1 znver2 znver3 btver1 btver2 native; did you mean ‘x86-64-v2’?
>
>
> Which seems to me a reasonable error message.
>
The patch looks good to me.
Thanks.
--
H.J.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] i386: support micro-levels in target{,_clone} attrs [PR101696]
2021-08-13 13:41 ` [PATCH] i386: support micro-levels in target{, _clone} " H.J. Lu
@ 2021-09-13 13:28 ` Martin Liška
0 siblings, 0 replies; 12+ messages in thread
From: Martin Liška @ 2021-09-13 13:28 UTC (permalink / raw)
To: H.J. Lu; +Cc: GCC Patches
PING^1
On 8/13/21 15:41, H.J. Lu wrote:
> On Fri, Aug 13, 2021 at 1:10 AM Martin Liška <mliska@suse.cz> wrote:
>>
>> On 8/12/21 7:35 PM, H.J. Lu wrote:
>>> What happens for arch=x86-64-v5?
>>
>> pr101696.c:5:55: error: bad value (‘x86-64-v5’) for ‘target("arch=")’ attribute
>>
>> 5 | __attribute__ ((target ("arch=x86-64-v5"))) void foo () { __builtin_printf ("arch=x86-64-v4\n"); }
>>
>> | ^
>>
>> pr101696.c:5:55: note: valid arguments to ‘target("arch=")’ attribute are: nocona core2 nehalem corei7 westmere sandybridge corei7-avx ivybridge core-avx-i haswell core-avx2 broadwell skylake skylake-avx512 cannonlake icelake-client rocketlake icelake-server cascadelake tigerlake cooperlake sapphirerapids alderlake bonnell atom silvermont slm goldmont goldmont-plus tremont knl knm x86-64 x86-64-v2 x86-64-v3 x86-64-v4 eden-x2 nano nano-1000 nano-2000 nano-3000 nano-x2 eden-x4 nano-x4 k8 k8-sse3 opteron opteron-sse3 athlon64 athlon64-sse3 athlon-fx amdfam10 barcelona bdver1 bdver2 bdver3 bdver4 znver1 znver2 znver3 btver1 btver2 native; did you mean ‘x86-64-v2’?
>>
>>
>> Which seems to me a reasonable error message.
>>
>
> The patch looks good to me.
>
> Thanks.
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] i386: support micro-levels in target{, _clone} attrs [PR101696]
2021-08-12 15:31 ` [PATCH] i386: support micro-levels in target{,_clone} " Martin Liška
2021-08-12 17:35 ` [PATCH] i386: support micro-levels in target{, _clone} " H.J. Lu
@ 2021-09-13 14:36 ` Uros Bizjak
1 sibling, 0 replies; 12+ messages in thread
From: Uros Bizjak @ 2021-09-13 14:36 UTC (permalink / raw)
To: Martin Liška; +Cc: H.J. Lu, GCC Patches
On Thu, Aug 12, 2021 at 5:32 PM Martin Liška <mliska@suse.cz> wrote:
>
> On 8/12/21 5:26 PM, H.J. Lu wrote:
> > Will it hurt if they have proper feature_priorities you added?
>
> No. They are unused, by we should use the proper priorities.
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.
OK.
Thanks,
Uros.
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2021-09-13 14:37 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-12 14:12 [PATCH] i386: support micro-levels in target{,_clone} attrs [PR101696] Martin Liška
2021-08-12 14:25 ` [PATCH] i386: support micro-levels in target{, _clone} " H.J. Lu
2021-08-12 14:39 ` [PATCH] i386: support micro-levels in target{,_clone} " Martin Liška
2021-08-12 14:51 ` [PATCH] i386: support micro-levels in target{, _clone} " H.J. Lu
2021-08-12 15:22 ` [PATCH] i386: support micro-levels in target{,_clone} " Martin Liška
2021-08-12 15:26 ` [PATCH] i386: support micro-levels in target{, _clone} " H.J. Lu
2021-08-12 15:31 ` [PATCH] i386: support micro-levels in target{,_clone} " Martin Liška
2021-08-12 17:35 ` [PATCH] i386: support micro-levels in target{, _clone} " H.J. Lu
2021-08-13 8:10 ` [PATCH] i386: support micro-levels in target{,_clone} " Martin Liška
2021-08-13 13:41 ` [PATCH] i386: support micro-levels in target{, _clone} " H.J. Lu
2021-09-13 13:28 ` [PATCH] i386: support micro-levels in target{,_clone} " Martin Liška
2021-09-13 14:36 ` [PATCH] i386: support micro-levels in target{, _clone} " Uros Bizjak
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).