diff --git a/gcc/attribs.cc b/gcc/attribs.cc index c63d13d7e55..99f2fd75531 100644 --- a/gcc/attribs.cc +++ b/gcc/attribs.cc @@ -1230,7 +1230,11 @@ make_dispatcher_decl (const tree decl) /* Set flags on the cgraph_node for the new decl. */ cgraph_node *func_node = cgraph_node::get_create (func_decl); func_node->dispatcher_function = true; - func_node->definition = true; + /* For targets with TARGET_HAS_FMV_TARGET_ATTRIBUTE, the resolver is created + unconditionally if any versioned nodes are present. + For !TARGET_HAS_FMV_TARGET_ATTRIBUTE, the dispatcher is only defined when + the default node is defined. */ + func_node->definition = node->definition || TARGET_HAS_FMV_TARGET_ATTRIBUTE; cgraph_function_version_info *func_v = func_node->insert_new_function_version (); diff --git a/gcc/ipa.cc b/gcc/ipa.cc index ca939c9c118..d1a0bb8ce1d 100644 --- a/gcc/ipa.cc +++ b/gcc/ipa.cc @@ -441,16 +441,6 @@ symbol_table::remove_unreachable_nodes (FILE *file) } } - /* A reference to the default node implies use of all the other - versions (they get used in the function resolver made later - in multiple_target.cc) */ - cgraph_function_version_info *node_v = cnode->function_version (); - if (node_v && is_function_default_version (node->decl)) - for (cgraph_function_version_info *fvi = node_v->next; - fvi; - fvi = fvi->next) - enqueue_node (fvi->this_node, &first, &reachable); - for (e = cnode->callees; e; e = e->next_callee) { symtab_node *body = e->callee->function_symbol (); @@ -494,6 +484,15 @@ symbol_table::remove_unreachable_nodes (FILE *file) else if (cnode->thunk) enqueue_node (cnode->callees->callee, &first, &reachable); + /* A reference to the default node implies use of all the other + versions (they get used in the function resolver made later + in multiple_target.cc) */ + cgraph_function_version_info *node_v = cnode->function_version (); + if (node_v && is_function_default_version (node->decl)) + for (cgraph_function_version_info *fvi = node_v->next; fvi; + fvi = fvi->next) + enqueue_node (fvi->this_node, &first, &reachable); + /* If any reachable function has simd clones, mark them as reachable as well. */ if (cnode->simd_clones) diff --git a/gcc/testsuite/gcc.target/aarch64/pr124167.c b/gcc/testsuite/gcc.target/aarch64/pr124167.c new file mode 100644 index 00000000000..4ba94b0fe9a --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr124167.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ + +/* Check there is no ICE. */ + +__attribute__ ((target_version ("default"))) int foo (); + +int bar () { return foo (); }