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 } } */

Reply via email to