Make redirection only for target_clones: V3 (PR ipa/85329).
authorMartin Liska <mliska@suse.cz>
Tue, 17 Apr 2018 05:40:39 +0000 (07:40 +0200)
committerMartin Liska <marxin@gcc.gnu.org>
Tue, 17 Apr 2018 05:40:39 +0000 (05:40 +0000)
2018-04-17  Martin Liska  <mliska@suse.cz>

PR ipa/85329
* multiple_target.c (create_dispatcher_calls): Set apostrophes
for target_clone error message.  Make default implementation
        clone to be a local declaration.
(separate_attrs): Add new argument and check for an empty
string.
(expand_target_clones): Handle it.
(ipa_target_clone): Make redirection just for target_clones
functions.
2018-04-17  Martin Liska  <mliska@suse.cz>

PR ipa/85329
* g++.dg/ext/pr85329-2.C: New test.
* g++.dg/ext/pr85329.C: New test.
* gcc.target/i386/mvc12.c: New test.

From-SVN: r259428

gcc/ChangeLog
gcc/multiple_target.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/pr85329-2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/pr85329.C [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/mvc12.c [new file with mode: 0644]

index caef3054ec68ba65ebfe1f9cf7049234fa85800f..a96c8decffc446000c73ad1832019df3a3599e6f 100644 (file)
@@ -1,3 +1,15 @@
+2018-04-17  Martin Liska  <mliska@suse.cz>
+
+       PR ipa/85329
+       * multiple_target.c (create_dispatcher_calls): Set apostrophes
+       for target_clone error message.  Make default implementation
+        clone to be a local declaration.
+       (separate_attrs): Add new argument and check for an empty
+       string.
+       (expand_target_clones): Handle it.
+       (ipa_target_clone): Make redirection just for target_clones
+       functions.
+
 2018-04-16  Cesar Philippidis  <cesar@codesourcery.com>
            Tom de Vries  <tom@codesourcery.com>
 
index b006a5ab6eca98c3380030eff403dc664178be0f..a1fe09a598318a154a23ca72d280767eccac9407 100644 (file)
@@ -88,7 +88,7 @@ create_dispatcher_calls (struct cgraph_node *node)
   if (!idecl)
     {
       error_at (DECL_SOURCE_LOCATION (node->decl),
-               "default target_clones attribute was not set");
+               "default %<target_clones%> attribute was not set");
       return;
     }
 
@@ -161,10 +161,25 @@ create_dispatcher_calls (struct cgraph_node *node)
        }
     }
 
-  TREE_PUBLIC (node->decl) = 0;
   symtab->change_decl_assembler_name (node->decl,
                                      clone_function_name (node->decl,
                                                           "default"));
+
+  /* FIXME: copy of cgraph_node::make_local that should be cleaned up
+           in next stage1.  */
+  node->make_decl_local ();
+  node->set_section (NULL);
+  node->set_comdat_group (NULL);
+  node->externally_visible = false;
+  node->forced_by_abi = false;
+  node->set_section (NULL);
+  node->unique_name = ((node->resolution == LDPR_PREVAILING_DEF_IRONLY
+                       || node->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
+                      && !flag_incremental_link);
+  node->resolution = LDPR_PREVAILING_DEF_IRONLY;
+
+  DECL_ARTIFICIAL (node->decl) = 1;
+  node->force_output = true;
 }
 
 /* Return length of attribute names string,
@@ -216,26 +231,30 @@ get_attr_str (tree arglist, char *attr_str)
 }
 
 /* Return number of attributes separated by comma and put them into ARGS.
-   If there is no DEFAULT attribute return -1.  */
+   If there is no DEFAULT attribute return -1.  If there is an empty
+   string in attribute return -2.  */
 
 static int
-separate_attrs (char *attr_str, char **attrs)
+separate_attrs (char *attr_str, char **attrs, int attrnum)
 {
   int i = 0;
-  bool has_default = false;
+  int default_count = 0;
 
   for (char *attr = strtok (attr_str, ",");
        attr != NULL; attr = strtok (NULL, ","))
     {
       if (strcmp (attr, "default") == 0)
        {
-         has_default = true;
+         default_count++;
          continue;
        }
       attrs[i++] = attr;
     }
-  if (!has_default)
+  if (default_count == 0)
     return -1;
+  else if (i + default_count < attrnum)
+    return -2;
+
   return i;
 }
 
@@ -321,7 +340,7 @@ expand_target_clones (struct cgraph_node *node, bool definition)
     {
       warning_at (DECL_SOURCE_LOCATION (node->decl),
                  0,
-                 "single target_clones attribute is ignored");
+                 "single %<target_clones%> attribute is ignored");
       return false;
     }
 
@@ -345,7 +364,7 @@ expand_target_clones (struct cgraph_node *node, bool definition)
   int attrnum = get_attr_str (arglist, attr_str);
   char **attrs = XNEWVEC (char *, attrnum);
 
-  attrnum = separate_attrs (attr_str, attrs);
+  attrnum = separate_attrs (attr_str, attrs, attrnum);
   if (attrnum == -1)
     {
       error_at (DECL_SOURCE_LOCATION (node->decl),
@@ -354,6 +373,14 @@ expand_target_clones (struct cgraph_node *node, bool definition)
       XDELETEVEC (attr_str);
       return false;
     }
+  else if (attrnum == -2)
+    {
+      error_at (DECL_SOURCE_LOCATION (node->decl),
+               "an empty string cannot be in %<target_clones%> attribute");
+      XDELETEVEC (attrs);
+      XDELETEVEC (attr_str);
+      return false;
+    }
 
   cgraph_function_version_info *decl1_v = NULL;
   cgraph_function_version_info *decl2_v = NULL;
@@ -427,14 +454,14 @@ static unsigned int
 ipa_target_clone (void)
 {
   struct cgraph_node *node;
+  auto_vec<cgraph_node *> to_dispatch;
 
-  bool target_clone_pass = false;
   FOR_EACH_FUNCTION (node)
-    target_clone_pass |= expand_target_clones (node, node->definition);
+    if (expand_target_clones (node, node->definition))
+      to_dispatch.safe_push (node);
 
-  if (target_clone_pass)
-    FOR_EACH_FUNCTION (node)
-      create_dispatcher_calls (node);
+  for (unsigned i = 0; i < to_dispatch.length (); i++)
+    create_dispatcher_calls (to_dispatch[i]);
 
   return 0;
 }
index 33258e6f4fc3a7c17f5fd980817d08c3462cbe2d..a7dd355e5a5af328c4c0a5e529d68c742fd29a90 100644 (file)
@@ -1,3 +1,10 @@
+2018-04-17  Martin Liska  <mliska@suse.cz>
+
+       PR ipa/85329
+       * g++.dg/ext/pr85329-2.C: New test.
+       * g++.dg/ext/pr85329.C: New test.
+       * gcc.target/i386/mvc12.c: New test.
+
 2018-04-16  Alexandre Oliva <aoliva@redhat.com>
 
        PR c++/85039
diff --git a/gcc/testsuite/g++.dg/ext/pr85329-2.C b/gcc/testsuite/g++.dg/ext/pr85329-2.C
new file mode 100644 (file)
index 0000000..24622d4
--- /dev/null
@@ -0,0 +1,22 @@
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-ifunc "" } */
+
+class b
+{
+public:
+  __attribute__ ((target ("aes"))) b () {}
+  __attribute__ ((target ("default"))) b () {}
+};
+class c
+{
+  b d;
+};
+void
+fn1 ()
+{
+  c a;
+}
+__attribute__ ((target_clones ("sse", "default"))) void
+e ()
+{
+}
diff --git a/gcc/testsuite/g++.dg/ext/pr85329.C b/gcc/testsuite/g++.dg/ext/pr85329.C
new file mode 100644 (file)
index 0000000..fb77e42
--- /dev/null
@@ -0,0 +1,19 @@
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-ifunc "" } */
+
+struct a
+{
+  __attribute__((target_clones("sse", "default"))) void operator^=(a) {}
+} * b;
+
+class c {
+public:
+  a *d();
+};
+
+class f {
+  void g();
+  c e;
+};
+
+void f::g() { *e.d() ^= b[0]; }
diff --git a/gcc/testsuite/gcc.target/i386/mvc12.c b/gcc/testsuite/gcc.target/i386/mvc12.c
new file mode 100644 (file)
index 0000000..f42ae80
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-ifunc "" } */
+
+__attribute__((target_clones("","arch=slm","arch=core-avx2", "default")))
+int foo (); /* { dg-error "an empty string cannot be in .target_clones. attribute" } */
+
+int
+bar ()
+{
+  return foo();
+}