From 3deeb24418fa5078a407ff6fee6d9d958b9ea869 Mon Sep 17 00:00:00 2001 From: marxin Date: Wed, 16 Jan 2019 09:05:02 +0100 Subject: [PATCH] Reset proper type on vector types (PR middle-end/88587). gcc/ChangeLog: 2019-01-16 Martin Liska Richard Biener PR middle-end/88587 * cgraph.h (create_version_clone_with_body): Add new argument with attributes. * cgraphclones.c (cgraph_node::create_version_clone): Add DECL_ATTRIBUTES to a newly created decl. And call valid_attribute_p so that proper cl_target_optimization_node is set for the newly created declaration. * multiple_target.c (create_target_clone): Set DECL_ATTRIBUTES for declaration. (expand_target_clones): Do not call valid_attribute_p, it must be already done. * tree-inline.c (copy_decl_for_dup_finish): Reset mode for vector types. gcc/testsuite/ChangeLog: 2019-01-16 Martin Liska PR middle-end/88587 * g++.target/i386/pr88587.C: New test. * gcc.target/i386/mvc13.c: New test. --- gcc/cgraph.h | 7 ++++- gcc/cgraphclones.c | 20 +++++++++++++- gcc/multiple_target.c | 36 ++++++++++--------------- gcc/testsuite/g++.target/i386/pr88587.C | 15 +++++++++++ gcc/testsuite/gcc.target/i386/mvc13.c | 9 +++++++ gcc/tree-inline.c | 4 +++ 6 files changed, 67 insertions(+), 24 deletions(-) create mode 100644 gcc/testsuite/g++.target/i386/pr88587.C create mode 100644 gcc/testsuite/gcc.target/i386/mvc13.c diff --git a/gcc/cgraph.h b/gcc/cgraph.h index c016da3875c..bb231833328 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -1019,12 +1019,17 @@ public: If non-NULL BLOCK_TO_COPY determine what basic blocks to copy. If non_NULL NEW_ENTRY determine new entry BB of the clone. + If TARGET_ATTRIBUTES is non-null, when creating a new declaration, + add the attributes to DECL_ATTRIBUTES. And call valid_attribute_p + that will promote value of the attribute DECL_FUNCTION_SPECIFIC_TARGET + of the declaration. + Return the new version's cgraph node. */ cgraph_node *create_version_clone_with_body (vec redirect_callers, vec *tree_map, bitmap args_to_skip, bool skip_return, bitmap bbs_to_copy, basic_block new_entry_block, - const char *clone_name); + const char *clone_name, tree target_attributes = NULL_TREE); /* Insert a new cgraph_function_version_info node into cgraph_fnver_htab corresponding to cgraph_node. */ diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c index 4688de91cfe..15f7e119d18 100644 --- a/gcc/cgraphclones.c +++ b/gcc/cgraphclones.c @@ -1012,6 +1012,11 @@ cgraph_node::create_version_clone (tree new_decl, If non-NULL BLOCK_TO_COPY determine what basic blocks to copy. If non_NULL NEW_ENTRY determine new entry BB of the clone. + If TARGET_ATTRIBUTES is non-null, when creating a new declaration, + add the attributes to DECL_ATTRIBUTES. And call valid_attribute_p + that will promote value of the attribute DECL_FUNCTION_SPECIFIC_TARGET + of the declaration. + Return the new version's cgraph node. */ cgraph_node * @@ -1019,7 +1024,7 @@ cgraph_node::create_version_clone_with_body (vec redirect_callers, vec *tree_map, bitmap args_to_skip, bool skip_return, bitmap bbs_to_copy, basic_block new_entry_block, - const char *suffix) + const char *suffix, tree target_attributes) { tree old_decl = decl; cgraph_node *new_version_node = NULL; @@ -1044,6 +1049,19 @@ cgraph_node::create_version_clone_with_body DECL_VIRTUAL_P (new_decl) = 0; + if (target_attributes) + { + DECL_ATTRIBUTES (new_decl) = target_attributes; + + location_t saved_loc = input_location; + tree v = TREE_VALUE (target_attributes); + input_location = DECL_SOURCE_LOCATION (new_decl); + bool r = targetm.target_option.valid_attribute_p (new_decl, NULL, v, 0); + input_location = saved_loc; + if (!r) + return NULL; + } + /* When the old decl was a con-/destructor make sure the clone isn't. */ DECL_STATIC_CONSTRUCTOR (new_decl) = 0; DECL_STATIC_DESTRUCTOR (new_decl) = 0; diff --git a/gcc/multiple_target.c b/gcc/multiple_target.c index 589d059424a..6126f42d7bf 100644 --- a/gcc/multiple_target.c +++ b/gcc/multiple_target.c @@ -294,7 +294,8 @@ create_new_asm_name (char *old_asm_name, char *new_asm_name) /* Creates target clone of NODE. */ static cgraph_node * -create_target_clone (cgraph_node *node, bool definition, char *name) +create_target_clone (cgraph_node *node, bool definition, char *name, + tree attributes) { cgraph_node *new_node; @@ -303,13 +304,16 @@ create_target_clone (cgraph_node *node, bool definition, char *name) new_node = node->create_version_clone_with_body (vNULL, NULL, NULL, false, NULL, NULL, - name); + name, attributes); + if (new_node == NULL) + return NULL; new_node->force_output = true; } else { tree new_decl = copy_node (node->decl); new_node = cgraph_node::get_create (new_decl); + DECL_ATTRIBUTES (new_decl) = attributes; /* Generate a new name for the new version. */ symtab->change_decl_assembler_name (new_node->decl, clone_function_name_numbered ( @@ -400,22 +404,16 @@ expand_target_clones (struct cgraph_node *node, bool definition) create_new_asm_name (attr, suffix); /* Create new target clone. */ - cgraph_node *new_node = create_target_clone (node, definition, suffix); - new_node->local.local = false; - 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)) + DECL_ATTRIBUTES (node->decl)); + + cgraph_node *new_node = create_target_clone (node, definition, suffix, + attributes); + if (new_node == NULL) return false; + new_node->local.local = false; + XDELETEVEC (suffix); - input_location = saved_loc; decl2_v = new_node->function_version (); if (decl2_v != NULL) continue; @@ -442,13 +440,7 @@ expand_target_clones (struct cgraph_node *node, bool definition) DECL_ATTRIBUTES (node->decl)); DECL_ATTRIBUTES (node->decl) = attributes; node->local.local = false; - 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; + return true; } /* When NODE is a target clone, consider all callees and redirect diff --git a/gcc/testsuite/g++.target/i386/pr88587.C b/gcc/testsuite/g++.target/i386/pr88587.C new file mode 100644 index 00000000000..6808ab68cbb --- /dev/null +++ b/gcc/testsuite/g++.target/i386/pr88587.C @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O -m32 -g -mno-sse -Wno-attributes" } */ + +__attribute__((target("default"),always_inline)) +void a() +{ + __attribute__((__vector_size__(4 * sizeof(float)))) int b = {}; +} + +__attribute__((target("sse2"))) void a2() +{ + a (); + __attribute__((__vector_size__(4 * sizeof(float)))) int b = {}; +} diff --git a/gcc/testsuite/gcc.target/i386/mvc13.c b/gcc/testsuite/gcc.target/i386/mvc13.c new file mode 100644 index 00000000000..9e31ef7c4da --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/mvc13.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-O -m32 -g -mno-sse" } */ + +__attribute__((target_clones("default,sse2"))) +void a() +{ + __attribute__((__vector_size__(4 * sizeof(float)))) int b = {}; +} diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 88620770212..1c2766d4799 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -5479,6 +5479,10 @@ copy_decl_for_dup_finish (copy_body_data *id, tree decl, tree copy) if (CODE_CONTAINS_STRUCT (TREE_CODE (copy), TS_DECL_WRTL) && !TREE_STATIC (copy) && !DECL_EXTERNAL (copy)) SET_DECL_RTL (copy, 0); + /* For vector typed decls make sure to update DECL_MODE according + to the new function context. */ + if (VECTOR_TYPE_P (TREE_TYPE (copy))) + SET_DECL_MODE (copy, TYPE_MODE (TREE_TYPE (copy))); /* These args would always appear unused, if not for this. */ TREE_USED (copy) = 1; -- 2.20.1