Forgot to add the patch. Martin
>From fb1bbf142af6668eeb1bdfeec96920de2f0edb21 Mon Sep 17 00:00:00 2001 From: marxin <mli...@suse.cz> Date: Thu, 12 Apr 2018 12:15:17 +0200 Subject: [PATCH] Make redirection only for target_clones: V2 (PR ipa/85329).
gcc/ChangeLog: 2018-04-12 Martin Liska <mli...@suse.cz> PR ipa/85329 * multiple_target.c (create_dispatcher_calls): Set apostrophes for target_clone error message. (separate_attrs): Add new argument and check for an emptry string. (expand_target_clones): Handle it. (ipa_target_clone): Make redirection just for target_clones functions. gcc/testsuite/ChangeLog: 2018-04-12 Martin Liska <mli...@suse.cz> PR ipa/85329 * g++.dg/ext/pr85329.C: New test. * gcc.target/i386/mvc12.c: New test. --- gcc/multiple_target.c | 43 ++++++++++++++++++++++++----------- gcc/testsuite/g++.dg/ext/pr85329.C | 19 ++++++++++++++++ gcc/testsuite/gcc.target/i386/mvc12.c | 11 +++++++++ 3 files changed, 60 insertions(+), 13 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ext/pr85329.C create mode 100644 gcc/testsuite/gcc.target/i386/mvc12.c diff --git a/gcc/multiple_target.c b/gcc/multiple_target.c index b006a5ab6ec..2357e458ec8 100644 --- a/gcc/multiple_target.c +++ b/gcc/multiple_target.c @@ -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; } @@ -216,26 +216,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 +325,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 +349,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 +358,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; @@ -382,6 +394,7 @@ expand_target_clones (struct cgraph_node *node, bool definition) DECL_ATTRIBUTES (new_node->decl) = attributes; location_t saved_loc = input_location; input_location = DECL_SOURCE_LOCATION (node->decl); + if (!targetm.target_option.valid_attribute_p (new_node->decl, NULL, TREE_VALUE (attributes), 0)) @@ -413,7 +426,11 @@ expand_target_clones (struct cgraph_node *node, bool definition) tree attributes = make_attribute ("target", "default", DECL_ATTRIBUTES (node->decl)); DECL_ATTRIBUTES (node->decl) = attributes; + DECL_COMDAT (node->decl) = 0; + DECL_WEAK (node->decl) = 0; + DECL_ARTIFICIAL (node->decl) = 1; node->local.local = false; + node->set_comdat_group (NULL); location_t saved_loc = input_location; input_location = DECL_SOURCE_LOCATION (node->decl); bool ret @@ -427,14 +444,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; } diff --git a/gcc/testsuite/g++.dg/ext/pr85329.C b/gcc/testsuite/g++.dg/ext/pr85329.C new file mode 100644 index 00000000000..fb77e42cd78 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/pr85329.C @@ -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 index 00000000000..f42ae8080e6 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/mvc12.c @@ -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(); +} -- 2.16.3