This is a partial patch to make the mangling of function version names for target_clones match those generated using the target or target_version attributes. It modifies the name of function versions, but does not yet rename the resolved symbol, resulting in a duplicate symbol name (and an error at assembly time).
Is this sort of approach ok? Should I create an extra target hook to be called here, so that the target_clones mangling can be target-specific but not necessarily the same as for target attribute versioning? diff --git a/gcc/cgraphclones.cc b/gcc/cgraphclones.cc index 8af6b23d8c0306920e0fdcb3559ef047a16689f4..15672c02c6f9d6043a36bf081067f08d1ab834e5 100644 --- a/gcc/cgraphclones.cc +++ b/gcc/cgraphclones.cc @@ -1033,11 +1033,6 @@ cgraph_node::create_version_clone_with_body else new_decl = copy_node (old_decl); - /* Generate a new name for the new version. */ - tree fnname = (version_decl ? clone_function_name_numbered (old_decl, suffix) - : clone_function_name (old_decl, suffix)); - DECL_NAME (new_decl) = fnname; - SET_DECL_ASSEMBLER_NAME (new_decl, fnname); SET_DECL_RTL (new_decl, NULL); DECL_VIRTUAL_P (new_decl) = 0; @@ -1065,6 +1060,24 @@ cgraph_node::create_version_clone_with_body return NULL; } + /* Generate a new name for the new version. */ + if (version_decl) + { + tree fnname = (clone_function_name_numbered (old_decl, suffix)); + DECL_NAME (new_decl) = fnname; + SET_DECL_ASSEMBLER_NAME (new_decl, fnname); + } + else + { + /* Add target version mangling. We assume that the target hook will + produce the same mangled name as it would have produced if the decl + had already been versioned when the hook was previously called. */ + tree fnname = DECL_ASSEMBLER_NAME (old_decl); + DECL_NAME (new_decl) = fnname; + fnname = targetm.mangle_decl_assembler_name (new_decl, fnname); + SET_DECL_ASSEMBLER_NAME (new_decl, fnname); + } + /* 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.cc b/gcc/multiple_target.cc index 3db57c2b13d612a37240d9dcf58ad21b2286633c..d9aec9a5ab532701b4a1877b440f3a553ffa28e2 100644 --- a/gcc/multiple_target.cc +++ b/gcc/multiple_target.cc @@ -162,7 +162,12 @@ create_dispatcher_calls (struct cgraph_node *node) } } - tree fname = clone_function_name (node->decl, "default"); + /* Add version mangling to default decl name. We assume that the target + hook will produce the same mangled name as it would have produced if the + decl had already been versioned when the hook was previously called. */ + tree fname = DECL_ASSEMBLER_NAME (node->decl); + DECL_NAME (node->decl) = fname; + fname = targetm.mangle_decl_assembler_name (node->decl, fname); symtab->change_decl_assembler_name (node->decl, fname); if (node->definition)