summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2016-11-18 22:21:31 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2016-11-18 22:21:31 +0000
commitcb6c05f855c410696b3fdc075399b97534cc7c35 (patch)
treeacf1794c26cb1e3b59a4151a8b8dcf6028251d3a
parente1c5261183f725d8ab3b0390110acc83f4e7231a (diff)
downloadgcc-cb6c05f855c410696b3fdc075399b97534cc7c35.tar.gz
PR middle-end/78419
* multiple_target.c (get_attr_len): Start with argnum and increment argnum on every arg. Use strchr in a loop instead of counting commas manually. (get_attr_str): Increment argnum for every comma in the string. (separate_attrs): Use for instead of while loop, simplify. (expand_target_clones): Rename defenition argument to definition. Free attrs and attr_str even when diagnosing errors. Temporarily change input_location around targetm.target_option.valid_attribute_p calls. Don't emit warning or errors if that function fails. * gcc.target/i386/pr78419.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@242608 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/multiple_target.c68
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/gcc.target/i386/pr78419.c23
4 files changed, 69 insertions, 36 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9a793343da3..67938695608 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,16 @@
2016-11-18 Jakub Jelinek <jakub@redhat.com>
+ PR middle-end/78419
+ * multiple_target.c (get_attr_len): Start with argnum and increment
+ argnum on every arg. Use strchr in a loop instead of counting commas
+ manually.
+ (get_attr_str): Increment argnum for every comma in the string.
+ (separate_attrs): Use for instead of while loop, simplify.
+ (expand_target_clones): Rename defenition argument to definition.
+ Free attrs and attr_str even when diagnosing errors. Temporarily
+ change input_location around targetm.target_option.valid_attribute_p
+ calls. Don't emit warning or errors if that function fails.
+
* dwarf2out.c (size_of_discr_list): Fix typo in function comment.
PR debug/78191
diff --git a/gcc/multiple_target.c b/gcc/multiple_target.c
index 9848feaddb3..4ead0292138 100644
--- a/gcc/multiple_target.c
+++ b/gcc/multiple_target.c
@@ -101,22 +101,18 @@ get_attr_len (tree arglist)
{
tree arg;
int str_len_sum = 0;
- int argnum = 1;
+ int argnum = 0;
for (arg = arglist; arg; arg = TREE_CHAIN (arg))
{
- unsigned int i;
const char *str = TREE_STRING_POINTER (TREE_VALUE (arg));
- int len = strlen (str);
-
+ size_t len = strlen (str);
str_len_sum += len + 1;
- if (arg != arglist)
+ for (const char *p = strchr (str, ','); p; p = strchr (p + 1, ','))
argnum++;
- for (i = 0; i < strlen (str); i++)
- if (str[i] == ',')
- argnum++;
+ argnum++;
}
- if (argnum == 1)
+ if (argnum <= 1)
return -1;
return str_len_sum;
}
@@ -134,8 +130,9 @@ get_attr_str (tree arglist, char *attr_str)
for (arg = arglist; arg; arg = TREE_CHAIN (arg))
{
const char *str = TREE_STRING_POINTER (TREE_VALUE (arg));
-
size_t len = strlen (str);
+ for (const char *p = strchr (str, ','); p; p = strchr (p + 1, ','))
+ argnum++;
memcpy (attr_str + str_len_sum, str, len);
attr_str[str_len_sum + len] = TREE_CHAIN (arg) ? ',' : '\0';
str_len_sum += len + 1;
@@ -152,19 +149,16 @@ separate_attrs (char *attr_str, char **attrs)
{
int i = 0;
bool has_default = false;
- char *attr = strtok (attr_str, ",");
- while (attr != NULL)
+ for (char *attr = strtok (attr_str, ",");
+ attr != NULL; attr = strtok (NULL, ","))
{
if (strcmp (attr, "default") == 0)
{
has_default = true;
- attr = strtok (NULL, ",");
continue;
}
- attrs[i] = attr;
- attr = strtok (NULL, ",");
- i++;
+ attrs[i++] = attr;
}
if (!has_default)
return -1;
@@ -235,7 +229,7 @@ create_target_clone (cgraph_node *node, bool definition, char *name)
create the appropriate clone for each valid target attribute. */
static bool
-expand_target_clones (struct cgraph_node *node, bool defenition)
+expand_target_clones (struct cgraph_node *node, bool definition)
{
int i;
/* Parsing target attributes separated by comma. */
@@ -266,6 +260,8 @@ expand_target_clones (struct cgraph_node *node, bool defenition)
{
error_at (DECL_SOURCE_LOCATION (node->decl),
"default target was not set");
+ XDELETEVEC (attrs);
+ XDELETEVEC (attr_str);
return false;
}
@@ -286,22 +282,24 @@ expand_target_clones (struct cgraph_node *node, bool defenition)
create_new_asm_name (attr, suffix);
/* Create new target clone. */
- cgraph_node *new_node = create_target_clone (node, defenition, suffix);
+ cgraph_node *new_node = create_target_clone (node, definition, suffix);
XDELETEVEC (suffix);
/* Set new attribute for the clone. */
tree attributes = make_attribute ("target", attr,
DECL_ATTRIBUTES (new_node->decl));
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))
+ TREE_VALUE (attributes),
+ 0))
{
- warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
- "attribute(target_clones(\"%s\")) is not "
- "valid for current target", attr);
+ input_location = saved_loc;
continue;
}
+ input_location = saved_loc;
decl2_v = new_node->function_version ();
if (decl2_v != NULL)
continue;
@@ -320,22 +318,20 @@ expand_target_clones (struct cgraph_node *node, bool defenition)
DECL_FUNCTION_VERSIONED (new_node->decl) = 1;
}
- /* Setting new attribute to initial function. */
- tree attributes = make_attribute ("target", "default",
- DECL_ATTRIBUTES (node->decl));
- DECL_ATTRIBUTES (node->decl) = attributes;
- if (!targetm.target_option.valid_attribute_p (node->decl, NULL,
- TREE_VALUE (attributes), 0))
- {
- error_at (DECL_SOURCE_LOCATION (node->decl),
- "attribute(target_clones(\"default\")) is not "
- "valid for current target");
- return false;
- }
-
XDELETEVEC (attrs);
XDELETEVEC (attr_str);
- return true;
+
+ /* Setting new attribute to initial function. */
+ tree attributes = make_attribute ("target", "default",
+ DECL_ATTRIBUTES (node->decl));
+ DECL_ATTRIBUTES (node->decl) = attributes;
+ location_t saved_loc = input_location;
+ input_location = DECL_SOURCE_LOCATION (node->decl);
+ bool ret
+ = targetm.target_option.valid_attribute_p (node->decl, NULL,
+ TREE_VALUE (attributes), 0);
+ input_location = saved_loc;
+ return ret;
}
static bool target_clone_pass;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c94d808a1de..85bed9e2f45 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
2016-11-18 Jakub Jelinek <jakub@redhat.com>
+ PR middle-end/78419
+ * gcc.target/i386/pr78419.c: New test.
+
PR c++/77285
* g++.dg/tls/pr77285-1.C: New test.
* g++.dg/tls/pr77285-2.C: New test.
diff --git a/gcc/testsuite/gcc.target/i386/pr78419.c b/gcc/testsuite/gcc.target/i386/pr78419.c
new file mode 100644
index 00000000000..1109193f72a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr78419.c
@@ -0,0 +1,23 @@
+/* PR middle-end/78419 */
+/* { dg-do compile } */
+
+static double bar (double *__restrict, double *__restrict, int)
+__attribute__ ((target_clones("avx,foo,avx2,avx512f,default")));
+
+double
+foo (double *__restrict a, double *__restrict b, int n)
+{
+ return bar (a,b,n);
+}
+
+double
+bar (double *__restrict a, double *__restrict b, int n) /* { dg-error "attribute\[^\n\r]*foo\[^\n\r]* is unknown" } */
+{
+ double s;
+ int i;
+ s = 0.0;
+ for (i=0; i<n; i++)
+ s += a[i] + b[i];
+
+ return s;
+}