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 <ja...@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. --- 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) +{ +} Jakub