Alfie Richards <alfie.richa...@arm.com> writes: > This changes behavior of target_clones and target_version attributes > to be inline with what is specified in the Arm C Language Extension. > > Notably this changes the scope and signature of multiversioned functions > to that of the default version, and changes the resolver to be > created at the implementation of the default version. > > This is achieved by changing the C++ front end to no longer resolve any > non-default version decls in lookup, and by moving dipatching > for default_target sets to reuse the dispatching logic for target_clones > in multiple_target.cc. > > The dispatching in create_dispatcher_calls is changed for the case of > a lone annotated default function to change the dispatched symbol to > be an alias for the mangled default function.
Heh, nice trick. I agree that conceptually it's also a a very clean solution, but I don't know the cgraph internals well enough to know whether there might be dragons. The gcc/*.cc changes look good to me as far as I can review them. Thanks, Richard > > gcc/ChangeLog: > > * cgraphunit.cc (analyze_functions): Add logic for target version > dependencies. > * ipa.cc (symbol_table::remove_unreachable_nodes): Ditto. > * multiple_target.cc (create_dispatcher_calls): Change to support > target version semantics. > (ipa_target_clone): Change to dispatch all function sets in > target_version semantics. > > gcc/cp/ChangeLog: > > * call.cc (add_candidates): Change to not resolve non-default versions > in > target_version semantics. > * class.cc (resolve_address_of_overloaded_function): Ditto. > * cp-gimplify.cc (cp_genericize_r): Change logic to not apply for > target_version semantics. > * decl.cc (start_decl): Change to mark and therefore mangle all > target_version decls. > (start_preparsed_function): Ditto. > * typeck.cc (cp_build_function_call_vec): Add error for calling > unresolvable > non-default node in target_version semantics. > > gcc/testsuite/ChangeLog: > > * g++.target/aarch64/mv-1.C: Change for target_version semantics. > * g++.target/aarch64/mv-symbols2.C: Ditto. > * g++.target/aarch64/mv-symbols3.C: Ditto. > * g++.target/aarch64/mv-symbols4.C: Ditto. > * g++.target/aarch64/mv-symbols5.C: Ditto. > * g++.target/aarch64/mvc-symbols3.C: Ditto. > * g++.target/riscv/mv-symbols2.C: Ditto. > * g++.target/riscv/mv-symbols3.C: Ditto. > * g++.target/riscv/mv-symbols4.C: Ditto. > * g++.target/riscv/mv-symbols5.C: Ditto. > * g++.target/riscv/mvc-symbols3.C: Ditto. > * g++.target/aarch64/mv-symbols10.C: New test. > * g++.target/aarch64/mv-symbols11.C: New test. > * g++.target/aarch64/mv-symbols12.C: New test. > * g++.target/aarch64/mv-symbols13.C: New test. > * g++.target/aarch64/mv-symbols6.C: New test. > * g++.target/aarch64/mv-symbols7.C: New test. > * g++.target/aarch64/mv-symbols8.C: New test. > * g++.target/aarch64/mv-symbols9.C: New test. > --- > gcc/cgraphunit.cc | 9 +++ > gcc/cp/call.cc | 10 +++ > gcc/cp/class.cc | 13 +++- > gcc/cp/cp-gimplify.cc | 11 ++- > gcc/cp/decl.cc | 14 ++++ > gcc/cp/typeck.cc | 10 +++ > gcc/ipa.cc | 11 +++ > gcc/multiple_target.cc | 73 ++++++++++++++++--- > gcc/testsuite/g++.target/aarch64/mv-1.C | 4 + > .../g++.target/aarch64/mv-symbols10.C | 27 +++++++ > .../g++.target/aarch64/mv-symbols11.C | 30 ++++++++ > .../g++.target/aarch64/mv-symbols12.C | 28 +++++++ > .../g++.target/aarch64/mv-symbols13.C | 28 +++++++ > .../g++.target/aarch64/mv-symbols2.C | 12 +-- > .../g++.target/aarch64/mv-symbols3.C | 6 +- > .../g++.target/aarch64/mv-symbols4.C | 6 +- > .../g++.target/aarch64/mv-symbols5.C | 6 +- > .../g++.target/aarch64/mv-symbols6.C | 25 +++++++ > .../g++.target/aarch64/mv-symbols7.C | 48 ++++++++++++ > .../g++.target/aarch64/mv-symbols8.C | 46 ++++++++++++ > .../g++.target/aarch64/mv-symbols9.C | 43 +++++++++++ > .../g++.target/aarch64/mvc-symbols3.C | 12 +-- > gcc/testsuite/g++.target/riscv/mv-symbols2.C | 12 +-- > gcc/testsuite/g++.target/riscv/mv-symbols3.C | 6 +- > gcc/testsuite/g++.target/riscv/mv-symbols4.C | 6 +- > gcc/testsuite/g++.target/riscv/mv-symbols5.C | 6 +- > gcc/testsuite/g++.target/riscv/mvc-symbols3.C | 12 +-- > 27 files changed, 456 insertions(+), 58 deletions(-) > create mode 100644 gcc/testsuite/g++.target/aarch64/mv-symbols10.C > create mode 100644 gcc/testsuite/g++.target/aarch64/mv-symbols11.C > create mode 100644 gcc/testsuite/g++.target/aarch64/mv-symbols12.C > create mode 100644 gcc/testsuite/g++.target/aarch64/mv-symbols13.C > create mode 100644 gcc/testsuite/g++.target/aarch64/mv-symbols6.C > create mode 100644 gcc/testsuite/g++.target/aarch64/mv-symbols7.C > create mode 100644 gcc/testsuite/g++.target/aarch64/mv-symbols8.C > create mode 100644 gcc/testsuite/g++.target/aarch64/mv-symbols9.C > > diff --git a/gcc/cgraphunit.cc b/gcc/cgraphunit.cc > index 82f205488e9..876f5b907bd 100644 > --- a/gcc/cgraphunit.cc > +++ b/gcc/cgraphunit.cc > @@ -1264,6 +1264,15 @@ analyze_functions (bool first_time) > if (!cnode->analyzed) > cnode->analyze (); > > + /* A reference to a default node in a function set implies a > + reference to all versions in the set. */ > + 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); > + > for (edge = cnode->callees; edge; edge = edge->next_callee) > if (edge->callee->definition > && (!DECL_EXTERNAL (edge->callee->decl) > diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc > index 03130f80f86..cc8f2b17297 100644 > --- a/gcc/cp/call.cc > +++ b/gcc/cp/call.cc > @@ -6847,6 +6847,16 @@ add_candidates (tree fns, tree first_arg, const > vec<tree, va_gc> *args, > continue; > } > > + /* Do not resolve any non-default function. Only the default version > + is resolvable (for the target_version attribute semantics.) */ > + if (!TARGET_HAS_FMV_TARGET_ATTRIBUTE > + && TREE_CODE (fn) == FUNCTION_DECL > + && !is_function_default_version (fn)) > + { > + add_ignored_candidate (candidates, fn); > + continue; > + } > + > if (TREE_CODE (fn) == TEMPLATE_DECL) > add_template_candidate (candidates, > fn, > diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc > index df67ec34273..ea19604ede2 100644 > --- a/gcc/cp/class.cc > +++ b/gcc/cp/class.cc > @@ -8845,6 +8845,13 @@ resolve_address_of_overloaded_function (tree > target_type, > if (!constraints_satisfied_p (fn)) > continue; > > + /* For target_version semantics, never resolve a non-default > + version. */ > + if (!TARGET_HAS_FMV_TARGET_ATTRIBUTE > + && TREE_CODE (fn) == FUNCTION_DECL > + && !is_function_default_version (fn)) > + continue; > + > if (undeduced_auto_decl (fn)) > { > /* Force instantiation to do return type deduction. */ > @@ -9070,8 +9077,10 @@ resolve_address_of_overloaded_function (tree > target_type, > /* If a pointer to a function that is multi-versioned is requested, the > pointer to the dispatcher function is returned instead. This works > well because indirectly calling the function will dispatch the right > - function version at run-time. */ > - if (DECL_FUNCTION_VERSIONED (fn)) > + function version at run-time. > + This is done at multiple_target.cc for target_version semantics. */ > + > + if (DECL_FUNCTION_VERSIONED (fn) && TARGET_HAS_FMV_TARGET_ATTRIBUTE) > { > fn = get_function_version_dispatcher (fn); > if (fn == NULL) > diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc > index 45f4e27b8b7..9310205378f 100644 > --- a/gcc/cp/cp-gimplify.cc > +++ b/gcc/cp/cp-gimplify.cc > @@ -2157,13 +2157,16 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, > void *data) > returns the function with the highest target priority, that is, > the version that will checked for dispatching first. If this > version is inlinable, a direct call to this version can be made > - otherwise the call should go through the dispatcher. */ > + otherwise the call should go through the dispatcher. > + This is done at multiple_target.cc for target_version semantics. */ > { > tree fn = cp_get_callee_fndecl_nofold (stmt); > - if (fn && DECL_FUNCTION_VERSIONED (fn) > + if (TARGET_HAS_FMV_TARGET_ATTRIBUTE > + && fn > + && DECL_FUNCTION_VERSIONED (fn) > && (current_function_decl == NULL > - || !targetm.target_option.can_inline_p (current_function_decl, > - fn))) > + || !targetm.target_option.can_inline_p > + (current_function_decl, fn))) > if (tree dis = get_function_version_dispatcher (fn)) > { > mark_versions_used (dis); > diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc > index 4edf5435c35..18a03a88aa4 100644 > --- a/gcc/cp/decl.cc > +++ b/gcc/cp/decl.cc > @@ -6163,6 +6163,13 @@ start_decl (const cp_declarator *declarator, > > was_public = TREE_PUBLIC (decl); > > + /* For target_version semantics, mark any annotated function as versioned > + so that it gets mangled even when on its own in a TU. */ > + if (!TARGET_HAS_FMV_TARGET_ATTRIBUTE > + && TREE_CODE (decl) == FUNCTION_DECL > + && lookup_attribute ("target_version", DECL_ATTRIBUTES (decl))) > + maybe_mark_function_versioned (decl); > + > if ((DECL_EXTERNAL (decl) || TREE_CODE (decl) == FUNCTION_DECL) > && current_function_decl) > { > @@ -18782,6 +18789,13 @@ start_preparsed_function (tree decl1, tree attrs, > int flags) > if (!DECL_OMP_DECLARE_REDUCTION_P (decl1)) > start_lambda_scope (decl1); > > + /* For target_version semantics, mark any annotated function as versioned > + so that it gets mangled even when on its own in a TU. */ > + if (!TARGET_HAS_FMV_TARGET_ATTRIBUTE > + && TREE_CODE (decl1) == FUNCTION_DECL > + && lookup_attribute ("target_version", DECL_ATTRIBUTES (decl1))) > + maybe_mark_function_versioned (decl1); > + > return true; > } > > diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc > index a9c32ff930d..ce95273f176 100644 > --- a/gcc/cp/typeck.cc > +++ b/gcc/cp/typeck.cc > @@ -4439,6 +4439,16 @@ cp_build_function_call_vec (tree function, vec<tree, > va_gc> **params, > return error_mark_node; > fndecl = function; > > + /* For target_version semantics, the funciton set cannot be called > + if there is no default version in scope. */ > + if (!TARGET_HAS_FMV_TARGET_ATTRIBUTE > + && !is_function_default_version (fndecl)) > + { > + if (complain & tf_error) > + error ("no default version in scope"); > + return error_mark_node; > + } > + > /* Convert anything with function type to a pointer-to-function. */ > if (DECL_MAIN_P (function)) > { > diff --git a/gcc/ipa.cc b/gcc/ipa.cc > index 8a7b067a526..dea22ea0b49 100644 > --- a/gcc/ipa.cc > +++ b/gcc/ipa.cc > @@ -433,6 +433,17 @@ symbol_table::remove_unreachable_nodes (FILE *file) > e, &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); > + > for (e = cnode->callees; e; e = e->next_callee) > { > symtab_node *body = e->callee->function_symbol (); > diff --git a/gcc/multiple_target.cc b/gcc/multiple_target.cc > index cd7570a9aad..839c6a4906a 100644 > --- a/gcc/multiple_target.cc > +++ b/gcc/multiple_target.cc > @@ -58,8 +58,15 @@ replace_function_decl (tree *op, int *walk_subtrees, void > *data) > return NULL; > } > > -/* If the call in NODE has multiple target attribute with multiple fields, > - replace it with dispatcher call and create dispatcher (once). */ > +/* In target FMV attributes, if the call in NODE has multiple target > attribute > + with multiple fields, replace it with calls to the dispatched symbol and > + create the disptacher body (once). > + > + In target_version semantics, if it is a lone annotated default, then > + the dispatched symbol is changed to be an alias and no resolver is > + required. Otherwise, redirect all calls and references to the dispatched > + symbol, but only create the resolver body if the default version is > + implemented. */ > > static void > create_dispatcher_calls (struct cgraph_node *node) > @@ -90,13 +97,48 @@ create_dispatcher_calls (struct cgraph_node *node) > > cgraph_node *inode = cgraph_node::get (idecl); > gcc_assert (inode); > - tree resolver_decl = targetm.generate_version_dispatcher_body (inode); > - > - /* Update aliases. */ > - inode->alias = true; > - inode->alias_target = resolver_decl; > - if (!inode->analyzed) > - inode->resolve_alias (cgraph_node::get (resolver_decl)); > + cgraph_function_version_info *inode_info = inode->function_version (); > + gcc_assert (inode_info); > + > + tree resolver_decl = NULL; > + > + /* For target_version semantics, if there is a lone default declaration > + it needs to be mangled, with an alias from the dispatched symbol to the > + default version. */ > + if (!TARGET_HAS_FMV_TARGET_ATTRIBUTE > + && TREE_STATIC (node->decl) > + && inode_info->next > + && !inode_info->next->next) > + { > + inode->alias = true; > + inode->alias_target = inode_info->next->this_node->decl; > + inode->externally_visible = true; > + if (!inode->analyzed) > + inode->resolve_alias > + (cgraph_node::get (inode_info->next->this_node->decl)); > + > + DECL_ATTRIBUTES (idecl) > + = make_attribute ("alias", > + IDENTIFIER_POINTER > + (DECL_ASSEMBLER_NAME > + (inode_info->next->this_node->decl)), > + DECL_ATTRIBUTES (node->decl)); > + TREE_USED (idecl) = true; > + DECL_EXTERNAL (idecl) = false; > + TREE_STATIC (idecl) = true; > + return; > + } > + /* In target_version semantics, only create the resolver if the > + default node is implemented. */ > + else if (TARGET_HAS_FMV_TARGET_ATTRIBUTE || TREE_STATIC (node->decl)) > + { > + resolver_decl = targetm.generate_version_dispatcher_body (inode); > + /* Update aliases. */ > + inode->alias = true; > + inode->alias_target = resolver_decl; > + if (!inode->analyzed) > + inode->resolve_alias (cgraph_node::get (resolver_decl)); > + } > > auto_vec<cgraph_edge *> edges_to_redirect; > /* We need to capture the references by value rather than just pointers to > them > @@ -426,9 +468,20 @@ ipa_target_clone (void) > auto_vec<cgraph_node *> to_dispatch; > > FOR_EACH_FUNCTION (node) > - if (expand_target_clones (node, node->definition)) > + /* Expand all target versions. */ > + if (expand_target_clones (node, node->definition) > + && TARGET_HAS_FMV_TARGET_ATTRIBUTE) > + /* In non target_version semantics, dispatch all target clone sets. */ > to_dispatch.safe_push (node); > > + /* In target_version semantics dispatch all FMV function sets with a > default > + implementation. */ > + if (!TARGET_HAS_FMV_TARGET_ATTRIBUTE) > + FOR_EACH_FUNCTION (node) > + if (is_function_default_version (node->decl) > + && DECL_FUNCTION_VERSIONED (node->decl)) > + to_dispatch.safe_push (node); > + > for (unsigned i = 0; i < to_dispatch.length (); i++) > create_dispatcher_calls (to_dispatch[i]); > > diff --git a/gcc/testsuite/g++.target/aarch64/mv-1.C > b/gcc/testsuite/g++.target/aarch64/mv-1.C > index b10037f1b9b..93b8a136587 100644 > --- a/gcc/testsuite/g++.target/aarch64/mv-1.C > +++ b/gcc/testsuite/g++.target/aarch64/mv-1.C > @@ -37,3 +37,7 @@ int bar() > /* { dg-final { scan-assembler-times "\n_Z3foov\._Mrng:\n" 1 } } */ > /* { dg-final { scan-assembler-times "\n_Z3foov\._MrngMflagm:\n" 1 } } */ > /* { dg-final { scan-assembler-times "\n_Z3foov\._Mflagm:\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n_Z3foov\.resolver:\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n\tbl\t_Z3foov\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3foov, > %gnu_indirect_function\n" 1 } } */ > +/* { dg-final { scan-assembler-times > "\n\t\.set\t_Z3foov,_Z3foov\.resolver\n" 1 } } */ > diff --git a/gcc/testsuite/g++.target/aarch64/mv-symbols10.C > b/gcc/testsuite/g++.target/aarch64/mv-symbols10.C > new file mode 100644 > index 00000000000..92d4ab617d8 > --- /dev/null > +++ b/gcc/testsuite/g++.target/aarch64/mv-symbols10.C > @@ -0,0 +1,27 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O0" } */ > +/* { dg-additional-options "-Wno-experimental-fmv-target" } */ > + > +__attribute__ ((target_version ("default"))) void > +foo (int a = 3); > + > +__attribute__ ((target_version ("sve"))) void > +foo (int a = 4); > + > +void bar() { > + foo(); > +} > + > +__attribute__ ((target_version ("sve"))) void > +foo2 (int a = 6); > + > +__attribute__ ((target_version ("default"))) void > +foo2 (int a = 5); > + > +void bar2() { > + foo2(); > +} > + > + > +/* { dg-final { scan-assembler-times "\n\tmov\tw\[0-9\]\+, 3\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n\tmov\tw\[0-9\]\+, 5\n" 1 } } */ > diff --git a/gcc/testsuite/g++.target/aarch64/mv-symbols11.C > b/gcc/testsuite/g++.target/aarch64/mv-symbols11.C > new file mode 100644 > index 00000000000..dadde22622e > --- /dev/null > +++ b/gcc/testsuite/g++.target/aarch64/mv-symbols11.C > @@ -0,0 +1,30 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O0" } */ > +/* { dg-additional-options "-Wno-experimental-fmv-target" } */ > + > +__attribute__ ((target_version ("default"))) int > +foo () { return 1; } > + > +__attribute__ ((target_version ("dotprod"))) int > +foo () { return 3; } > + > +int (*test)(); > + > +void bar () > +{ > + test = foo; > +} > + > +__attribute__ ((target_version ("default"))) int > +foo2 (); > + > +__attribute__ ((target_version ("dotprod"))) int > +foo2 (); > + > +void bar2 () > +{ > + test = foo2; > +} > + > +/* { dg-final { scan-assembler-times "\n\tadrp\tx\[0-9\]+, _Z3foov\n" 1 } } > */ > +/* { dg-final { scan-assembler-times "\n\tadrp\tx\[0-9\]+, _Z4foo2v\n" 1 } } > */ > diff --git a/gcc/testsuite/g++.target/aarch64/mv-symbols12.C > b/gcc/testsuite/g++.target/aarch64/mv-symbols12.C > new file mode 100644 > index 00000000000..d78ee4b91c5 > --- /dev/null > +++ b/gcc/testsuite/g++.target/aarch64/mv-symbols12.C > @@ -0,0 +1,28 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O0" } */ > +/* { dg-additional-options "-Wno-experimental-fmv-target" } */ > + > +int foo () { > + return 1; > +} > + > +void > +bar () > +{ > + foo (); > +} > + > +__attribute__ ((target_version ("dotprod"))) int > +foo (); > + > +/* { dg-final { scan-assembler-times "\n_Z3foov\.default:\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n_Z3foov\._Mdotprod:\n" 0 } } */ > + > +/* { dg-final { scan-assembler-times "\n_Z3foov\.resolver:\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n\tadrp\tx\[0-9\]+, > _Z3foov\._Mdotprod\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n\tadrp\tx\[0-9\]+, > _Z3foov\.default\n" 1 } } */ > + > +/* { dg-final { scan-assembler-times "\n\tbl\t_Z3foov\n" 1 } } */ > + > +/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3foov, > %gnu_indirect_function\n" 1 } } */ > +/* { dg-final { scan-assembler-times > "\n\t\.set\t_Z3foov,_Z3foov\.resolver\n" 1 } } */ > diff --git a/gcc/testsuite/g++.target/aarch64/mv-symbols13.C > b/gcc/testsuite/g++.target/aarch64/mv-symbols13.C > new file mode 100644 > index 00000000000..997b9bad6d6 > --- /dev/null > +++ b/gcc/testsuite/g++.target/aarch64/mv-symbols13.C > @@ -0,0 +1,28 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O0" } */ > +/* { dg-additional-options "-Wno-experimental-fmv-target" } */ > + > +int foo () { > + return 1; > +} > + > +void bar () > +{ > + int (*test)() = foo; > + > + test(); > +} > + > +__attribute__ ((target_version ("dotprod"))) int foo (); > + > +/* { dg-final { scan-assembler-times "\n_Z3foov\.default:\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n_Z3foov\._Mdotprod:\n" 0 } } */ > + > +/* { dg-final { scan-assembler-times "\n_Z3foov\.resolver:\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n\tadrp\tx\[0-9\]+, > _Z3foov\._Mdotprod\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n\tadrp\tx\[0-9\]+, > _Z3foov\.default\n" 1 } } */ > + > +/* { dg-final { scan-assembler-times "\n\tadrp\tx\[0-9\]+, _Z3foov\n" 1 } } > */ > + > +/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3foov, > %gnu_indirect_function\n" 1 } } */ > +/* { dg-final { scan-assembler-times > "\n\t\.set\t_Z3foov,_Z3foov\.resolver\n" 1 } } */ > diff --git a/gcc/testsuite/g++.target/aarch64/mv-symbols2.C > b/gcc/testsuite/g++.target/aarch64/mv-symbols2.C > index 6da88ddfb48..55f2d48f5e4 100644 > --- a/gcc/testsuite/g++.target/aarch64/mv-symbols2.C > +++ b/gcc/testsuite/g++.target/aarch64/mv-symbols2.C > @@ -41,13 +41,13 @@ int foo (int) > /* { dg-final { scan-assembler-times "\n_Z3foov\.default:\n" 1 } } */ > /* { dg-final { scan-assembler-times "\n_Z3foov\._Mdotprod:\n" 1 } } */ > /* { dg-final { scan-assembler-times "\n_Z3foov\._MsveMsve2:\n" 1 } } */ > -/* { dg-final { scan-assembler-times "\n_Z3foov\.resolver:\n" 0 } } */ > -/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3foov, > %gnu_indirect_function\n" 0 } } */ > -/* { dg-final { scan-assembler-times > "\n\t\.set\t_Z3foov,_Z3foov\.resolver\n" 0 } } */ > +/* { dg-final { scan-assembler-times "\n_Z3foov\.resolver:\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3foov, > %gnu_indirect_function\n" 1 } } */ > +/* { dg-final { scan-assembler-times > "\n\t\.set\t_Z3foov,_Z3foov\.resolver\n" 1 } } */ > > /* { dg-final { scan-assembler-times "\n_Z3fooi\.default:\n" 1 } } */ > /* { dg-final { scan-assembler-times "\n_Z3fooi\._Mdotprod:\n" 1 } } */ > /* { dg-final { scan-assembler-times "\n_Z3fooi\._MsveMsve2:\n" 1 } } */ > -/* { dg-final { scan-assembler-times "\n_Z3fooi\.resolver:\n" 0 } } */ > -/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3fooi, > %gnu_indirect_function\n" 0 } } */ > -/* { dg-final { scan-assembler-times > "\n\t\.set\t_Z3fooi,_Z3fooi\.resolver\n" 0 } } */ > +/* { dg-final { scan-assembler-times "\n_Z3fooi\.resolver:\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3fooi, > %gnu_indirect_function\n" 1 } } */ > +/* { dg-final { scan-assembler-times > "\n\t\.set\t_Z3fooi,_Z3fooi\.resolver\n" 1 } } */ > diff --git a/gcc/testsuite/g++.target/aarch64/mv-symbols3.C > b/gcc/testsuite/g++.target/aarch64/mv-symbols3.C > index 5dd7b49be2a..6ba02a2aae9 100644 > --- a/gcc/testsuite/g++.target/aarch64/mv-symbols3.C > +++ b/gcc/testsuite/g++.target/aarch64/mv-symbols3.C > @@ -29,10 +29,10 @@ int bar() > /* { dg-final { scan-assembler-times "\n_Z3foov\.default:\n" 0 } } */ > /* { dg-final { scan-assembler-times "\n_Z3foov\._Mdotprod:\n" 0 } } */ > /* { dg-final { scan-assembler-times "\n_Z3foov\._MsveMsve2:\n" 0 } } */ > -/* { dg-final { scan-assembler-times "\n_Z3foov\.resolver:\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n_Z3foov\.resolver:\n" 0 } } */ > /* { dg-final { scan-assembler-times "\n\tbl\t_Z3foov\n" 1 } } */ > -/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3foov, > %gnu_indirect_function\n" 1 } } */ > -/* { dg-final { scan-assembler-times > "\n\t\.set\t_Z3foov,_Z3foov\.resolver\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3foov, > %gnu_indirect_function\n" 0 } } */ > +/* { dg-final { scan-assembler-times > "\n\t\.set\t_Z3foov,_Z3foov\.resolver\n" 0 } } */ > > /* { dg-final { scan-assembler-times "\n_Z3fooi\.default:\n" 0 } } */ > /* { dg-final { scan-assembler-times "\n_Z3fooi\._Mdotprod:\n" 0 } } */ > diff --git a/gcc/testsuite/g++.target/aarch64/mv-symbols4.C > b/gcc/testsuite/g++.target/aarch64/mv-symbols4.C > index 4b25d17cc15..cc013c47848 100644 > --- a/gcc/testsuite/g++.target/aarch64/mv-symbols4.C > +++ b/gcc/testsuite/g++.target/aarch64/mv-symbols4.C > @@ -44,6 +44,6 @@ int bar() > /* { dg-final { scan-assembler-times "\n_Z3fooi\.default:\n" 1 } } */ > /* { dg-final { scan-assembler-times "\n_Z3fooi\._Mdotprod:\n" 0 } } */ > /* { dg-final { scan-assembler-times "\n_Z3fooi\._MsveMsve2:\n" 0 } } */ > -/* { dg-final { scan-assembler-times "\n_Z3fooi\.resolver:\n" 0 } } */ > -/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3fooi, > %gnu_indirect_function\n" 0 } } */ > -/* { dg-final { scan-assembler-times > "\n\t\.set\t_Z3fooi,_Z3fooi\.resolver\n" 0 } } */ > +/* { dg-final { scan-assembler-times "\n_Z3fooi\.resolver:\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3fooi, > %gnu_indirect_function\n" 1 } } */ > +/* { dg-final { scan-assembler-times > "\n\t\.set\t_Z3fooi,_Z3fooi\.resolver\n" 1 } } */ > diff --git a/gcc/testsuite/g++.target/aarch64/mv-symbols5.C > b/gcc/testsuite/g++.target/aarch64/mv-symbols5.C > index fac00b20313..1396ca379e4 100644 > --- a/gcc/testsuite/g++.target/aarch64/mv-symbols5.C > +++ b/gcc/testsuite/g++.target/aarch64/mv-symbols5.C > @@ -44,10 +44,10 @@ int bar() > /* { dg-final { scan-assembler-times "\n_Z3foov\.default:\n" 0 } } */ > /* { dg-final { scan-assembler-times "\n_Z3foov\._Mdotprod:\n" 1 } } */ > /* { dg-final { scan-assembler-times "\n_Z3foov\._MsveMsve2:\n" 1 } } */ > -/* { dg-final { scan-assembler-times "\n_Z3foov\.resolver:\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n_Z3foov\.resolver:\n" 0 } } */ > /* { dg-final { scan-assembler-times "\n\tbl\t_Z3foov\n" 1 } } */ > -/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3foov, > %gnu_indirect_function\n" 1 } } */ > -/* { dg-final { scan-assembler-times > "\n\t\.set\t_Z3foov,_Z3foov\.resolver\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3foov, > %gnu_indirect_function\n" 0 } } */ > +/* { dg-final { scan-assembler-times > "\n\t\.set\t_Z3foov,_Z3foov\.resolver\n" 0 } } */ > > /* { dg-final { scan-assembler-times "\n_Z3fooi\.default:\n" 0 } } */ > /* { dg-final { scan-assembler-times "\n_Z3fooi\._Mdotprod:\n" 1 } } */ > diff --git a/gcc/testsuite/g++.target/aarch64/mv-symbols6.C > b/gcc/testsuite/g++.target/aarch64/mv-symbols6.C > new file mode 100644 > index 00000000000..e53d88d8bf3 > --- /dev/null > +++ b/gcc/testsuite/g++.target/aarch64/mv-symbols6.C > @@ -0,0 +1,25 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O0" } */ > +/* { dg-additional-options "-Wno-experimental-fmv-target" } */ > + > +__attribute__ ((target_version ("default"))) int > +foo () > +{ > + return 1; > +} > + > +int bar() > +{ > + return foo(); > +} > + > +/* It is not overly clear what the correct behaviour is in this case. > + This test serves more as a test of consistency for this case rather > + than a test of correctness. */ > + > +/* { dg-final { scan-assembler-times "\n_Z3foov:\n" 0 } } */ > +/* { dg-final { scan-assembler-times "\n_Z3foov\.default:\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n_Z3foov\.resolver:\n" 0 } } */ > +/* { dg-final { scan-assembler-times "bl\t_Z3foov.default\n" 1 } } */ > +/* { dg-final { scan-assembler-times ".global\t_Z3foov\n" 1 } } */ > +/* { dg-final { scan-assembler-times ".set\t_Z3foov,_Z3foov.default\n" 1 } } > */ > diff --git a/gcc/testsuite/g++.target/aarch64/mv-symbols7.C > b/gcc/testsuite/g++.target/aarch64/mv-symbols7.C > new file mode 100644 > index 00000000000..3998adb54a7 > --- /dev/null > +++ b/gcc/testsuite/g++.target/aarch64/mv-symbols7.C > @@ -0,0 +1,48 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O0" } */ > +/* { dg-additional-options "-Wno-experimental-fmv-target" } */ > + > +__attribute__ ((target_version ("dotprod"))) int > +foo (); > + > +__attribute__ ((target_version ("sve+sve2"))) int > +foo (); > + > +__attribute__ ((target_version ("default"))) int > +foo (); > + > +__attribute__ ((target_version ("sve+sve2"))) int > +foo () > +{ > + return 5; > +} > +__attribute__ ((target_version ("dotprod"))) int > +foo () > +{ > + return 3; > +} > +__attribute__ ((target_version ("default"))) int > +foo () > +{ > + return 1; > +} > + > +int > +bar () > +{ > + return foo (); > +} > + > +/* { dg-final { scan-assembler-times "\n_Z3foov\.default:\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n_Z3foov\._Mdotprod:\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n_Z3foov\._MsveMsve2:\n" 1 } } */ > + > +/* { dg-final { scan-assembler-times "\n_Z3foov\.resolver:\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n\tadrp\tx\[0-9\]+, > _Z3foov\._MsveMsve2\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n\tadrp\tx\[0-9\]+, > _Z3foov\._Mdotprod\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n\tadrp\tx\[0-9\]+, > _Z3foov\.default\n" 1 } } */ > + > +/* { dg-final { scan-assembler-times "\n\tbl\t_Z3foov\n" 1 } } */ > + > +/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3foov, > %gnu_indirect_function\n" 1 } } */ > +/* { dg-final { scan-assembler-times > "\n\t\.set\t_Z3foov,_Z3foov\.resolver\n" 1 } } */ > diff --git a/gcc/testsuite/g++.target/aarch64/mv-symbols8.C > b/gcc/testsuite/g++.target/aarch64/mv-symbols8.C > new file mode 100644 > index 00000000000..5983bbd6925 > --- /dev/null > +++ b/gcc/testsuite/g++.target/aarch64/mv-symbols8.C > @@ -0,0 +1,46 @@ > +/* { dg-do compile } */ > +/* { dg-require-ifunc "" } */ > +/* { dg-options "-O0" } */ > +/* { dg-additional-options "-Wno-experimental-fmv-target" } */ > + > +__attribute__ ((target_version ("dotprod"))) int > +foo (); > +__attribute__ ((target_version ("sve+sve2"))) int > +foo (); > + > +int > +foo () > +{ > + return 1; > +} > + > +__attribute__ ((target_version ("dotprod"))) int > +foo () > +{ > + return 3; > +} > +__attribute__ ((target_version ("sve+sve2"))) int > +foo () > +{ > + return 5; > +} > + > +int > +bar () > +{ > + return foo (); > +} > + > +/* { dg-final { scan-assembler-times "\n_Z3foov\.default:\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n_Z3foov\._Mdotprod:\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n_Z3foov\._MsveMsve2:\n" 1 } } */ > + > +/* { dg-final { scan-assembler-times "\n_Z3foov\.resolver:\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n\tadrp\tx\[0-9\]+, > _Z3foov\._MsveMsve2\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n\tadrp\tx\[0-9\]+, > _Z3foov\._Mdotprod\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n\tadrp\tx\[0-9\]+, > _Z3foov\.default\n" 1 } } */ > + > +/* { dg-final { scan-assembler-times "\n\tbl\t_Z3foov\n" 1 } } */ > + > +/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3foov, > %gnu_indirect_function\n" 1 } } */ > +/* { dg-final { scan-assembler-times > "\n\t\.set\t_Z3foov,_Z3foov\.resolver\n" 1 } } */ > diff --git a/gcc/testsuite/g++.target/aarch64/mv-symbols9.C > b/gcc/testsuite/g++.target/aarch64/mv-symbols9.C > new file mode 100644 > index 00000000000..bfad9bb5850 > --- /dev/null > +++ b/gcc/testsuite/g++.target/aarch64/mv-symbols9.C > @@ -0,0 +1,43 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O0" } */ > +/* { dg-additional-options "-Wno-experimental-fmv-target" } */ > + > +int > +foo (); > + > +int > +foo () > +{ > + return 1; > +} > + > +__attribute__ ((target_version ("dotprod"))) int > +foo () > +{ > + return 3; > +} > +__attribute__ ((target_version ("sve+sve2"))) int > +foo () > +{ > + return 5; > +} > + > +int > +bar () > +{ > + return foo (); > +} > + > +/* { dg-final { scan-assembler-times "\n_Z3foov\.default:\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n_Z3foov\._Mdotprod:\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n_Z3foov\._MsveMsve2:\n" 1 } } */ > + > +/* { dg-final { scan-assembler-times "\n_Z3foov\.resolver:\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n\tadrp\tx\[0-9\]+, > _Z3foov\._MsveMsve2\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n\tadrp\tx\[0-9\]+, > _Z3foov\._Mdotprod\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n\tadrp\tx\[0-9\]+, > _Z3foov\.default\n" 1 } } */ > + > +/* { dg-final { scan-assembler-times "\n\tbl\t_Z3foov\n" 1 } } */ > + > +/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3foov, > %gnu_indirect_function\n" 1 } } */ > +/* { dg-final { scan-assembler-times > "\n\t\.set\t_Z3foov,_Z3foov\.resolver\n" 1 } } */ > diff --git a/gcc/testsuite/g++.target/aarch64/mvc-symbols3.C > b/gcc/testsuite/g++.target/aarch64/mvc-symbols3.C > index 350a5586643..2a315d2db5c 100644 > --- a/gcc/testsuite/g++.target/aarch64/mvc-symbols3.C > +++ b/gcc/testsuite/g++.target/aarch64/mvc-symbols3.C > @@ -22,15 +22,15 @@ int bar(int x) > /* { dg-final { scan-assembler-times "\n_Z3foov\.default:\n" 0 } } */ > /* { dg-final { scan-assembler-times "\n_Z3foov\._Mdotprod:\n" 0 } } */ > /* { dg-final { scan-assembler-times "\n_Z3foov\._MsveMsve2:\n" 0 } } */ > -/* { dg-final { scan-assembler-times "\n_Z3foov\.resolver:\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n_Z3foov\.resolver:\n" 0 } } */ > /* { dg-final { scan-assembler-times "\n\tbl\t_Z3foov\n" 1 } } */ > -/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3foov, > %gnu_indirect_function\n" 1 } } */ > -/* { dg-final { scan-assembler-times > "\n\t\.set\t_Z3foov,_Z3foov\.resolver\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3foov, > %gnu_indirect_function\n" 0 } } */ > +/* { dg-final { scan-assembler-times > "\n\t\.set\t_Z3foov,_Z3foov\.resolver\n" 0 } } */ > > /* { dg-final { scan-assembler-times "\n_Z3fooi\.default:\n" 0 } } */ > /* { dg-final { scan-assembler-times "\n_Z3fooi\._Mdotprod:\n" 0 } } */ > /* { dg-final { scan-assembler-times "\n_Z3fooi\._MsveMsve2:\n" 0 } } */ > -/* { dg-final { scan-assembler-times "\n_Z3fooi\.resolver:\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n_Z3fooi\.resolver:\n" 0 } } */ > /* { dg-final { scan-assembler-times "\n\tbl\t_Z3fooi\n" 1 } } */ > -/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3fooi, > %gnu_indirect_function\n" 1 } } */ > -/* { dg-final { scan-assembler-times > "\n\t\.set\t_Z3fooi,_Z3fooi\.resolver\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3fooi, > %gnu_indirect_function\n" 0 } } */ > +/* { dg-final { scan-assembler-times > "\n\t\.set\t_Z3fooi,_Z3fooi\.resolver\n" 0 } } */ > diff --git a/gcc/testsuite/g++.target/riscv/mv-symbols2.C > b/gcc/testsuite/g++.target/riscv/mv-symbols2.C > index 43fa1502b7d..8a5c5a0bc9f 100644 > --- a/gcc/testsuite/g++.target/riscv/mv-symbols2.C > +++ b/gcc/testsuite/g++.target/riscv/mv-symbols2.C > @@ -47,15 +47,15 @@ int foo (int) > /* { dg-final { scan-assembler-times "\n_Z3foov\.default:\n" 1 } } */ > /* { dg-final { scan-assembler-times "\n_Z3foov\.arch__v:\n" 1 } } */ > /* { dg-final { scan-assembler-times "\n_Z3foov\.arch__zba__zbb:\n" 1 } } */ > -/* { dg-final { scan-assembler-times "\n_Z3foov\.resolver:\n" 0 } } */ > +/* { dg-final { scan-assembler-times "\n_Z3foov\.resolver:\n" 1 } } */ > /* { dg-final { scan-assembler-times "\n\tcall\t_Z3foov\n" 0 } } */ > -/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3foov, > @gnu_indirect_function\n" 0 } } */ > -/* { dg-final { scan-assembler-times > "\n\t\.set\t_Z3foov,_Z3foov\.resolver\n" 0 } } */ > +/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3foov, > @gnu_indirect_function\n" 1 } } */ > +/* { dg-final { scan-assembler-times > "\n\t\.set\t_Z3foov,_Z3foov\.resolver\n" 1 } } */ > > /* { dg-final { scan-assembler-times "\n_Z3fooi\.default:\n" 1 } } */ > /* { dg-final { scan-assembler-times "\n_Z3fooi\.arch__v:\n" 1 } } */ > /* { dg-final { scan-assembler-times "\n_Z3fooi\.arch__zba__zbb:\n" 1 } } */ > -/* { dg-final { scan-assembler-times "\n_Z3fooi\.resolver:\n" 0 } } */ > +/* { dg-final { scan-assembler-times "\n_Z3fooi\.resolver:\n" 1 } } */ > /* { dg-final { scan-assembler-times "\n\tcall\t_Z3fooi\n" 0 } } */ > -/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3fooi, > @gnu_indirect_function\n" 0 } } */ > -/* { dg-final { scan-assembler-times > "\n\t\.set\t_Z3fooi,_Z3fooi\.resolver\n" 0 } } */ > +/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3fooi, > @gnu_indirect_function\n" 1 } } */ > +/* { dg-final { scan-assembler-times > "\n\t\.set\t_Z3fooi,_Z3fooi\.resolver\n" 1 } } */ > diff --git a/gcc/testsuite/g++.target/riscv/mv-symbols3.C > b/gcc/testsuite/g++.target/riscv/mv-symbols3.C > index 4dc81cf7395..fa2d3371e87 100644 > --- a/gcc/testsuite/g++.target/riscv/mv-symbols3.C > +++ b/gcc/testsuite/g++.target/riscv/mv-symbols3.C > @@ -36,10 +36,10 @@ int bar() > /* { dg-final { scan-assembler-times "\n_Z3foov\.default:\n" 0 } } */ > /* { dg-final { scan-assembler-times "\n_Z3foov\.arch__v:\n" 0 } } */ > /* { dg-final { scan-assembler-times "\n_Z3foov\.arch__zba__zbb:\n" 0 } } */ > -/* { dg-final { scan-assembler-times "\n_Z3foov\.resolver:\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n_Z3foov\.resolver:\n" 0 } } */ > /* { dg-final { scan-assembler-times "\n\tcall\t_Z3foov\n" 1 } } */ > -/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3foov, > @gnu_indirect_function\n" 1 } } */ > -/* { dg-final { scan-assembler-times > "\n\t\.set\t_Z3foov,_Z3foov\.resolver\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3foov, > @gnu_indirect_function\n" 0 } } */ > +/* { dg-final { scan-assembler-times > "\n\t\.set\t_Z3foov,_Z3foov\.resolver\n" 0 } } */ > > /* { dg-final { scan-assembler-times "\n_Z3fooi\.default:\n" 0 } } */ > /* { dg-final { scan-assembler-times "\n_Z3fooi\.arch__v:\n" 0 } } */ > diff --git a/gcc/testsuite/g++.target/riscv/mv-symbols4.C > b/gcc/testsuite/g++.target/riscv/mv-symbols4.C > index b0ed16a5eda..fa84e25900c 100644 > --- a/gcc/testsuite/g++.target/riscv/mv-symbols4.C > +++ b/gcc/testsuite/g++.target/riscv/mv-symbols4.C > @@ -50,7 +50,7 @@ int bar() > /* { dg-final { scan-assembler-times "\n_Z3fooi\.default:\n" 1 } } */ > /* { dg-final { scan-assembler-times "\n_Z3fooi\.arch__v:\n" 0 } } */ > /* { dg-final { scan-assembler-times "\n_Z3fooi\.arch__zba__zbb:\n" 0 } } */ > -/* { dg-final { scan-assembler-times "\n_Z3fooi\.resolver:\n" 0 } } */ > +/* { dg-final { scan-assembler-times "\n_Z3fooi\.resolver:\n" 1 } } */ > /* { dg-final { scan-assembler-times "\n\tcall\t_Z3fooi\n" 0 } } */ > -/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3fooi, > @gnu_indirect_function\n" 0 } } */ > -/* { dg-final { scan-assembler-times > "\n\t\.set\t_Z3fooi,_Z3fooi\.resolver\n" 0 } } */ > +/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3fooi, > @gnu_indirect_function\n" 1 } } */ > +/* { dg-final { scan-assembler-times > "\n\t\.set\t_Z3fooi,_Z3fooi\.resolver\n" 1 } } */ > diff --git a/gcc/testsuite/g++.target/riscv/mv-symbols5.C > b/gcc/testsuite/g++.target/riscv/mv-symbols5.C > index f4c6b294e0f..5551f5da554 100644 > --- a/gcc/testsuite/g++.target/riscv/mv-symbols5.C > +++ b/gcc/testsuite/g++.target/riscv/mv-symbols5.C > @@ -48,10 +48,10 @@ int bar() > /* { dg-final { scan-assembler-times "\n_Z3foov\.default:\n" 0 } } */ > /* { dg-final { scan-assembler-times "\n_Z3foov\.arch__v:\n" 1 } } */ > /* { dg-final { scan-assembler-times "\n_Z3foov\.arch__zba__zbb:\n" 1 } } */ > -/* { dg-final { scan-assembler-times "\n_Z3foov\.resolver:\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n_Z3foov\.resolver:\n" 0 } } */ > /* { dg-final { scan-assembler-times "\n\tcall\t_Z3foov\n" 1 } } */ > -/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3foov, > @gnu_indirect_function\n" 1 } } */ > -/* { dg-final { scan-assembler-times > "\n\t\.set\t_Z3foov,_Z3foov\.resolver\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3foov, > @gnu_indirect_function\n" 0 } } */ > +/* { dg-final { scan-assembler-times > "\n\t\.set\t_Z3foov,_Z3foov\.resolver\n" 0 } } */ > > /* { dg-final { scan-assembler-times "\n_Z3fooi\.default:\n" 0 } } */ > /* { dg-final { scan-assembler-times "\n_Z3fooi\.arch__v:\n" 1 } } */ > diff --git a/gcc/testsuite/g++.target/riscv/mvc-symbols3.C > b/gcc/testsuite/g++.target/riscv/mvc-symbols3.C > index b36c3fa7a95..256fec7d368 100644 > --- a/gcc/testsuite/g++.target/riscv/mvc-symbols3.C > +++ b/gcc/testsuite/g++.target/riscv/mvc-symbols3.C > @@ -28,15 +28,15 @@ int bar(int x) > /* { dg-final { scan-assembler-times "\n_Z3foov\.default:\n" 0 } } */ > /* { dg-final { scan-assembler-times "\n_Z3foov\.arch__v:\n" 0 } } */ > /* { dg-final { scan-assembler-times "\n_Z3foov\.arch__zba__zbb:\n" 0 } } */ > -/* { dg-final { scan-assembler-times "\n_Z3foov\.resolver:\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n_Z3foov\.resolver:\n" 0 } } */ > /* { dg-final { scan-assembler-times "\n\tcall\t_Z3foov\n" 1 } } */ > -/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3foov, > @gnu_indirect_function\n" 1 } } */ > -/* { dg-final { scan-assembler-times > "\n\t\.set\t_Z3foov,_Z3foov\.resolver\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3foov, > @gnu_indirect_function\n" 0 } } */ > +/* { dg-final { scan-assembler-times > "\n\t\.set\t_Z3foov,_Z3foov\.resolver\n" 0 } } */ > > /* { dg-final { scan-assembler-times "\n_Z3fooi\.default:\n" 0 } } */ > /* { dg-final { scan-assembler-times "\n_Z3fooi\.arch__v:\n" 0 } } */ > /* { dg-final { scan-assembler-times "\n_Z3fooi\.arch__zba__zbb:\n" 0 } } */ > -/* { dg-final { scan-assembler-times "\n_Z3fooi\.resolver:\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n_Z3fooi\.resolver:\n" 0 } } */ > /* { dg-final { scan-assembler-times "\n\tcall\t_Z3fooi\n" 1 } } */ > -/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3fooi, > @gnu_indirect_function\n" 1 } } */ > -/* { dg-final { scan-assembler-times > "\n\t\.set\t_Z3fooi,_Z3fooi\.resolver\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n\t\.type\t_Z3fooi, > @gnu_indirect_function\n" 0 } } */ > +/* { dg-final { scan-assembler-times > "\n\t\.set\t_Z3fooi,_Z3fooi\.resolver\n" 0 } } */