public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/marxin/heads/PR101696-x86-64-micro-archs-v2)] i386: support micro-levels in target{, _clone} attrs [PR101696]
@ 2021-08-12 15:30 Martin Liska
  0 siblings, 0 replies; 2+ messages in thread
From: Martin Liska @ 2021-08-12 15:30 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:5a2f40394390f8bfca0724d6e371b5105d01c027

commit 5a2f40394390f8bfca0724d6e371b5105d01c027
Author: Martin Liska <mliska@suse.cz>
Date:   Thu Aug 12 15:20:43 2021 +0200

    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>

Diff:
---
 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/testsuite/gcc.target/i386/builtin_target.c |  2 ++
 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 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 ();
+}


^ permalink raw reply	[flat|nested] 2+ messages in thread

* [gcc(refs/users/marxin/heads/PR101696-x86-64-micro-archs-v2)] i386: support micro-levels in target{, _clone} attrs [PR101696]
@ 2021-08-12 14:33 Martin Liska
  0 siblings, 0 replies; 2+ messages in thread
From: Martin Liska @ 2021-08-12 14:33 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:22ab27eab643d99addd00c11f62eca891e11ac08

commit 22ab27eab643d99addd00c11f62eca891e11ac08
Author: Martin Liska <mliska@suse.cz>
Date:   Thu Aug 12 15:20:43 2021 +0200

    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>

Diff:
---
 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/testsuite/gcc.target/i386/builtin_target.c |  2 ++
 gcc/testsuite/gcc.target/i386/mvc16.c          | 15 ++++++++
 8 files changed, 158 insertions(+), 3 deletions(-)

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 ();
+}


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-08-12 15:30 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-12 15:30 [gcc(refs/users/marxin/heads/PR101696-x86-64-micro-archs-v2)] i386: support micro-levels in target{, _clone} attrs [PR101696] Martin Liska
  -- strict thread matches above, loose matches on Subject: below --
2021-08-12 14:33 Martin Liska

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).