Message ID | 0d2f9afa-b0fb-b81b-aba4-1f7f1faa5f35@suse.cz |
---|---|
State | New |
Headers | show |
Series | Reset proper type on vector types (PR middle-end/88587). | expand |
And there's patch with Richi's validation check that he provided.
It fails on following 2 tests in test-suite:
$ ./xgcc -B. /home/marxin/Programming/gcc/gcc/testsuite/gcc.target/i386/pr68674.c
DECL_MODE BLK vs TYPE_MODE V8SI [V8SI]: a
...
$ ./xgcc -B. /home/marxin/Programming/gcc/gcc/testsuite/gcc.target/i386/pr80583.c -c
DECL_MODE BLK vs TYPE_MODE V8SI [V8SI]: a
...
In both cases we access a global variable from a function with a different target
attributes. I guess Honza has seen that in inliner.
What to do with these, can it be potentially dangerous?
Thanks,
Martin
From bf22210f96a2ead9d50e351102f095aadf9d879f Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Wed, 16 Jan 2019 09:05:21 +0100
Subject: [PATCH] Sanitize about VECTOR_TYPEs.
---
gcc/tree-cfg.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 6041f4208b0..fc1dd36fbb7 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -5108,6 +5108,17 @@ verify_node_sharing_1 (tree *tp, int *walk_subtrees, void *data)
{
hash_set<void *> *visited = (hash_set<void *> *) data;
+ if (DECL_P (*tp)
+ && VECTOR_TYPE_P (TREE_TYPE (*tp))
+ && DECL_MODE (*tp) != TYPE_MODE (TREE_TYPE (*tp)))
+ {
+ fprintf (stderr, "DECL_MODE %s vs TYPE_MODE %s [%s]: ",
+ mode_name[DECL_MODE (*tp)],
+ mode_name[TYPE_MODE (TREE_TYPE (*tp))],
+ mode_name[TYPE_MODE_RAW (TREE_TYPE (*tp))]);
+ print_generic_expr (stderr, *tp);
+ fprintf (stderr, "\n");
+ }
if (tree_node_can_be_shared (*tp))
{
*walk_subtrees = false;
On Wed, Jan 16, 2019 at 10:26 AM Martin Liška <mliska@suse.cz> wrote: > > And there's patch with Richi's validation check that he provided. > It fails on following 2 tests in test-suite: > > $ ./xgcc -B. /home/marxin/Programming/gcc/gcc/testsuite/gcc.target/i386/pr68674.c > DECL_MODE BLK vs TYPE_MODE V8SI [V8SI]: a > ... > > $ ./xgcc -B. /home/marxin/Programming/gcc/gcc/testsuite/gcc.target/i386/pr80583.c -c > DECL_MODE BLK vs TYPE_MODE V8SI [V8SI]: a > ... > > In both cases we access a global variable from a function with a different target > attributes. I guess Honza has seen that in inliner. > > What to do with these, can it be potentially dangerous? I guess so. There's not much we can do about this other than making DECL_MODE dynamic the same way as TYPE_MODE. I still believe this is the wrong direction and instead RTL expansion should properly adjust DECL_RTL and generally on GIMPLE we shouldn't need to commit to modes early at all... [but then we eventually want to expose more ABI details to GIMPLE] Richard. > > Thanks, > Martin >
On Wed, Jan 16, 2019 at 12:50:23PM +0100, Richard Biener wrote: > I guess so. There's not much we can do about this other than making > DECL_MODE dynamic the same way as TYPE_MODE. I still believe > this is the wrong direction and instead RTL expansion should properly > adjust DECL_RTL and generally on GIMPLE we shouldn't need to > commit to modes early at all... Are there cases where DECL_MODE (decl) should not be equal to TYPE_MODE (TREE_TYPE (decl))? Is that for structs with flexible array members where the initializer is filling up the flexible array member, or something different? E.g. in expand_debug* it shouldn't be hard to use TYPE_MODE if VECTOR_TYPE_P (TREE_TYPE (decl)), but there are many other uses of DECL_MODE. Jakub
On Wed, Jan 16, 2019 at 12:59 PM Jakub Jelinek <jakub@redhat.com> wrote: > > On Wed, Jan 16, 2019 at 12:50:23PM +0100, Richard Biener wrote: > > I guess so. There's not much we can do about this other than making > > DECL_MODE dynamic the same way as TYPE_MODE. I still believe > > this is the wrong direction and instead RTL expansion should properly > > adjust DECL_RTL and generally on GIMPLE we shouldn't need to > > commit to modes early at all... > > Are there cases where DECL_MODE (decl) should not be equal to > TYPE_MODE (TREE_TYPE (decl))? Is that for structs with flexible array > members where the initializer is filling up the flexible array member, or > something different? ISTR seeing the most differences in FIELD_DECL modes (bitfields? packed fields getting BLKmode but types not being packed/etc.?) > E.g. in expand_debug* it shouldn't be hard to use TYPE_MODE if > VECTOR_TYPE_P (TREE_TYPE (decl)), but there are many other uses of > DECL_MODE. > > Jakub
On Wed, Jan 16, 2019 at 10:20 AM Martin Liška <mliska@suse.cz> wrote: > > Hi. > > The patch is about resetting TYPE_MODE of vector types. This is problematic > when an inlining among different ISAs happen. Then we end up with a different > mode than when it's expected from debug info. > > When creating a new function decl in target_clones, we must valid_attribute_p early > so that the declaration has a proper cl_target_.. node and so that inliner can > fix modes. > > Patch can bootstrap on x86_64-linux-gnu and survives regression tests. > > Ready to be installed? I don't like the new failure mode too much. It looks like create_version_clone_with_body can fail so why not simply return NULL when targetm.target_option.valid_attribute_p returns false and handle that case in multi-versioning? That is, + return !seen_error (); that looks very wrong to me. Richard. > Thanks, > Martin > > gcc/ChangeLog: > > 2019-01-16 Martin Liska <mliska@suse.cz> > Richard Biener <rguenther@suse.de> > > 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 <mliska@suse.cz> > > 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 | 18 +++++++++++++- > gcc/multiple_target.c | 32 ++++++++----------------- > gcc/testsuite/g++.target/i386/pr88587.C | 15 ++++++++++++ > gcc/testsuite/gcc.target/i386/mvc13.c | 9 +++++++ > gcc/tree-inline.c | 4 ++++ > 6 files changed, 61 insertions(+), 24 deletions(-) > create mode 100644 gcc/testsuite/g++.target/i386/pr88587.C > create mode 100644 gcc/testsuite/gcc.target/i386/mvc13.c > >
On 1/16/19 1:06 PM, Richard Biener wrote: > On Wed, Jan 16, 2019 at 10:20 AM Martin Liška <mliska@suse.cz> wrote: >> >> Hi. >> >> The patch is about resetting TYPE_MODE of vector types. This is problematic >> when an inlining among different ISAs happen. Then we end up with a different >> mode than when it's expected from debug info. >> >> When creating a new function decl in target_clones, we must valid_attribute_p early >> so that the declaration has a proper cl_target_.. node and so that inliner can >> fix modes. >> >> Patch can bootstrap on x86_64-linux-gnu and survives regression tests. >> >> Ready to be installed? > > I don't like the new failure mode too much. It looks like > create_version_clone_with_body > can fail so why not simply return NULL when > targetm.target_option.valid_attribute_p > returns false and handle that case in multi-versioning? > > That is, > > + return !seen_error (); > > that looks very wrong to me. Yep, update patch should be better. Patch can bootstrap on x86_64-linux-gnu and survives regression tests. Ready to be installed? Thanks, Martin > > Richard. > >> Thanks, >> Martin >> >> gcc/ChangeLog: >> >> 2019-01-16 Martin Liska <mliska@suse.cz> >> Richard Biener <rguenther@suse.de> >> >> 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 <mliska@suse.cz> >> >> 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 | 18 +++++++++++++- >> gcc/multiple_target.c | 32 ++++++++----------------- >> gcc/testsuite/g++.target/i386/pr88587.C | 15 ++++++++++++ >> gcc/testsuite/gcc.target/i386/mvc13.c | 9 +++++++ >> gcc/tree-inline.c | 4 ++++ >> 6 files changed, 61 insertions(+), 24 deletions(-) >> create mode 100644 gcc/testsuite/g++.target/i386/pr88587.C >> create mode 100644 gcc/testsuite/gcc.target/i386/mvc13.c >> >> From 3deeb24418fa5078a407ff6fee6d9d958b9ea869 Mon Sep 17 00:00:00 2001 From: marxin <mliska@suse.cz> 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 <mliska@suse.cz> Richard Biener <rguenther@suse.de> 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 <mliska@suse.cz> 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<cgraph_edge *> redirect_callers, vec<ipa_replace_map *, va_gc> *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<cgraph_edge *> redirect_callers, vec<ipa_replace_map *, va_gc> *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;
On Thu, Jan 17, 2019 at 12:21 PM Martin Liška <mliska@suse.cz> wrote: > > On 1/16/19 1:06 PM, Richard Biener wrote: > > On Wed, Jan 16, 2019 at 10:20 AM Martin Liška <mliska@suse.cz> wrote: > >> > >> Hi. > >> > >> The patch is about resetting TYPE_MODE of vector types. This is problematic > >> when an inlining among different ISAs happen. Then we end up with a different > >> mode than when it's expected from debug info. > >> > >> When creating a new function decl in target_clones, we must valid_attribute_p early > >> so that the declaration has a proper cl_target_.. node and so that inliner can > >> fix modes. > >> > >> Patch can bootstrap on x86_64-linux-gnu and survives regression tests. > >> > >> Ready to be installed? > > > > I don't like the new failure mode too much. It looks like > > create_version_clone_with_body > > can fail so why not simply return NULL when > > targetm.target_option.valid_attribute_p > > returns false and handle that case in multi-versioning? > > > > That is, > > > > + return !seen_error (); > > > > that looks very wrong to me. > > Yep, update patch should be better. > > Patch can bootstrap on x86_64-linux-gnu and survives regression tests. > > Ready to be installed? OK. Thanks, Richard. > Thanks, > Martin > > > > > Richard. > > > >> Thanks, > >> Martin > >> > >> gcc/ChangeLog: > >> > >> 2019-01-16 Martin Liska <mliska@suse.cz> > >> Richard Biener <rguenther@suse.de> > >> > >> 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 <mliska@suse.cz> > >> > >> 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 | 18 +++++++++++++- > >> gcc/multiple_target.c | 32 ++++++++----------------- > >> gcc/testsuite/g++.target/i386/pr88587.C | 15 ++++++++++++ > >> gcc/testsuite/gcc.target/i386/mvc13.c | 9 +++++++ > >> gcc/tree-inline.c | 4 ++++ > >> 6 files changed, 61 insertions(+), 24 deletions(-) > >> create mode 100644 gcc/testsuite/g++.target/i386/pr88587.C > >> create mode 100644 gcc/testsuite/gcc.target/i386/mvc13.c > >> > >> >
On Thu, Jan 17, 2019 at 4:51 AM Richard Biener <richard.guenther@gmail.com> wrote: > > On Thu, Jan 17, 2019 at 12:21 PM Martin Liška <mliska@suse.cz> wrote: > > > > On 1/16/19 1:06 PM, Richard Biener wrote: > > > On Wed, Jan 16, 2019 at 10:20 AM Martin Liška <mliska@suse.cz> wrote: > > >> > > >> Hi. > > >> > > >> The patch is about resetting TYPE_MODE of vector types. This is problematic > > >> when an inlining among different ISAs happen. Then we end up with a different > > >> mode than when it's expected from debug info. > > >> > > >> When creating a new function decl in target_clones, we must valid_attribute_p early > > >> so that the declaration has a proper cl_target_.. node and so that inliner can > > >> fix modes. > > >> > > >> Patch can bootstrap on x86_64-linux-gnu and survives regression tests. > > >> > > >> Ready to be installed? > > > > > > I don't like the new failure mode too much. It looks like > > > create_version_clone_with_body > > > can fail so why not simply return NULL when > > > targetm.target_option.valid_attribute_p > > > returns false and handle that case in multi-versioning? > > > > > > That is, > > > > > > + return !seen_error (); > > > > > > that looks very wrong to me. > > > > Yep, update patch should be better. > > > > Patch can bootstrap on x86_64-linux-gnu and survives regression tests. > > > > Ready to be installed? > > OK. > > Thanks, > Richard. > > > Thanks, > > Martin > > > > > > > > Richard. > > > > > >> Thanks, > > >> Martin > > >> > > >> gcc/ChangeLog: > > >> > > >> 2019-01-16 Martin Liska <mliska@suse.cz> > > >> Richard Biener <rguenther@suse.de> > > >> > > >> 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 <mliska@suse.cz> > > >> > > >> 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 | 18 +++++++++++++- > > >> gcc/multiple_target.c | 32 ++++++++----------------- > > >> gcc/testsuite/g++.target/i386/pr88587.C | 15 ++++++++++++ > > >> gcc/testsuite/gcc.target/i386/mvc13.c | 9 +++++++ > > >> gcc/tree-inline.c | 4 ++++ > > >> 6 files changed, 61 insertions(+), 24 deletions(-) > > >> create mode 100644 gcc/testsuite/g++.target/i386/pr88587.C > > >> create mode 100644 gcc/testsuite/gcc.target/i386/mvc13.c > > >> > > >> > > It is wrong to use -m32 in dg-options: /* { dg-do compile } */ /* { dg-require-ifunc "" } */ /* { dg-options "-O -m32 -g -mno-sse" } */ You should use /* { dg-do compile { target ia32 } } */ Since g++.target/i386/pr88587.C doesn't support -fPIC, [hjl@gnu-cfl-1 gcc]$ ./xgcc -B./ /export/gnu/import/git/sources/gcc/gcc/testsuite/g++.target/i386/pr88587.C -mx32 -fpic -S /export/gnu/import/git/sources/gcc/gcc/testsuite/g++.target/i386/pr88587.C:6:6: warning: always_inline function might not be inlinable [-Wattributes] 6 | void a() | ^ /export/gnu/import/git/sources/gcc/gcc/testsuite/g++.target/i386/pr88587.C: In function \u2018void a2()\u2019: /export/gnu/import/git/sources/gcc/gcc/testsuite/g++.target/i386/pr88587.C:6:6: error: inlining failed in call to always_inline \u2018void a()\u2019: function body can be overwritten at link time /export/gnu/import/git/sources/gcc/gcc/testsuite/g++.target/i386/pr88587.C:13:5: note: called from here 13 | a (); | ~~^~ [hjl@gnu-cfl-1 gcc]$ you should add -fno-pic.
On Fri, Jan 18, 2019 at 6:25 AM H.J. Lu <hjl.tools@gmail.com> wrote: > > On Thu, Jan 17, 2019 at 4:51 AM Richard Biener > <richard.guenther@gmail.com> wrote: > > > > On Thu, Jan 17, 2019 at 12:21 PM Martin Liška <mliska@suse.cz> wrote: > > > > > > On 1/16/19 1:06 PM, Richard Biener wrote: > > > > On Wed, Jan 16, 2019 at 10:20 AM Martin Liška <mliska@suse.cz> wrote: > > > >> > > > >> Hi. > > > >> > > > >> The patch is about resetting TYPE_MODE of vector types. This is problematic > > > >> when an inlining among different ISAs happen. Then we end up with a different > > > >> mode than when it's expected from debug info. > > > >> > > > >> When creating a new function decl in target_clones, we must valid_attribute_p early > > > >> so that the declaration has a proper cl_target_.. node and so that inliner can > > > >> fix modes. > > > >> > > > >> Patch can bootstrap on x86_64-linux-gnu and survives regression tests. > > > >> > > > >> Ready to be installed? > > > > > > > > I don't like the new failure mode too much. It looks like > > > > create_version_clone_with_body > > > > can fail so why not simply return NULL when > > > > targetm.target_option.valid_attribute_p > > > > returns false and handle that case in multi-versioning? > > > > > > > > That is, > > > > > > > > + return !seen_error (); > > > > > > > > that looks very wrong to me. > > > > > > Yep, update patch should be better. > > > > > > Patch can bootstrap on x86_64-linux-gnu and survives regression tests. > > > > > > Ready to be installed? > > > > OK. > > > > Thanks, > > Richard. > > > > > Thanks, > > > Martin > > > > > > > > > > > Richard. > > > > > > > >> Thanks, > > > >> Martin > > > >> > > > >> gcc/ChangeLog: > > > >> > > > >> 2019-01-16 Martin Liska <mliska@suse.cz> > > > >> Richard Biener <rguenther@suse.de> > > > >> > > > >> 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 <mliska@suse.cz> > > > >> > > > >> 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 | 18 +++++++++++++- > > > >> gcc/multiple_target.c | 32 ++++++++----------------- > > > >> gcc/testsuite/g++.target/i386/pr88587.C | 15 ++++++++++++ > > > >> gcc/testsuite/gcc.target/i386/mvc13.c | 9 +++++++ > > > >> gcc/tree-inline.c | 4 ++++ > > > >> 6 files changed, 61 insertions(+), 24 deletions(-) > > > >> create mode 100644 gcc/testsuite/g++.target/i386/pr88587.C > > > >> create mode 100644 gcc/testsuite/gcc.target/i386/mvc13.c > > > >> > > > >> > > > > > It is wrong to use -m32 in dg-options: > > /* { dg-do compile } */ > /* { dg-require-ifunc "" } */ > /* { dg-options "-O -m32 -g -mno-sse" } */ > > You should use > > /* { dg-do compile { target ia32 } } */ > > Since g++.target/i386/pr88587.C doesn't support -fPIC, > > [hjl@gnu-cfl-1 gcc]$ ./xgcc -B./ > /export/gnu/import/git/sources/gcc/gcc/testsuite/g++.target/i386/pr88587.C > -mx32 -fpic -S > /export/gnu/import/git/sources/gcc/gcc/testsuite/g++.target/i386/pr88587.C:6:6: > warning: always_inline function might not be inlinable [-Wattributes] > 6 | void a() > | ^ > /export/gnu/import/git/sources/gcc/gcc/testsuite/g++.target/i386/pr88587.C: > In function \u2018void a2()\u2019: > /export/gnu/import/git/sources/gcc/gcc/testsuite/g++.target/i386/pr88587.C:6:6: > error: inlining failed in call to always_inline \u2018void a()\u2019: > function body can be overwritten at link time > /export/gnu/import/git/sources/gcc/gcc/testsuite/g++.target/i386/pr88587.C:13:5: > note: called from here > 13 | a (); > | ~~^~ > [hjl@gnu-cfl-1 gcc]$ > > you should add -fno-pic. > I am checking in this patch as an obvious fix.
Hi. Apparently, there's one another PR: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90083 May I backport the patch to GCC-8 branch? Thanks, Martin
On Mon, Apr 15, 2019 at 8:48 AM Martin Liška <mliska@suse.cz> wrote: > > Hi. > > Apparently, there's one another PR: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90083 > > May I backport the patch to GCC-8 branch? Hmm, it isn't a regression, right? But it only affects multi-versioning, so yes, go ahead. Might as well consider GCC 7 then - do you have an overall idea of the state of the MV stuff on branches? IIRC you've done most of the "fixes"? Richard. > Thanks, > Martin
On 4/15/19 9:27 AM, Richard Biener wrote: > On Mon, Apr 15, 2019 at 8:48 AM Martin Liška <mliska@suse.cz> wrote: >> >> Hi. >> >> Apparently, there's one another PR: >> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90083 >> >> May I backport the patch to GCC-8 branch? > > Hmm, it isn't a regression, right? But it only > affects multi-versioning, so yes, go ahead. No, it's not. The issue is very old. > Might as well consider GCC 7 then - do you have > an overall idea of the state of the MV stuff on branches? Well, I've made quite some changes to target_clone pass (multiple_target.c). Thus I would ignore GCC-7 if possible. Martin > IIRC you've done most of the "fixes"? > > Richard. > >> Thanks, >> Martin
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<cgraph_edge *> redirect_callers, vec<ipa_replace_map *, va_gc> *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..f1c0351584d 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<cgraph_edge *> redirect_callers, vec<ipa_replace_map *, va_gc> *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,17 @@ 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); + targetm.target_option.valid_attribute_p (new_decl, NULL, v, 0); + input_location = saved_loc; + } + /* 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..fcec0f4676d 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,14 @@ 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); 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 +402,14 @@ 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); + tree attributes = make_attribute ("target", attr, + DECL_ATTRIBUTES (node->decl)); + + cgraph_node *new_node = create_target_clone (node, definition, suffix, + attributes); 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)) - return false; - - input_location = saved_loc; decl2_v = new_node->function_version (); if (decl2_v != NULL) continue; @@ -442,13 +436,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 !seen_error (); } /* 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;