On 1/16/19 1:06 PM, Richard Biener wrote:
> On Wed, Jan 16, 2019 at 10:20 AM Martin Liška <mli...@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  <mli...@suse.cz>
>>             Richard Biener  <rguent...@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  <mli...@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 <mli...@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  <mli...@suse.cz>
	    Richard Biener  <rguent...@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  <mli...@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;
-- 
2.20.1

Reply via email to