[v2] Add error message for target_clones and AVX512 ISAs (PR target/89929).

Message ID cdd34d5d-7b96-e056-0a11-a48477bddf66@suse.cz
State New
Headers show
Series
  • [v2] Add error message for target_clones and AVX512 ISAs (PR target/89929).
Related show

Commit Message

Martin Liška April 18, 2019, 11:07 a.m.
Hi.

I'm sending updated version of that patch. The patch rejects usage of AVX512 ISAs (except AVX512F)
for target attribute for C++ multiversioning and for target_clone attribute.

Patch can bootstrap on x86_64-linux-gnu and survives regression tests.

Ready to be installed?
Thanks,
Martin

Comments

H.J. Lu April 18, 2019, 5:44 p.m. | #1
On Thu, Apr 18, 2019 at 4:07 AM Martin Liška <mliska@suse.cz> wrote:
>

> Hi.

>

> I'm sending updated version of that patch. The patch rejects usage of AVX512 ISAs (except AVX512F)

> for target attribute for C++ multiversioning and for target_clone attribute.

>

> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.

>

> Ready to be installed?

> Thanks,

> Martin


Your patch doesn't handle cmov nor gfni properly, which aren't AVX512.
I prefer this patch.

-- 
H.J.
From 6089577be432bdd22fc89bf40e363c4af6876987 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Thu, 18 Apr 2019 09:49:58 -0700
Subject: [PATCH] x86: Update message for target_clones and unsupported ISAs

Before AVX512F, processors with the newer ISAs also support the older
ISAs, i.e., AVX2 processors also support AVX and SSE4, SSE4 processors
also support SSSE3, ...   After AVX512F, an AVX512XX processor may not
support AVX512YY.  It means AVX512XX features, except for AVX512F, can't
be used to decide priority in target_clones.

This patch updates error message for ISAs with P_ZERO priority.  It also
merges _feature_list into _isa_names_table and marks ISAs, which have
unknown priority, with P_ZERO so that we only need to update one place
to add a new ISA feature.

gcc/

2019-04-18  H.J. Lu  <hongjiu.lu@intel.com>

	PR target/89929
	* config/i386/i386.c (feature_priority): Moved to file scope.
	(processor_features): Likewise.
	(processor_model): Likewise.
	(_arch_names_table): Likewise.
	(arch_names_table): Likewise.
	(_feature_list): Removed.
	(feature_list): Likewise.
	(_isa_names_table): Moved to file scope.  Add priority.
	(isa_names_table): Likewise.
	(get_builtin_code_for_version): Replace feature_list with
	isa_names_table.  Update error message for P_ZERO priority.

gcc/testsuite/

2019-04-18  Martin Liska  <mliska@suse.cz>

	PR target/89929
	* g++.target/i386/mv28.C: New test.
	* gcc.target/i386/mvc14.c: New test.
---
 gcc/config/i386/i386.c                | 490 ++++++++++++--------------
 gcc/testsuite/g++.target/i386/mv28.C  |  26 ++
 gcc/testsuite/gcc.target/i386/mvc14.c |  16 +
 3 files changed, 274 insertions(+), 258 deletions(-)
 create mode 100644 gcc/testsuite/g++.target/i386/mv28.C
 create mode 100644 gcc/testsuite/gcc.target/i386/mvc14.c

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 498a35d8aea..198af816f74 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -31832,6 +31832,229 @@ add_condition_to_bb (tree function_decl, tree version_decl,
   return bb3;
 }
 
+/* Priority of i386 features, greater value is higher priority.   This is
+   used to decide the order in which function dispatch must happen.  For
+   instance, a version specialized for SSE4.2 should be checked for dispatch
+   before a version for SSE3, as SSE4.2 implies SSE3.  */
+enum feature_priority
+{
+  P_ZERO = 0,
+  P_MMX,
+  P_SSE,
+  P_SSE2,
+  P_SSE3,
+  P_SSSE3,
+  P_PROC_SSSE3,
+  P_SSE4_A,
+  P_PROC_SSE4_A,
+  P_SSE4_1,
+  P_SSE4_2,
+  P_PROC_SSE4_2,
+  P_POPCNT,
+  P_AES,
+  P_PCLMUL,
+  P_AVX,
+  P_PROC_AVX,
+  P_BMI,
+  P_PROC_BMI,
+  P_FMA4,
+  P_XOP,
+  P_PROC_XOP,
+  P_FMA,
+  P_PROC_FMA,
+  P_BMI2,
+  P_AVX2,
+  P_PROC_AVX2,
+  P_AVX512F,
+  P_PROC_AVX512F
+};
+
+/* This is the order of bit-fields in __processor_features in cpuinfo.c */
+enum processor_features
+{
+  F_CMOV = 0,
+  F_MMX,
+  F_POPCNT,
+  F_SSE,
+  F_SSE2,
+  F_SSE3,
+  F_SSSE3,
+  F_SSE4_1,
+  F_SSE4_2,
+  F_AVX,
+  F_AVX2,
+  F_SSE4_A,
+  F_FMA4,
+  F_XOP,
+  F_FMA,
+  F_AVX512F,
+  F_BMI,
+  F_BMI2,
+  F_AES,
+  F_PCLMUL,
+  F_AVX512VL,
+  F_AVX512BW,
+  F_AVX512DQ,
+  F_AVX512CD,
+  F_AVX512ER,
+  F_AVX512PF,
+  F_AVX512VBMI,
+  F_AVX512IFMA,
+  F_AVX5124VNNIW,
+  F_AVX5124FMAPS,
+  F_AVX512VPOPCNTDQ,
+  F_AVX512VBMI2,
+  F_GFNI,
+  F_VPCLMULQDQ,
+  F_AVX512VNNI,
+  F_AVX512BITALG,
+  F_MAX
+};
+
+/* These are the values for vendor types and cpu types  and subtypes
+   in cpuinfo.c.  Cpu types and subtypes should be subtracted by
+   the corresponding start value.  */
+enum processor_model
+{
+  M_INTEL = 1,
+  M_AMD,
+  M_CPU_TYPE_START,
+  M_INTEL_BONNELL,
+  M_INTEL_CORE2,
+  M_INTEL_COREI7,
+  M_AMDFAM10H,
+  M_AMDFAM15H,
+  M_INTEL_SILVERMONT,
+  M_INTEL_KNL,
+  M_AMD_BTVER1,
+  M_AMD_BTVER2,
+  M_AMDFAM17H,
+  M_INTEL_KNM,
+  M_INTEL_GOLDMONT,
+  M_INTEL_GOLDMONT_PLUS,
+  M_INTEL_TREMONT,
+  M_CPU_SUBTYPE_START,
+  M_INTEL_COREI7_NEHALEM,
+  M_INTEL_COREI7_WESTMERE,
+  M_INTEL_COREI7_SANDYBRIDGE,
+  M_AMDFAM10H_BARCELONA,
+  M_AMDFAM10H_SHANGHAI,
+  M_AMDFAM10H_ISTANBUL,
+  M_AMDFAM15H_BDVER1,
+  M_AMDFAM15H_BDVER2,
+  M_AMDFAM15H_BDVER3,
+  M_AMDFAM15H_BDVER4,
+  M_AMDFAM17H_ZNVER1,
+  M_INTEL_COREI7_IVYBRIDGE,
+  M_INTEL_COREI7_HASWELL,
+  M_INTEL_COREI7_BROADWELL,
+  M_INTEL_COREI7_SKYLAKE,
+  M_INTEL_COREI7_SKYLAKE_AVX512,
+  M_INTEL_COREI7_CANNONLAKE,
+  M_INTEL_COREI7_ICELAKE_CLIENT,
+  M_INTEL_COREI7_ICELAKE_SERVER,
+  M_AMDFAM17H_ZNVER2,
+  M_INTEL_COREI7_CASCADELAKE
+};
+
+struct _arch_names_table
+{
+  const char *const name;
+  const enum processor_model model;
+};
+
+static const _arch_names_table arch_names_table[] =
+{
+  {"amd", M_AMD},
+  {"intel", M_INTEL},
+  {"atom", M_INTEL_BONNELL},
+  {"slm", M_INTEL_SILVERMONT},
+  {"core2", M_INTEL_CORE2},
+  {"corei7", M_INTEL_COREI7},
+  {"nehalem", M_INTEL_COREI7_NEHALEM},
+  {"westmere", M_INTEL_COREI7_WESTMERE},
+  {"sandybridge", M_INTEL_COREI7_SANDYBRIDGE},
+  {"ivybridge", M_INTEL_COREI7_IVYBRIDGE},
+  {"haswell", M_INTEL_COREI7_HASWELL},
+  {"broadwell", M_INTEL_COREI7_BROADWELL},
+  {"skylake", M_INTEL_COREI7_SKYLAKE},
+  {"skylake-avx512", M_INTEL_COREI7_SKYLAKE_AVX512},
+  {"cannonlake", M_INTEL_COREI7_CANNONLAKE},
+  {"icelake-client", M_INTEL_COREI7_ICELAKE_CLIENT},
+  {"icelake-server", M_INTEL_COREI7_ICELAKE_SERVER},
+  {"cascadelake", M_INTEL_COREI7_CASCADELAKE},
+  {"bonnell", M_INTEL_BONNELL},
+  {"silvermont", M_INTEL_SILVERMONT},
+  {"goldmont", M_INTEL_GOLDMONT},
+  {"goldmont-plus", M_INTEL_GOLDMONT_PLUS},
+  {"tremont", M_INTEL_TREMONT},
+  {"knl", M_INTEL_KNL},
+  {"knm", M_INTEL_KNM},
+  {"amdfam10h", M_AMDFAM10H},
+  {"barcelona", M_AMDFAM10H_BARCELONA},
+  {"shanghai", M_AMDFAM10H_SHANGHAI},
+  {"istanbul", M_AMDFAM10H_ISTANBUL},
+  {"btver1", M_AMD_BTVER1},
+  {"amdfam15h", M_AMDFAM15H},
+  {"bdver1", M_AMDFAM15H_BDVER1},
+  {"bdver2", M_AMDFAM15H_BDVER2},
+  {"bdver3", M_AMDFAM15H_BDVER3},
+  {"bdver4", M_AMDFAM15H_BDVER4},
+  {"btver2", M_AMD_BTVER2},
+  {"amdfam17h", M_AMDFAM17H},
+  {"znver1", M_AMDFAM17H_ZNVER1},
+  {"znver2", M_AMDFAM17H_ZNVER2},
+};
+
+/* These are the target attribute strings for which a dispatcher is
+   available, from fold_builtin_cpu.  */
+struct _isa_names_table
+{
+  const char *const name;
+  const enum processor_features feature;
+  const enum feature_priority priority;
+};
+
+static const _isa_names_table isa_names_table[] =
+{
+  {"cmov",    F_CMOV,	P_ZERO},
+  {"mmx",     F_MMX,	P_MMX},
+  {"popcnt",  F_POPCNT,	P_POPCNT},
+  {"sse",     F_SSE,	P_SSE},
+  {"sse2",    F_SSE2,	P_SSE2},
+  {"sse3",    F_SSE3,	P_SSE3},
+  {"ssse3",   F_SSSE3,	P_SSSE3},
+  {"sse4a",   F_SSE4_A,	P_SSE4_A},
+  {"sse4.1",  F_SSE4_1,	P_SSE4_1},
+  {"sse4.2",  F_SSE4_2,	P_SSE4_2},
+  {"avx",     F_AVX,	P_AVX},
+  {"fma4",    F_FMA4,	P_FMA4},
+  {"xop",     F_XOP,	P_XOP},
+  {"fma",     F_FMA,	P_FMA},
+  {"avx2",    F_AVX2,	P_AVX2},
+  {"avx512f", F_AVX512F, P_AVX512F},
+  {"bmi",     F_BMI,	P_BMI},
+  {"bmi2",    F_BMI2,	P_BMI2},
+  {"aes",     F_AES,	P_AES},
+  {"pclmul",  F_PCLMUL,	P_PCLMUL},
+  {"avx512vl",F_AVX512VL, P_ZERO},
+  {"avx512bw",F_AVX512BW, P_ZERO},
+  {"avx512dq",F_AVX512DQ, P_ZERO},
+  {"avx512cd",F_AVX512CD, P_ZERO},
+  {"avx512er",F_AVX512ER, P_ZERO},
+  {"avx512pf",F_AVX512PF, P_ZERO},
+  {"avx512vbmi",F_AVX512VBMI, P_ZERO},
+  {"avx512ifma",F_AVX512IFMA, P_ZERO},
+  {"avx5124vnniw",F_AVX5124VNNIW, P_ZERO},
+  {"avx5124fmaps",F_AVX5124FMAPS, P_ZERO},
+  {"avx512vpopcntdq",F_AVX512VPOPCNTDQ,	P_ZERO},
+  {"avx512vbmi2", F_AVX512VBMI2, P_ZERO},
+  {"gfni",	F_GFNI,	P_ZERO},
+  {"vpclmulqdq", F_VPCLMULQDQ, P_ZERO},
+  {"avx512vnni", F_AVX512VNNI, P_ZERO},
+  {"avx512bitalg", F_AVX512BITALG, P_ZERO}
+};
+
 /* This parses the attribute arguments to target in DECL and determines
    the right builtin to use to match the platform specification.
    It returns the priority value for this version decl.  If PREDICATE_LIST
@@ -31850,79 +32073,10 @@ get_builtin_code_for_version (tree decl, tree *predicate_list)
   char *tok_str = NULL;
   char *token;
 
-  /* Priority of i386 features, greater value is higher priority.   This is
-     used to decide the order in which function dispatch must happen.  For
-     instance, a version specialized for SSE4.2 should be checked for dispatch
-     before a version for SSE3, as SSE4.2 implies SSE3.  */
-  enum feature_priority
-  {
-    P_ZERO = 0,
-    P_MMX,
-    P_SSE,
-    P_SSE2,
-    P_SSE3,
-    P_SSSE3,
-    P_PROC_SSSE3,
-    P_SSE4_A,
-    P_PROC_SSE4_A,
-    P_SSE4_1,
-    P_SSE4_2,
-    P_PROC_SSE4_2,
-    P_POPCNT,
-    P_AES,
-    P_PCLMUL,
-    P_AVX,
-    P_PROC_AVX,
-    P_BMI,
-    P_PROC_BMI,
-    P_FMA4,
-    P_XOP,
-    P_PROC_XOP,
-    P_FMA,    
-    P_PROC_FMA,
-    P_BMI2,
-    P_AVX2,
-    P_PROC_AVX2,
-    P_AVX512F,
-    P_PROC_AVX512F
-  };
-
   enum feature_priority priority = P_ZERO;
 
-  /* These are the target attribute strings for which a dispatcher is
-     available, from fold_builtin_cpu.  */
-
-  static struct _feature_list
-    {
-      const char *const name;
-      const enum feature_priority priority;
-    }
-  const feature_list[] =
-    {
-      {"mmx", P_MMX},
-      {"sse", P_SSE},
-      {"sse2", P_SSE2},
-      {"sse3", P_SSE3},
-      {"sse4a", P_SSE4_A},
-      {"ssse3", P_SSSE3},
-      {"sse4.1", P_SSE4_1},
-      {"sse4.2", P_SSE4_2},
-      {"popcnt", P_POPCNT},
-      {"aes", P_AES},
-      {"pclmul", P_PCLMUL},
-      {"avx", P_AVX},
-      {"bmi", P_BMI},
-      {"fma4", P_FMA4},
-      {"xop", P_XOP},
-      {"fma", P_FMA},
-      {"bmi2", P_BMI2},
-      {"avx2", P_AVX2},
-      {"avx512f", P_AVX512F}
-    };
-
-
   static unsigned int NUM_FEATURES
-    = sizeof (feature_list) / sizeof (struct _feature_list);
+    = sizeof (isa_names_table) / sizeof (_isa_names_table);
 
   unsigned int i;
 
@@ -32121,27 +32275,28 @@ get_builtin_code_for_version (tree decl, tree *predicate_list)
 	}
       for (i = 0; i < NUM_FEATURES; ++i)
 	{
-	  if (strcmp (token, feature_list[i].name) == 0)
+	  if (strcmp (token, isa_names_table[i].name) == 0)
 	    {
 	      if (predicate_list)
 		{
 		  predicate_arg = build_string_literal (
-				  strlen (feature_list[i].name) + 1,
-				  feature_list[i].name);
+				  strlen (isa_names_table[i].name) + 1,
+				  isa_names_table[i].name);
 		  predicate_chain = tree_cons (predicate_decl, predicate_arg,
 					       predicate_chain);
 		}
 	      /* Find the maximum priority feature.  */
-	      if (feature_list[i].priority > priority)
-		priority = feature_list[i].priority;
+	      if (isa_names_table[i].priority > priority)
+		priority = isa_names_table[i].priority;
 
 	      break;
 	    }
 	}
-      if (predicate_list && i == NUM_FEATURES)
+      if (predicate_list && priority == P_ZERO)
 	{
 	  error_at (DECL_SOURCE_LOCATION (decl),
-		    "no dispatcher found for %s", token);
+		    "ISA %qs is not supported in %<target%> attribute, "
+		    "use %<arch=%> syntax", token);
 	  return 0;
 	}
       token = strtok (NULL, ",");
@@ -32676,187 +32831,6 @@ fold_builtin_cpu (tree fndecl, tree *args)
 				DECL_FUNCTION_CODE (fndecl);
   tree param_string_cst = NULL;
 
-  /* This is the order of bit-fields in __processor_features in cpuinfo.c */
-  enum processor_features
-  {
-    F_CMOV = 0,
-    F_MMX,
-    F_POPCNT,
-    F_SSE,
-    F_SSE2,
-    F_SSE3,
-    F_SSSE3,
-    F_SSE4_1,
-    F_SSE4_2,
-    F_AVX,
-    F_AVX2,
-    F_SSE4_A,
-    F_FMA4,
-    F_XOP,
-    F_FMA,
-    F_AVX512F,
-    F_BMI,
-    F_BMI2,
-    F_AES,
-    F_PCLMUL,
-    F_AVX512VL,
-    F_AVX512BW,
-    F_AVX512DQ,
-    F_AVX512CD,
-    F_AVX512ER,
-    F_AVX512PF,
-    F_AVX512VBMI,
-    F_AVX512IFMA,
-    F_AVX5124VNNIW,
-    F_AVX5124FMAPS,
-    F_AVX512VPOPCNTDQ,
-    F_AVX512VBMI2,
-    F_GFNI,
-    F_VPCLMULQDQ,
-    F_AVX512VNNI,
-    F_AVX512BITALG,
-    F_MAX
-  };
-
-  /* These are the values for vendor types and cpu types  and subtypes
-     in cpuinfo.c.  Cpu types and subtypes should be subtracted by
-     the corresponding start value.  */
-  enum processor_model
-  {
-    M_INTEL = 1,
-    M_AMD,
-    M_CPU_TYPE_START,
-    M_INTEL_BONNELL,
-    M_INTEL_CORE2,
-    M_INTEL_COREI7,
-    M_AMDFAM10H,
-    M_AMDFAM15H,
-    M_INTEL_SILVERMONT,
-    M_INTEL_KNL,
-    M_AMD_BTVER1,
-    M_AMD_BTVER2,    
-    M_AMDFAM17H,
-    M_INTEL_KNM,
-    M_INTEL_GOLDMONT,
-    M_INTEL_GOLDMONT_PLUS,
-    M_INTEL_TREMONT,
-    M_CPU_SUBTYPE_START,
-    M_INTEL_COREI7_NEHALEM,
-    M_INTEL_COREI7_WESTMERE,
-    M_INTEL_COREI7_SANDYBRIDGE,
-    M_AMDFAM10H_BARCELONA,
-    M_AMDFAM10H_SHANGHAI,
-    M_AMDFAM10H_ISTANBUL,
-    M_AMDFAM15H_BDVER1,
-    M_AMDFAM15H_BDVER2,
-    M_AMDFAM15H_BDVER3,
-    M_AMDFAM15H_BDVER4,
-    M_AMDFAM17H_ZNVER1,
-    M_INTEL_COREI7_IVYBRIDGE,
-    M_INTEL_COREI7_HASWELL,
-    M_INTEL_COREI7_BROADWELL,
-    M_INTEL_COREI7_SKYLAKE,
-    M_INTEL_COREI7_SKYLAKE_AVX512,
-    M_INTEL_COREI7_CANNONLAKE,
-    M_INTEL_COREI7_ICELAKE_CLIENT,
-    M_INTEL_COREI7_ICELAKE_SERVER,
-    M_AMDFAM17H_ZNVER2,
-    M_INTEL_COREI7_CASCADELAKE
-  };
-
-  static struct _arch_names_table
-    {
-      const char *const name;
-      const enum processor_model model;
-    }
-  const arch_names_table[] =
-    {
-      {"amd", M_AMD},
-      {"intel", M_INTEL},
-      {"atom", M_INTEL_BONNELL},
-      {"slm", M_INTEL_SILVERMONT},
-      {"core2", M_INTEL_CORE2},
-      {"corei7", M_INTEL_COREI7},
-      {"nehalem", M_INTEL_COREI7_NEHALEM},
-      {"westmere", M_INTEL_COREI7_WESTMERE},
-      {"sandybridge", M_INTEL_COREI7_SANDYBRIDGE},
-      {"ivybridge", M_INTEL_COREI7_IVYBRIDGE},
-      {"haswell", M_INTEL_COREI7_HASWELL},
-      {"broadwell", M_INTEL_COREI7_BROADWELL},
-      {"skylake", M_INTEL_COREI7_SKYLAKE},
-      {"skylake-avx512", M_INTEL_COREI7_SKYLAKE_AVX512},
-      {"cannonlake", M_INTEL_COREI7_CANNONLAKE},
-      {"icelake-client", M_INTEL_COREI7_ICELAKE_CLIENT},
-      {"icelake-server", M_INTEL_COREI7_ICELAKE_SERVER},
-      {"cascadelake", M_INTEL_COREI7_CASCADELAKE},
-      {"bonnell", M_INTEL_BONNELL},
-      {"silvermont", M_INTEL_SILVERMONT},
-      {"goldmont", M_INTEL_GOLDMONT},
-      {"goldmont-plus", M_INTEL_GOLDMONT_PLUS},
-      {"tremont", M_INTEL_TREMONT},
-      {"knl", M_INTEL_KNL},
-      {"knm", M_INTEL_KNM},
-      {"amdfam10h", M_AMDFAM10H},
-      {"barcelona", M_AMDFAM10H_BARCELONA},
-      {"shanghai", M_AMDFAM10H_SHANGHAI},
-      {"istanbul", M_AMDFAM10H_ISTANBUL},
-      {"btver1", M_AMD_BTVER1},      
-      {"amdfam15h", M_AMDFAM15H},
-      {"bdver1", M_AMDFAM15H_BDVER1},
-      {"bdver2", M_AMDFAM15H_BDVER2},
-      {"bdver3", M_AMDFAM15H_BDVER3},
-      {"bdver4", M_AMDFAM15H_BDVER4},
-      {"btver2", M_AMD_BTVER2},
-      {"amdfam17h", M_AMDFAM17H},
-      {"znver1", M_AMDFAM17H_ZNVER1},
-      {"znver2", M_AMDFAM17H_ZNVER2},
-    };
-
-  static struct _isa_names_table
-    {
-      const char *const name;
-      const enum processor_features feature;
-    }
-  const isa_names_table[] =
-    {
-      {"cmov",    F_CMOV},
-      {"mmx",     F_MMX},
-      {"popcnt",  F_POPCNT},
-      {"sse",     F_SSE},
-      {"sse2",    F_SSE2},
-      {"sse3",    F_SSE3},
-      {"ssse3",   F_SSSE3},
-      {"sse4a",   F_SSE4_A},
-      {"sse4.1",  F_SSE4_1},
-      {"sse4.2",  F_SSE4_2},
-      {"avx",     F_AVX},
-      {"fma4",    F_FMA4},
-      {"xop",     F_XOP},
-      {"fma",     F_FMA},
-      {"avx2",    F_AVX2},
-      {"avx512f", F_AVX512F},
-      {"bmi",     F_BMI},
-      {"bmi2",    F_BMI2},
-      {"aes",     F_AES},
-      {"pclmul",  F_PCLMUL},
-      {"avx512vl",F_AVX512VL},
-      {"avx512bw",F_AVX512BW},
-      {"avx512dq",F_AVX512DQ},
-      {"avx512cd",F_AVX512CD},
-      {"avx512er",F_AVX512ER},
-      {"avx512pf",F_AVX512PF},
-      {"avx512vbmi",F_AVX512VBMI},
-      {"avx512ifma",F_AVX512IFMA},
-      {"avx5124vnniw",F_AVX5124VNNIW},
-      {"avx5124fmaps",F_AVX5124FMAPS},
-      {"avx512vpopcntdq",F_AVX512VPOPCNTDQ},
-      {"avx512vbmi2", F_AVX512VBMI2},
-      {"gfni", F_GFNI},
-      {"vpclmulqdq", F_VPCLMULQDQ},
-      {"avx512vnni", F_AVX512VNNI},
-      {"avx512bitalg", F_AVX512BITALG}
-    };
-
   tree __processor_model_type = build_processor_model_struct ();
   tree __cpu_model_var = make_var_decl (__processor_model_type,
 					"__cpu_model");
diff --git a/gcc/testsuite/g++.target/i386/mv28.C b/gcc/testsuite/g++.target/i386/mv28.C
new file mode 100644
index 00000000000..adc53962ee5
--- /dev/null
+++ b/gcc/testsuite/g++.target/i386/mv28.C
@@ -0,0 +1,26 @@
+/* { dg-do compile} */
+/* { dg-require-ifunc "" }  */
+
+void __attribute__ ((target("avx512vl"))) foo () {} /* { dg-error "ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("avx512bw"))) foo () {} /* { dg-error "ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("avx512dq"))) foo () {} /* { dg-error "ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("avx512cd"))) foo () {} /* { dg-error "ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("avx512er"))) foo () {} /* { dg-error "ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("avx512pf"))) foo () {} /* { dg-error "ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("avx512vbmi"))) foo () {} /* { dg-error "ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("avx512ifma"))) foo () {} /* { dg-error "ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("avx5124vnniw"))) foo () {} /* { dg-error "ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("avx5124fmaps"))) foo () {} /* { dg-error "ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("avx512vpopcntdq"))) foo () {} /* { dg-error "ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("avx512vbmi2"))) foo () {} /* { dg-error "ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("gfni"))) foo () {} /* { dg-error "ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("vpclmulqdq"))) foo () {} /* { dg-error "ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("avx512vnni"))) foo () {} /* { dg-error "ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("avx512bitalg"))) foo () {} /* { dg-error "ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("default"))) foo () {}
+
+int main()
+{
+  foo ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mvc14.c b/gcc/testsuite/gcc.target/i386/mvc14.c
new file mode 100644
index 00000000000..a3aec6a0055
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mvc14.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-require-ifunc "" } */
+
+__attribute__((target_clones("avx512vl", "avx512bw", "avx512dq",
+			     "avx512cd", "avx512er", "avx512pf", "avx512vbmi",
+			     "avx512ifma", "avx5124vnniw", "avx5124fmaps",
+			     "avx512vpopcntdq", "avx512vbmi2", "gfni",
+			     "vpclmulqdq", "avx512vnni", "avx512bitalg",
+			     "default")))
+int foo (); /* { dg-error "ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+
+int
+bar ()
+{
+  return foo();
+}
Martin Liška April 23, 2019, 8:29 a.m. | #2
On 4/18/19 7:44 PM, H.J. Lu wrote:
> On Thu, Apr 18, 2019 at 4:07 AM Martin Liška <mliska@suse.cz> wrote:

>>

>> Hi.

>>

>> I'm sending updated version of that patch. The patch rejects usage of AVX512 ISAs (except AVX512F)

>> for target attribute for C++ multiversioning and for target_clone attribute.

>>

>> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.

>>

>> Ready to be installed?

>> Thanks,

>> Martin

> 

> Your patch doesn't handle cmov nor gfni properly, which aren't AVX512.

> I prefer this patch.

> 


I like the patch. Thanks for working on that.

Martin
Martin Liška April 25, 2019, 7:51 a.m. | #3
On 4/23/19 10:29 AM, Martin Liška wrote:
> On 4/18/19 7:44 PM, H.J. Lu wrote:

>> On Thu, Apr 18, 2019 at 4:07 AM Martin Liška <mliska@suse.cz> wrote:

>>>

>>> Hi.

>>>

>>> I'm sending updated version of that patch. The patch rejects usage of AVX512 ISAs (except AVX512F)

>>> for target attribute for C++ multiversioning and for target_clone attribute.

>>>

>>> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.

>>>

>>> Ready to be installed?

>>> Thanks,

>>> Martin

>>

>> Your patch doesn't handle cmov nor gfni properly, which aren't AVX512.

>> I prefer this patch.

>>

> 

> I like the patch. Thanks for working on that.

> 

> Martin

> 

> 


Btw. can we get that patch into GCC 9.1?

Adding port maintainers to CC.

Martin
Uros Bizjak April 25, 2019, 8:03 a.m. | #4
On Thu, Apr 25, 2019 at 9:51 AM Martin Liška <mliska@suse.cz> wrote:

> On 4/23/19 10:29 AM, Martin Liška wrote:

> > On 4/18/19 7:44 PM, H.J. Lu wrote:

> >> On Thu, Apr 18, 2019 at 4:07 AM Martin Liška <mliska@suse.cz> wrote:

> >>>

> >>> Hi.

> >>>

> >>> I'm sending updated version of that patch. The patch rejects usage of

> AVX512 ISAs (except AVX512F)

> >>> for target attribute for C++ multiversioning and for target_clone

> attribute.

> >>>

> >>> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.

> >>>

> >>> Ready to be installed?

> >>> Thanks,

> >>> Martin

> >>

> >> Your patch doesn't handle cmov nor gfni properly, which aren't AVX512.

> >> I prefer this patch.

> >>

> >

> > I like the patch. Thanks for working on that.

> >

> > Martin

> >

> >

>

> Btw. can we get that patch into GCC 9.1?

>

> Adding port maintainers to CC.

>


HJ knows ISA interdependencies, and the benefit of the patch outweights the
(small) risk, so from the maintaner PoV, OK for the mainline unless RM
vetoes the decision soon. HJ, please double check the patch for eventual
inconsistencies or possible regressions before committing.

Thanks,
Uros.
H.J. Lu April 25, 2019, 4:58 p.m. | #5
On Thu, Apr 25, 2019 at 1:03 AM Uros Bizjak <ubizjak@gmail.com> wrote:
>

>

>

> On Thu, Apr 25, 2019 at 9:51 AM Martin Liška <mliska@suse.cz> wrote:

>>

>> On 4/23/19 10:29 AM, Martin Liška wrote:

>> > On 4/18/19 7:44 PM, H.J. Lu wrote:

>> >> On Thu, Apr 18, 2019 at 4:07 AM Martin Liška <mliska@suse.cz> wrote:

>> >>>

>> >>> Hi.

>> >>>

>> >>> I'm sending updated version of that patch. The patch rejects usage of AVX512 ISAs (except AVX512F)

>> >>> for target attribute for C++ multiversioning and for target_clone attribute.

>> >>>

>> >>> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.

>> >>>

>> >>> Ready to be installed?

>> >>> Thanks,

>> >>> Martin

>> >>

>> >> Your patch doesn't handle cmov nor gfni properly, which aren't AVX512.

>> >> I prefer this patch.

>> >>

>> >

>> > I like the patch. Thanks for working on that.

>> >

>> > Martin

>> >

>> >

>>

>> Btw. can we get that patch into GCC 9.1?

>>

>> Adding port maintainers to CC.

>

>

> HJ knows ISA interdependencies, and the benefit of the patch outweights the (small) risk, so from the maintaner PoV, OK for the mainline unless RM vetoes the decision soon. HJ, please double check the patch for eventual inconsistencies or possible regressions before committing.

>

> Thanks,

> Uros.


Tested on x86-64.  I am checking in this updated patch with:

diff --git a/gcc/testsuite/g++.target/i386/pr57362.C b/gcc/testsuite/g++.target/
i386/pr57362.C
index 5e612130357..ced5e518cfe 100644
--- a/gcc/testsuite/g++.target/i386/pr57362.C
+++ b/gcc/testsuite/g++.target/i386/pr57362.C
@@ -199,4 +199,4 @@ int foo(void) { return 1; }
 /* { dg-prune-output "attribute.* is unknown" } */
 /* { dg-prune-output "missing 'target' attribute*" } */
 /* { dg-prune-output "redefinition of 'int foo" } */
-/* { dg-prune-output "no dispatcher found for" } */
+/* { dg-prune-output "ISA '.*' is not supported in 'target' attribute" } */


-- 
H.J.
From 79013fe56d7ca7588dc9dbebdeb64f869e15e278 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Thu, 18 Apr 2019 09:49:58 -0700
Subject: [PATCH] x86: Update message for target_clones and unsupported ISAs

Before AVX512F, processors with the newer ISAs also support the older
ISAs, i.e., AVX2 processors also support AVX and SSE4, SSE4 processors
also support SSSE3, ...   After AVX512F, an AVX512XX processor may not
support AVX512YY.  It means AVX512XX features, except for AVX512F, can't
be used to decide priority in target_clones.

This patch updates error message for ISAs with P_ZERO priority.  It also
merges _feature_list into _isa_names_table and marks ISAs, which have
unknown priority, with P_ZERO so that we only need to update one place
to add a new ISA feature.

gcc/

2019-04-25  H.J. Lu  <hongjiu.lu@intel.com>

	PR target/89929
	* config/i386/i386.c (feature_priority): Moved to file scope.
	(processor_features): Likewise.
	(processor_model): Likewise.
	(_arch_names_table): Likewise.
	(arch_names_table): Likewise.
	(_feature_list): Removed.
	(feature_list): Likewise.
	(_isa_names_table): Moved to file scope.  Add priority.
	(isa_names_table): Likewise.
	(get_builtin_code_for_version): Replace feature_list with
	isa_names_table.  Update error message for P_ZERO priority.

gcc/testsuite/

2019-04-25  Martin Liska  <mliska@suse.cz>
	    H.J. Lu  <hongjiu.lu@intel.com>

	PR target/89929
	* g++.target/i386/mv28.C: New test.
	* gcc.target/i386/mvc14.c: Likewise.
	* g++.target/i386/pr57362.C: Updated.
---
 gcc/config/i386/i386.c                  | 490 +++++++++++-------------
 gcc/testsuite/g++.target/i386/mv28.C    |  26 ++
 gcc/testsuite/g++.target/i386/pr57362.C |   2 +-
 gcc/testsuite/gcc.target/i386/mvc14.c   |  16 +
 4 files changed, 275 insertions(+), 259 deletions(-)
 create mode 100644 gcc/testsuite/g++.target/i386/mv28.C
 create mode 100644 gcc/testsuite/gcc.target/i386/mvc14.c

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 191f570455b..8a1ffd3769f 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -31834,6 +31834,229 @@ add_condition_to_bb (tree function_decl, tree version_decl,
   return bb3;
 }
 
+/* Priority of i386 features, greater value is higher priority.   This is
+   used to decide the order in which function dispatch must happen.  For
+   instance, a version specialized for SSE4.2 should be checked for dispatch
+   before a version for SSE3, as SSE4.2 implies SSE3.  */
+enum feature_priority
+{
+  P_ZERO = 0,
+  P_MMX,
+  P_SSE,
+  P_SSE2,
+  P_SSE3,
+  P_SSSE3,
+  P_PROC_SSSE3,
+  P_SSE4_A,
+  P_PROC_SSE4_A,
+  P_SSE4_1,
+  P_SSE4_2,
+  P_PROC_SSE4_2,
+  P_POPCNT,
+  P_AES,
+  P_PCLMUL,
+  P_AVX,
+  P_PROC_AVX,
+  P_BMI,
+  P_PROC_BMI,
+  P_FMA4,
+  P_XOP,
+  P_PROC_XOP,
+  P_FMA,
+  P_PROC_FMA,
+  P_BMI2,
+  P_AVX2,
+  P_PROC_AVX2,
+  P_AVX512F,
+  P_PROC_AVX512F
+};
+
+/* This is the order of bit-fields in __processor_features in cpuinfo.c */
+enum processor_features
+{
+  F_CMOV = 0,
+  F_MMX,
+  F_POPCNT,
+  F_SSE,
+  F_SSE2,
+  F_SSE3,
+  F_SSSE3,
+  F_SSE4_1,
+  F_SSE4_2,
+  F_AVX,
+  F_AVX2,
+  F_SSE4_A,
+  F_FMA4,
+  F_XOP,
+  F_FMA,
+  F_AVX512F,
+  F_BMI,
+  F_BMI2,
+  F_AES,
+  F_PCLMUL,
+  F_AVX512VL,
+  F_AVX512BW,
+  F_AVX512DQ,
+  F_AVX512CD,
+  F_AVX512ER,
+  F_AVX512PF,
+  F_AVX512VBMI,
+  F_AVX512IFMA,
+  F_AVX5124VNNIW,
+  F_AVX5124FMAPS,
+  F_AVX512VPOPCNTDQ,
+  F_AVX512VBMI2,
+  F_GFNI,
+  F_VPCLMULQDQ,
+  F_AVX512VNNI,
+  F_AVX512BITALG,
+  F_MAX
+};
+
+/* These are the values for vendor types and cpu types  and subtypes
+   in cpuinfo.c.  Cpu types and subtypes should be subtracted by
+   the corresponding start value.  */
+enum processor_model
+{
+  M_INTEL = 1,
+  M_AMD,
+  M_CPU_TYPE_START,
+  M_INTEL_BONNELL,
+  M_INTEL_CORE2,
+  M_INTEL_COREI7,
+  M_AMDFAM10H,
+  M_AMDFAM15H,
+  M_INTEL_SILVERMONT,
+  M_INTEL_KNL,
+  M_AMD_BTVER1,
+  M_AMD_BTVER2,
+  M_AMDFAM17H,
+  M_INTEL_KNM,
+  M_INTEL_GOLDMONT,
+  M_INTEL_GOLDMONT_PLUS,
+  M_INTEL_TREMONT,
+  M_CPU_SUBTYPE_START,
+  M_INTEL_COREI7_NEHALEM,
+  M_INTEL_COREI7_WESTMERE,
+  M_INTEL_COREI7_SANDYBRIDGE,
+  M_AMDFAM10H_BARCELONA,
+  M_AMDFAM10H_SHANGHAI,
+  M_AMDFAM10H_ISTANBUL,
+  M_AMDFAM15H_BDVER1,
+  M_AMDFAM15H_BDVER2,
+  M_AMDFAM15H_BDVER3,
+  M_AMDFAM15H_BDVER4,
+  M_AMDFAM17H_ZNVER1,
+  M_INTEL_COREI7_IVYBRIDGE,
+  M_INTEL_COREI7_HASWELL,
+  M_INTEL_COREI7_BROADWELL,
+  M_INTEL_COREI7_SKYLAKE,
+  M_INTEL_COREI7_SKYLAKE_AVX512,
+  M_INTEL_COREI7_CANNONLAKE,
+  M_INTEL_COREI7_ICELAKE_CLIENT,
+  M_INTEL_COREI7_ICELAKE_SERVER,
+  M_AMDFAM17H_ZNVER2,
+  M_INTEL_COREI7_CASCADELAKE
+};
+
+struct _arch_names_table
+{
+  const char *const name;
+  const enum processor_model model;
+};
+
+static const _arch_names_table arch_names_table[] =
+{
+  {"amd", M_AMD},
+  {"intel", M_INTEL},
+  {"atom", M_INTEL_BONNELL},
+  {"slm", M_INTEL_SILVERMONT},
+  {"core2", M_INTEL_CORE2},
+  {"corei7", M_INTEL_COREI7},
+  {"nehalem", M_INTEL_COREI7_NEHALEM},
+  {"westmere", M_INTEL_COREI7_WESTMERE},
+  {"sandybridge", M_INTEL_COREI7_SANDYBRIDGE},
+  {"ivybridge", M_INTEL_COREI7_IVYBRIDGE},
+  {"haswell", M_INTEL_COREI7_HASWELL},
+  {"broadwell", M_INTEL_COREI7_BROADWELL},
+  {"skylake", M_INTEL_COREI7_SKYLAKE},
+  {"skylake-avx512", M_INTEL_COREI7_SKYLAKE_AVX512},
+  {"cannonlake", M_INTEL_COREI7_CANNONLAKE},
+  {"icelake-client", M_INTEL_COREI7_ICELAKE_CLIENT},
+  {"icelake-server", M_INTEL_COREI7_ICELAKE_SERVER},
+  {"cascadelake", M_INTEL_COREI7_CASCADELAKE},
+  {"bonnell", M_INTEL_BONNELL},
+  {"silvermont", M_INTEL_SILVERMONT},
+  {"goldmont", M_INTEL_GOLDMONT},
+  {"goldmont-plus", M_INTEL_GOLDMONT_PLUS},
+  {"tremont", M_INTEL_TREMONT},
+  {"knl", M_INTEL_KNL},
+  {"knm", M_INTEL_KNM},
+  {"amdfam10h", M_AMDFAM10H},
+  {"barcelona", M_AMDFAM10H_BARCELONA},
+  {"shanghai", M_AMDFAM10H_SHANGHAI},
+  {"istanbul", M_AMDFAM10H_ISTANBUL},
+  {"btver1", M_AMD_BTVER1},
+  {"amdfam15h", M_AMDFAM15H},
+  {"bdver1", M_AMDFAM15H_BDVER1},
+  {"bdver2", M_AMDFAM15H_BDVER2},
+  {"bdver3", M_AMDFAM15H_BDVER3},
+  {"bdver4", M_AMDFAM15H_BDVER4},
+  {"btver2", M_AMD_BTVER2},
+  {"amdfam17h", M_AMDFAM17H},
+  {"znver1", M_AMDFAM17H_ZNVER1},
+  {"znver2", M_AMDFAM17H_ZNVER2},
+};
+
+/* These are the target attribute strings for which a dispatcher is
+   available, from fold_builtin_cpu.  */
+struct _isa_names_table
+{
+  const char *const name;
+  const enum processor_features feature;
+  const enum feature_priority priority;
+};
+
+static const _isa_names_table isa_names_table[] =
+{
+  {"cmov",    F_CMOV,	P_ZERO},
+  {"mmx",     F_MMX,	P_MMX},
+  {"popcnt",  F_POPCNT,	P_POPCNT},
+  {"sse",     F_SSE,	P_SSE},
+  {"sse2",    F_SSE2,	P_SSE2},
+  {"sse3",    F_SSE3,	P_SSE3},
+  {"ssse3",   F_SSSE3,	P_SSSE3},
+  {"sse4a",   F_SSE4_A,	P_SSE4_A},
+  {"sse4.1",  F_SSE4_1,	P_SSE4_1},
+  {"sse4.2",  F_SSE4_2,	P_SSE4_2},
+  {"avx",     F_AVX,	P_AVX},
+  {"fma4",    F_FMA4,	P_FMA4},
+  {"xop",     F_XOP,	P_XOP},
+  {"fma",     F_FMA,	P_FMA},
+  {"avx2",    F_AVX2,	P_AVX2},
+  {"avx512f", F_AVX512F, P_AVX512F},
+  {"bmi",     F_BMI,	P_BMI},
+  {"bmi2",    F_BMI2,	P_BMI2},
+  {"aes",     F_AES,	P_AES},
+  {"pclmul",  F_PCLMUL,	P_PCLMUL},
+  {"avx512vl",F_AVX512VL, P_ZERO},
+  {"avx512bw",F_AVX512BW, P_ZERO},
+  {"avx512dq",F_AVX512DQ, P_ZERO},
+  {"avx512cd",F_AVX512CD, P_ZERO},
+  {"avx512er",F_AVX512ER, P_ZERO},
+  {"avx512pf",F_AVX512PF, P_ZERO},
+  {"avx512vbmi",F_AVX512VBMI, P_ZERO},
+  {"avx512ifma",F_AVX512IFMA, P_ZERO},
+  {"avx5124vnniw",F_AVX5124VNNIW, P_ZERO},
+  {"avx5124fmaps",F_AVX5124FMAPS, P_ZERO},
+  {"avx512vpopcntdq",F_AVX512VPOPCNTDQ,	P_ZERO},
+  {"avx512vbmi2", F_AVX512VBMI2, P_ZERO},
+  {"gfni",	F_GFNI,	P_ZERO},
+  {"vpclmulqdq", F_VPCLMULQDQ, P_ZERO},
+  {"avx512vnni", F_AVX512VNNI, P_ZERO},
+  {"avx512bitalg", F_AVX512BITALG, P_ZERO}
+};
+
 /* This parses the attribute arguments to target in DECL and determines
    the right builtin to use to match the platform specification.
    It returns the priority value for this version decl.  If PREDICATE_LIST
@@ -31852,79 +32075,10 @@ get_builtin_code_for_version (tree decl, tree *predicate_list)
   char *tok_str = NULL;
   char *token;
 
-  /* Priority of i386 features, greater value is higher priority.   This is
-     used to decide the order in which function dispatch must happen.  For
-     instance, a version specialized for SSE4.2 should be checked for dispatch
-     before a version for SSE3, as SSE4.2 implies SSE3.  */
-  enum feature_priority
-  {
-    P_ZERO = 0,
-    P_MMX,
-    P_SSE,
-    P_SSE2,
-    P_SSE3,
-    P_SSSE3,
-    P_PROC_SSSE3,
-    P_SSE4_A,
-    P_PROC_SSE4_A,
-    P_SSE4_1,
-    P_SSE4_2,
-    P_PROC_SSE4_2,
-    P_POPCNT,
-    P_AES,
-    P_PCLMUL,
-    P_AVX,
-    P_PROC_AVX,
-    P_BMI,
-    P_PROC_BMI,
-    P_FMA4,
-    P_XOP,
-    P_PROC_XOP,
-    P_FMA,    
-    P_PROC_FMA,
-    P_BMI2,
-    P_AVX2,
-    P_PROC_AVX2,
-    P_AVX512F,
-    P_PROC_AVX512F
-  };
-
   enum feature_priority priority = P_ZERO;
 
-  /* These are the target attribute strings for which a dispatcher is
-     available, from fold_builtin_cpu.  */
-
-  static struct _feature_list
-    {
-      const char *const name;
-      const enum feature_priority priority;
-    }
-  const feature_list[] =
-    {
-      {"mmx", P_MMX},
-      {"sse", P_SSE},
-      {"sse2", P_SSE2},
-      {"sse3", P_SSE3},
-      {"sse4a", P_SSE4_A},
-      {"ssse3", P_SSSE3},
-      {"sse4.1", P_SSE4_1},
-      {"sse4.2", P_SSE4_2},
-      {"popcnt", P_POPCNT},
-      {"aes", P_AES},
-      {"pclmul", P_PCLMUL},
-      {"avx", P_AVX},
-      {"bmi", P_BMI},
-      {"fma4", P_FMA4},
-      {"xop", P_XOP},
-      {"fma", P_FMA},
-      {"bmi2", P_BMI2},
-      {"avx2", P_AVX2},
-      {"avx512f", P_AVX512F}
-    };
-
-
   static unsigned int NUM_FEATURES
-    = sizeof (feature_list) / sizeof (struct _feature_list);
+    = sizeof (isa_names_table) / sizeof (_isa_names_table);
 
   unsigned int i;
 
@@ -32123,27 +32277,28 @@ get_builtin_code_for_version (tree decl, tree *predicate_list)
 	}
       for (i = 0; i < NUM_FEATURES; ++i)
 	{
-	  if (strcmp (token, feature_list[i].name) == 0)
+	  if (strcmp (token, isa_names_table[i].name) == 0)
 	    {
 	      if (predicate_list)
 		{
 		  predicate_arg = build_string_literal (
-				  strlen (feature_list[i].name) + 1,
-				  feature_list[i].name);
+				  strlen (isa_names_table[i].name) + 1,
+				  isa_names_table[i].name);
 		  predicate_chain = tree_cons (predicate_decl, predicate_arg,
 					       predicate_chain);
 		}
 	      /* Find the maximum priority feature.  */
-	      if (feature_list[i].priority > priority)
-		priority = feature_list[i].priority;
+	      if (isa_names_table[i].priority > priority)
+		priority = isa_names_table[i].priority;
 
 	      break;
 	    }
 	}
-      if (predicate_list && i == NUM_FEATURES)
+      if (predicate_list && priority == P_ZERO)
 	{
 	  error_at (DECL_SOURCE_LOCATION (decl),
-		    "no dispatcher found for %s", token);
+		    "ISA %qs is not supported in %<target%> attribute, "
+		    "use %<arch=%> syntax", token);
 	  return 0;
 	}
       token = strtok (NULL, ",");
@@ -32678,187 +32833,6 @@ fold_builtin_cpu (tree fndecl, tree *args)
 				DECL_FUNCTION_CODE (fndecl);
   tree param_string_cst = NULL;
 
-  /* This is the order of bit-fields in __processor_features in cpuinfo.c */
-  enum processor_features
-  {
-    F_CMOV = 0,
-    F_MMX,
-    F_POPCNT,
-    F_SSE,
-    F_SSE2,
-    F_SSE3,
-    F_SSSE3,
-    F_SSE4_1,
-    F_SSE4_2,
-    F_AVX,
-    F_AVX2,
-    F_SSE4_A,
-    F_FMA4,
-    F_XOP,
-    F_FMA,
-    F_AVX512F,
-    F_BMI,
-    F_BMI2,
-    F_AES,
-    F_PCLMUL,
-    F_AVX512VL,
-    F_AVX512BW,
-    F_AVX512DQ,
-    F_AVX512CD,
-    F_AVX512ER,
-    F_AVX512PF,
-    F_AVX512VBMI,
-    F_AVX512IFMA,
-    F_AVX5124VNNIW,
-    F_AVX5124FMAPS,
-    F_AVX512VPOPCNTDQ,
-    F_AVX512VBMI2,
-    F_GFNI,
-    F_VPCLMULQDQ,
-    F_AVX512VNNI,
-    F_AVX512BITALG,
-    F_MAX
-  };
-
-  /* These are the values for vendor types and cpu types  and subtypes
-     in cpuinfo.c.  Cpu types and subtypes should be subtracted by
-     the corresponding start value.  */
-  enum processor_model
-  {
-    M_INTEL = 1,
-    M_AMD,
-    M_CPU_TYPE_START,
-    M_INTEL_BONNELL,
-    M_INTEL_CORE2,
-    M_INTEL_COREI7,
-    M_AMDFAM10H,
-    M_AMDFAM15H,
-    M_INTEL_SILVERMONT,
-    M_INTEL_KNL,
-    M_AMD_BTVER1,
-    M_AMD_BTVER2,    
-    M_AMDFAM17H,
-    M_INTEL_KNM,
-    M_INTEL_GOLDMONT,
-    M_INTEL_GOLDMONT_PLUS,
-    M_INTEL_TREMONT,
-    M_CPU_SUBTYPE_START,
-    M_INTEL_COREI7_NEHALEM,
-    M_INTEL_COREI7_WESTMERE,
-    M_INTEL_COREI7_SANDYBRIDGE,
-    M_AMDFAM10H_BARCELONA,
-    M_AMDFAM10H_SHANGHAI,
-    M_AMDFAM10H_ISTANBUL,
-    M_AMDFAM15H_BDVER1,
-    M_AMDFAM15H_BDVER2,
-    M_AMDFAM15H_BDVER3,
-    M_AMDFAM15H_BDVER4,
-    M_AMDFAM17H_ZNVER1,
-    M_INTEL_COREI7_IVYBRIDGE,
-    M_INTEL_COREI7_HASWELL,
-    M_INTEL_COREI7_BROADWELL,
-    M_INTEL_COREI7_SKYLAKE,
-    M_INTEL_COREI7_SKYLAKE_AVX512,
-    M_INTEL_COREI7_CANNONLAKE,
-    M_INTEL_COREI7_ICELAKE_CLIENT,
-    M_INTEL_COREI7_ICELAKE_SERVER,
-    M_AMDFAM17H_ZNVER2,
-    M_INTEL_COREI7_CASCADELAKE
-  };
-
-  static struct _arch_names_table
-    {
-      const char *const name;
-      const enum processor_model model;
-    }
-  const arch_names_table[] =
-    {
-      {"amd", M_AMD},
-      {"intel", M_INTEL},
-      {"atom", M_INTEL_BONNELL},
-      {"slm", M_INTEL_SILVERMONT},
-      {"core2", M_INTEL_CORE2},
-      {"corei7", M_INTEL_COREI7},
-      {"nehalem", M_INTEL_COREI7_NEHALEM},
-      {"westmere", M_INTEL_COREI7_WESTMERE},
-      {"sandybridge", M_INTEL_COREI7_SANDYBRIDGE},
-      {"ivybridge", M_INTEL_COREI7_IVYBRIDGE},
-      {"haswell", M_INTEL_COREI7_HASWELL},
-      {"broadwell", M_INTEL_COREI7_BROADWELL},
-      {"skylake", M_INTEL_COREI7_SKYLAKE},
-      {"skylake-avx512", M_INTEL_COREI7_SKYLAKE_AVX512},
-      {"cannonlake", M_INTEL_COREI7_CANNONLAKE},
-      {"icelake-client", M_INTEL_COREI7_ICELAKE_CLIENT},
-      {"icelake-server", M_INTEL_COREI7_ICELAKE_SERVER},
-      {"cascadelake", M_INTEL_COREI7_CASCADELAKE},
-      {"bonnell", M_INTEL_BONNELL},
-      {"silvermont", M_INTEL_SILVERMONT},
-      {"goldmont", M_INTEL_GOLDMONT},
-      {"goldmont-plus", M_INTEL_GOLDMONT_PLUS},
-      {"tremont", M_INTEL_TREMONT},
-      {"knl", M_INTEL_KNL},
-      {"knm", M_INTEL_KNM},
-      {"amdfam10h", M_AMDFAM10H},
-      {"barcelona", M_AMDFAM10H_BARCELONA},
-      {"shanghai", M_AMDFAM10H_SHANGHAI},
-      {"istanbul", M_AMDFAM10H_ISTANBUL},
-      {"btver1", M_AMD_BTVER1},      
-      {"amdfam15h", M_AMDFAM15H},
-      {"bdver1", M_AMDFAM15H_BDVER1},
-      {"bdver2", M_AMDFAM15H_BDVER2},
-      {"bdver3", M_AMDFAM15H_BDVER3},
-      {"bdver4", M_AMDFAM15H_BDVER4},
-      {"btver2", M_AMD_BTVER2},
-      {"amdfam17h", M_AMDFAM17H},
-      {"znver1", M_AMDFAM17H_ZNVER1},
-      {"znver2", M_AMDFAM17H_ZNVER2},
-    };
-
-  static struct _isa_names_table
-    {
-      const char *const name;
-      const enum processor_features feature;
-    }
-  const isa_names_table[] =
-    {
-      {"cmov",    F_CMOV},
-      {"mmx",     F_MMX},
-      {"popcnt",  F_POPCNT},
-      {"sse",     F_SSE},
-      {"sse2",    F_SSE2},
-      {"sse3",    F_SSE3},
-      {"ssse3",   F_SSSE3},
-      {"sse4a",   F_SSE4_A},
-      {"sse4.1",  F_SSE4_1},
-      {"sse4.2",  F_SSE4_2},
-      {"avx",     F_AVX},
-      {"fma4",    F_FMA4},
-      {"xop",     F_XOP},
-      {"fma",     F_FMA},
-      {"avx2",    F_AVX2},
-      {"avx512f", F_AVX512F},
-      {"bmi",     F_BMI},
-      {"bmi2",    F_BMI2},
-      {"aes",     F_AES},
-      {"pclmul",  F_PCLMUL},
-      {"avx512vl",F_AVX512VL},
-      {"avx512bw",F_AVX512BW},
-      {"avx512dq",F_AVX512DQ},
-      {"avx512cd",F_AVX512CD},
-      {"avx512er",F_AVX512ER},
-      {"avx512pf",F_AVX512PF},
-      {"avx512vbmi",F_AVX512VBMI},
-      {"avx512ifma",F_AVX512IFMA},
-      {"avx5124vnniw",F_AVX5124VNNIW},
-      {"avx5124fmaps",F_AVX5124FMAPS},
-      {"avx512vpopcntdq",F_AVX512VPOPCNTDQ},
-      {"avx512vbmi2", F_AVX512VBMI2},
-      {"gfni", F_GFNI},
-      {"vpclmulqdq", F_VPCLMULQDQ},
-      {"avx512vnni", F_AVX512VNNI},
-      {"avx512bitalg", F_AVX512BITALG}
-    };
-
   tree __processor_model_type = build_processor_model_struct ();
   tree __cpu_model_var = make_var_decl (__processor_model_type,
 					"__cpu_model");
diff --git a/gcc/testsuite/g++.target/i386/mv28.C b/gcc/testsuite/g++.target/i386/mv28.C
new file mode 100644
index 00000000000..adc53962ee5
--- /dev/null
+++ b/gcc/testsuite/g++.target/i386/mv28.C
@@ -0,0 +1,26 @@
+/* { dg-do compile} */
+/* { dg-require-ifunc "" }  */
+
+void __attribute__ ((target("avx512vl"))) foo () {} /* { dg-error "ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("avx512bw"))) foo () {} /* { dg-error "ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("avx512dq"))) foo () {} /* { dg-error "ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("avx512cd"))) foo () {} /* { dg-error "ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("avx512er"))) foo () {} /* { dg-error "ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("avx512pf"))) foo () {} /* { dg-error "ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("avx512vbmi"))) foo () {} /* { dg-error "ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("avx512ifma"))) foo () {} /* { dg-error "ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("avx5124vnniw"))) foo () {} /* { dg-error "ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("avx5124fmaps"))) foo () {} /* { dg-error "ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("avx512vpopcntdq"))) foo () {} /* { dg-error "ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("avx512vbmi2"))) foo () {} /* { dg-error "ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("gfni"))) foo () {} /* { dg-error "ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("vpclmulqdq"))) foo () {} /* { dg-error "ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("avx512vnni"))) foo () {} /* { dg-error "ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("avx512bitalg"))) foo () {} /* { dg-error "ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("default"))) foo () {}
+
+int main()
+{
+  foo ();
+  return 0;
+}
diff --git a/gcc/testsuite/g++.target/i386/pr57362.C b/gcc/testsuite/g++.target/i386/pr57362.C
index 5e612130357..ced5e518cfe 100644
--- a/gcc/testsuite/g++.target/i386/pr57362.C
+++ b/gcc/testsuite/g++.target/i386/pr57362.C
@@ -199,4 +199,4 @@ int foo(void) { return 1; }
 /* { dg-prune-output "attribute.* is unknown" } */
 /* { dg-prune-output "missing 'target' attribute*" } */
 /* { dg-prune-output "redefinition of 'int foo" } */
-/* { dg-prune-output "no dispatcher found for" } */
+/* { dg-prune-output "ISA '.*' is not supported in 'target' attribute" } */
diff --git a/gcc/testsuite/gcc.target/i386/mvc14.c b/gcc/testsuite/gcc.target/i386/mvc14.c
new file mode 100644
index 00000000000..a3aec6a0055
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mvc14.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-require-ifunc "" } */
+
+__attribute__((target_clones("avx512vl", "avx512bw", "avx512dq",
+			     "avx512cd", "avx512er", "avx512pf", "avx512vbmi",
+			     "avx512ifma", "avx5124vnniw", "avx5124fmaps",
+			     "avx512vpopcntdq", "avx512vbmi2", "gfni",
+			     "vpclmulqdq", "avx512vnni", "avx512bitalg",
+			     "default")))
+int foo (); /* { dg-error "ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+
+int
+bar ()
+{
+  return foo();
+}

Patch

From 6a7119cbdb908a2a7bd8017c64e084b5f20b3052 Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Wed, 17 Apr 2019 14:01:21 +0200
Subject: [PATCH] Add error message for target_clones and AVX512 ISAs (PR
 target/89929).

gcc/ChangeLog:

2019-04-18  Martin Liska  <mliska@suse.cz>

	PR target/89929
	* config/i386/i386.c (get_builtin_code_for_version): Provide new
	error for AVX512 ISAs.

gcc/testsuite/ChangeLog:

2019-04-18  Martin Liska  <mliska@suse.cz>

	PR target/89929
	* g++.target/i386/mv28.C: New test.
	* gcc.target/i386/mvc14.c: New test.
---
 gcc/config/i386/i386.c                | 27 +++++++++++++++++++++++++++
 gcc/testsuite/g++.target/i386/mv28.C  | 26 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/i386/mvc14.c | 16 ++++++++++++++++
 3 files changed, 69 insertions(+)
 create mode 100644 gcc/testsuite/g++.target/i386/mv28.C
 create mode 100644 gcc/testsuite/gcc.target/i386/mvc14.c

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 498a35d8aea..ed9a9c2e3f7 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -31920,6 +31920,24 @@  get_builtin_code_for_version (tree decl, tree *predicate_list)
       {"avx512f", P_AVX512F}
     };
 
+  static const char * avx512_warning_isas[] = {
+      "avx5124fmaps",
+      "avx5124vnniw",
+      "avx512vpopcntdq",
+      "avx512vbmi2",
+      "avx512vnni",
+      "avx512bitalg",
+      "avx512vbmi",
+      "avx512ifma",
+      "avx512vl",
+      "avx512bw",
+      "avx512dq",
+      "avx512er",
+      "avx512pf",
+      "avx512cd",
+      "gfni",
+      "vpclmulqdq",
+  };
 
   static unsigned int NUM_FEATURES
     = sizeof (feature_list) / sizeof (struct _feature_list);
@@ -32140,6 +32158,15 @@  get_builtin_code_for_version (tree decl, tree *predicate_list)
 	}
       if (predicate_list && i == NUM_FEATURES)
 	{
+	  for (unsigned i = 0; i < ARRAY_SIZE (avx512_warning_isas); i++)
+	    if (strcmp (token, avx512_warning_isas[i]) == 0)
+	      {
+		error_at (DECL_SOURCE_LOCATION (decl),
+			  "AVX512 ISA %qs is not supported in "
+			  "%<target%> attribute, use %<arch=%> syntax", token);
+		return 0;
+	      }
+
 	  error_at (DECL_SOURCE_LOCATION (decl),
 		    "no dispatcher found for %s", token);
 	  return 0;
diff --git a/gcc/testsuite/g++.target/i386/mv28.C b/gcc/testsuite/g++.target/i386/mv28.C
new file mode 100644
index 00000000000..a33efd9cf21
--- /dev/null
+++ b/gcc/testsuite/g++.target/i386/mv28.C
@@ -0,0 +1,26 @@ 
+/* { dg-do compile} */
+/* { dg-require-ifunc "" }  */
+
+void __attribute__ ((target("avx512vl"))) foo () {} /* { dg-error "AVX512 ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("avx512bw"))) foo () {} /* { dg-error "AVX512 ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("avx512dq"))) foo () {} /* { dg-error "AVX512 ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("avx512cd"))) foo () {} /* { dg-error "AVX512 ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("avx512er"))) foo () {} /* { dg-error "AVX512 ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("avx512pf"))) foo () {} /* { dg-error "AVX512 ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("avx512vbmi"))) foo () {} /* { dg-error "AVX512 ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("avx512ifma"))) foo () {} /* { dg-error "AVX512 ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("avx5124vnniw"))) foo () {} /* { dg-error "AVX512 ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("avx5124fmaps"))) foo () {} /* { dg-error "AVX512 ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("avx512vpopcntdq"))) foo () {} /* { dg-error "AVX512 ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("avx512vbmi2"))) foo () {} /* { dg-error "AVX512 ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("gfni"))) foo () {} /* { dg-error "AVX512 ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("vpclmulqdq"))) foo () {} /* { dg-error "AVX512 ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("avx512vnni"))) foo () {} /* { dg-error "AVX512 ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("avx512bitalg"))) foo () {} /* { dg-error "AVX512 ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+void __attribute__ ((target("default"))) foo () {}
+
+int main()
+{
+  foo ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mvc14.c b/gcc/testsuite/gcc.target/i386/mvc14.c
new file mode 100644
index 00000000000..fc357e65eca
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mvc14.c
@@ -0,0 +1,16 @@ 
+/* { dg-do compile } */
+/* { dg-require-ifunc "" } */
+
+__attribute__((target_clones("avx512vl", "avx512bw", "avx512dq",
+			     "avx512cd", "avx512er", "avx512pf", "avx512vbmi",
+			     "avx512ifma", "avx5124vnniw", "avx5124fmaps",
+			     "avx512vpopcntdq", "avx512vbmi2", "gfni",
+			     "vpclmulqdq", "avx512vnni", "avx512bitalg",
+			     "default")))
+int foo (); /* { dg-error "AVX512 ISA '\[^\n\r\]*' is not supported in 'target' attribute, use 'arch=' syntax" } */
+
+int
+bar ()
+{
+  return foo();
+}
-- 
2.21.0