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