cgraphclones: Fix up target_clones cloning of functions with vector arguments [PR105554]

Message ID ZBQkoxouS5jRLwv5@tucnak
State New
Headers
Series cgraphclones: Fix up target_clones cloning of functions with vector arguments [PR105554] |

Commit Message

Jakub Jelinek March 17, 2023, 8:28 a.m. UTC
  Hi!

multiple_target.cc is the only caller of create_version_clone_with_body
which calls it with non-NULL target_attributes.  The attributes are
finalized soon after new_decl is created and then tree_function_versioning
is called.  This temporarily sets DECL_RESULT and DECL_ARGUMENTS of
new_decl to the ones of old_decl, after all usually we don't have the
arguments yet and then it initializes cfun for the new function, so that
we can later e.g. remap the arguments which needs the inlining
infrastructure and dest_cfun in id.  Now, initialize_cfun calls
allocate_function which with the new cfun pushed does:
4845		  /* Now that we have activated any function-specific attributes
4846		     that might affect layout, particularly vector modes, relayout
4847		     each of the parameters and the result.  */
4848		  relayout_decl (result);
4849		  for (tree parm = DECL_ARGUMENTS (fndecl); parm;
4850		       parm = DECL_CHAIN (parm))
4851		    relayout_decl (parm);
Normally that is the correct thing to do, but because in this case
DECL_RESULT and DECL_ARGUMENTs are those from old_decl until we change it,
the above actually could have changed DECL_MODE of DECL_RESULT and
DECL_ARGUMENTS if any of that has vector type and whether a vector_type_mode
differs between the old_decl and new_decl enabled ISAs.

I don't have an idea how to cleanly resolve this on the
tree_function_versioning side, plus most of the time this isn't a problem
because usually tree_function_versioning works between old_decl and new_decl
with same target attributes.  So, the following patch instead fixes it up
afterwards, doing the relayout_decl again on old_decl to restore it back.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2023-03-17  Jakub Jelinek  <jakub@redhat.com>

	PR target/105554
	* cgraphclones.cc: Include stor-layout.h.
	(cgraph_node::create_version_clone_with_body): If target_attributes,
	relayout DECL_RESULT and DECL_ARGUMENTS of old_decl back after
	tree_function_versioning.

	* gcc.target/i386/pr105554.c: New test.


	Jakub
  

Patch

--- gcc/cgraphclones.cc.jj	2023-02-24 11:05:19.704595633 +0100
+++ gcc/cgraphclones.cc	2023-03-16 19:46:14.592006501 +0100
@@ -87,6 +87,7 @@  along with GCC; see the file COPYING3.
 #include "ipa-fnsummary.h"
 #include "symtab-thunks.h"
 #include "symtab-clones.h"
+#include "stor-layout.h"
 
 /* Create clone of edge in the node N represented by CALL_EXPR
    the callgraph.  */
@@ -1094,6 +1095,19 @@  cgraph_node::create_version_clone_with_b
       || in_lto_p)
     new_version_node->unique_name = true;
 
+  if (target_attributes)
+    {
+      /* tree_function_versioning temporarily copies old_decl's DECL_RESULT
+	 and DECL_ARGUMENTS to new_decl, then allocate_struct_function
+	 which will relayout_decl those.  Relayout them back.  */
+      push_cfun (DECL_STRUCT_FUNCTION (old_decl));
+      relayout_decl (DECL_RESULT (old_decl));
+      for (tree parm = DECL_ARGUMENTS (old_decl);
+	   parm; parm = DECL_CHAIN (parm))
+	relayout_decl (parm);
+      pop_cfun ();
+    }
+
   /* Update the call_expr on the edges to call the new version node. */
   update_call_expr (new_version_node);
 
--- gcc/testsuite/gcc.target/i386/pr105554.c.jj	2023-03-16 19:50:58.126884823 +0100
+++ gcc/testsuite/gcc.target/i386/pr105554.c	2023-03-16 19:50:25.031365400 +0100
@@ -0,0 +1,10 @@ 
+/* PR target/105554 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wno-psabi -mno-sse3" } */
+
+typedef long long v4di __attribute__((__vector_size__(32)));
+
+__attribute__((target_clones ("arch=core-avx2", "default"))) void
+foo (v4di x)
+{
+}