aarch64: Fix function multiversioning mangling
It would be neater if the middle end for target_clones used a target hook for version name mangling, so we only do version name mangling once. However, that would require more intrusive refactoring that will have to wait till Stage 1. gcc/ChangeLog: * config/aarch64/aarch64.cc (aarch64_mangle_decl_assembler_name): Move before new caller, and add ".default" suffix. (get_suffixed_assembler_name): New. (make_resolver_func): Use get_suffixed_assembler_name. (aarch64_generate_version_dispatcher_body): Redo name mangling. gcc/testsuite/ChangeLog: * g++.target/aarch64/mv-symbols1.C: New test. * 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-symbols1.C: Ditto. * g++.target/aarch64/mvc-symbols2.C: Ditto. * g++.target/aarch64/mvc-symbols3.C: Ditto. * g++.target/aarch64/mvc-symbols4.C: Ditto.
This commit is contained in:
parent
df9f6b9348
commit
8ec2f1922a
10 changed files with 475 additions and 38 deletions
|
@ -19872,6 +19872,62 @@ build_ifunc_arg_type ()
|
|||
return pointer_type;
|
||||
}
|
||||
|
||||
/* Implement TARGET_MANGLE_DECL_ASSEMBLER_NAME, to add function multiversioning
|
||||
suffixes. */
|
||||
|
||||
tree
|
||||
aarch64_mangle_decl_assembler_name (tree decl, tree id)
|
||||
{
|
||||
/* For function version, add the target suffix to the assembler name. */
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL
|
||||
&& DECL_FUNCTION_VERSIONED (decl))
|
||||
{
|
||||
aarch64_fmv_feature_mask feature_mask = get_feature_mask_for_version (decl);
|
||||
|
||||
std::string name = IDENTIFIER_POINTER (id);
|
||||
|
||||
/* For the default version, append ".default". */
|
||||
if (feature_mask == 0ULL)
|
||||
{
|
||||
name += ".default";
|
||||
return get_identifier (name.c_str());
|
||||
}
|
||||
|
||||
name += "._";
|
||||
|
||||
for (int i = 0; i < FEAT_MAX; i++)
|
||||
{
|
||||
if (feature_mask & aarch64_fmv_feature_data[i].feature_mask)
|
||||
{
|
||||
name += "M";
|
||||
name += aarch64_fmv_feature_data[i].name;
|
||||
}
|
||||
}
|
||||
|
||||
if (DECL_ASSEMBLER_NAME_SET_P (decl))
|
||||
SET_DECL_RTL (decl, NULL);
|
||||
|
||||
id = get_identifier (name.c_str());
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
/* Return an identifier for the base assembler name of a versioned function.
|
||||
This is computed by taking the default version's assembler name, and
|
||||
stripping off the ".default" suffix if it's already been appended. */
|
||||
|
||||
static tree
|
||||
get_suffixed_assembler_name (tree default_decl, const char *suffix)
|
||||
{
|
||||
std::string name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (default_decl));
|
||||
|
||||
auto size = name.size ();
|
||||
if (size >= 8 && name.compare (size - 8, 8, ".default") == 0)
|
||||
name.resize (size - 8);
|
||||
name += suffix;
|
||||
return get_identifier (name.c_str());
|
||||
}
|
||||
|
||||
/* Make the resolver function decl to dispatch the versions of
|
||||
a multi-versioned function, DEFAULT_DECL. IFUNC_ALIAS_DECL is
|
||||
ifunc alias that will point to the created resolver. Create an
|
||||
|
@ -19885,8 +19941,9 @@ make_resolver_func (const tree default_decl,
|
|||
{
|
||||
tree decl, type, t;
|
||||
|
||||
/* Create resolver function name based on default_decl. */
|
||||
tree decl_name = clone_function_name (default_decl, "resolver");
|
||||
/* Create resolver function name based on default_decl. We need to remove an
|
||||
existing ".default" suffix if this has already been appended. */
|
||||
tree decl_name = get_suffixed_assembler_name (default_decl, ".resolver");
|
||||
const char *resolver_name = IDENTIFIER_POINTER (decl_name);
|
||||
|
||||
/* The resolver function should have signature
|
||||
|
@ -20233,6 +20290,28 @@ aarch64_generate_version_dispatcher_body (void *node_p)
|
|||
dispatch_function_versions (resolver_decl, &fn_ver_vec, &empty_bb);
|
||||
cgraph_edge::rebuild_edges ();
|
||||
pop_cfun ();
|
||||
|
||||
/* Fix up symbol names. First we need to obtain the base name, which may
|
||||
have already been mangled. */
|
||||
tree base_name = get_suffixed_assembler_name (default_ver_decl, "");
|
||||
|
||||
/* We need to redo the version mangling on the non-default versions for the
|
||||
target_clones case. Redoing the mangling for the target_version case is
|
||||
redundant but does no harm. We need to skip the default version, because
|
||||
expand_clones will append ".default" later; fortunately that suffix is the
|
||||
one we want anyway. */
|
||||
for (versn_info = node_version_info->next->next; versn_info;
|
||||
versn_info = versn_info->next)
|
||||
{
|
||||
tree version_decl = versn_info->this_node->decl;
|
||||
tree name = aarch64_mangle_decl_assembler_name (version_decl,
|
||||
base_name);
|
||||
symtab->change_decl_assembler_name (version_decl, name);
|
||||
}
|
||||
|
||||
/* We also need to use the base name for the ifunc declaration. */
|
||||
symtab->change_decl_assembler_name (node->decl, base_name);
|
||||
|
||||
return resolver_decl;
|
||||
}
|
||||
|
||||
|
@ -20345,42 +20424,6 @@ aarch64_common_function_versions (tree fn1, tree fn2)
|
|||
return (aarch64_compare_version_priority (fn1, fn2) != 0);
|
||||
}
|
||||
|
||||
/* Implement TARGET_MANGLE_DECL_ASSEMBLER_NAME, to add function multiversioning
|
||||
suffixes. */
|
||||
|
||||
tree
|
||||
aarch64_mangle_decl_assembler_name (tree decl, tree id)
|
||||
{
|
||||
/* For function version, add the target suffix to the assembler name. */
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL
|
||||
&& DECL_FUNCTION_VERSIONED (decl))
|
||||
{
|
||||
aarch64_fmv_feature_mask feature_mask = get_feature_mask_for_version (decl);
|
||||
|
||||
/* No suffix for the default version. */
|
||||
if (feature_mask == 0ULL)
|
||||
return id;
|
||||
|
||||
std::string name = IDENTIFIER_POINTER (id);
|
||||
name += "._";
|
||||
|
||||
for (int i = 0; i < FEAT_MAX; i++)
|
||||
{
|
||||
if (feature_mask & aarch64_fmv_feature_data[i].feature_mask)
|
||||
{
|
||||
name += "M";
|
||||
name += aarch64_fmv_feature_data[i].name;
|
||||
}
|
||||
}
|
||||
|
||||
if (DECL_ASSEMBLER_NAME_SET_P (decl))
|
||||
SET_DECL_RTL (decl, NULL);
|
||||
|
||||
id = get_identifier (name.c_str());
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
/* Implement TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P. Use an opt-out
|
||||
rather than an opt-in list. */
|
||||
|
||||
|
|
66
gcc/testsuite/g++.target/aarch64/mv-symbols1.C
Normal file
66
gcc/testsuite/g++.target/aarch64/mv-symbols1.C
Normal file
|
@ -0,0 +1,66 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-require-ifunc "" } */
|
||||
/* { dg-options "-O0" } */
|
||||
|
||||
int foo ()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
__attribute__((target_version("dotprod")))
|
||||
int foo ()
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
__attribute__((target_version("sve+sve2")))
|
||||
int foo ()
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
__attribute__((target_version("sve+sve2")))
|
||||
int foo (int)
|
||||
{
|
||||
return 6;
|
||||
}
|
||||
|
||||
__attribute__((target_version("dotprod")))
|
||||
int foo (int)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
int foo (int)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
int bar()
|
||||
{
|
||||
return foo ();
|
||||
}
|
||||
|
||||
int bar(int x)
|
||||
{
|
||||
return foo (x);
|
||||
}
|
||||
|
||||
/* When updating any of the symbol names in these tests, make sure to also
|
||||
update any tests for their absence in mv-symbolsN.C */
|
||||
|
||||
/* { 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\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_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" 1 } } */
|
||||
/* { 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 } } */
|
52
gcc/testsuite/g++.target/aarch64/mv-symbols2.C
Normal file
52
gcc/testsuite/g++.target/aarch64/mv-symbols2.C
Normal file
|
@ -0,0 +1,52 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-require-ifunc "" } */
|
||||
/* { dg-options "-O0" } */
|
||||
|
||||
__attribute__((target_version("default")))
|
||||
int foo ()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
__attribute__((target_version("dotprod")))
|
||||
int foo ()
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
__attribute__((target_version("sve+sve2")))
|
||||
int foo ()
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
__attribute__((target_version("sve+sve2")))
|
||||
int foo (int)
|
||||
{
|
||||
return 6;
|
||||
}
|
||||
|
||||
__attribute__((target_version("dotprod")))
|
||||
int foo (int)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
__attribute__((target_version("default")))
|
||||
int foo (int)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* { 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_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 } } */
|
41
gcc/testsuite/g++.target/aarch64/mv-symbols3.C
Normal file
41
gcc/testsuite/g++.target/aarch64/mv-symbols3.C
Normal file
|
@ -0,0 +1,41 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-require-ifunc "" } */
|
||||
/* { dg-options "-O0" } */
|
||||
|
||||
__attribute__((target_version("default")))
|
||||
int foo ();
|
||||
|
||||
__attribute__((target_version("dotprod")))
|
||||
int foo ();
|
||||
|
||||
__attribute__((target_version("sve+sve2")))
|
||||
int foo ();
|
||||
|
||||
__attribute__((target_version("default")))
|
||||
int foo (int);
|
||||
|
||||
__attribute__((target_version("dotprod")))
|
||||
int foo (int);
|
||||
|
||||
__attribute__((target_version("sve+sve2")))
|
||||
int foo (int);
|
||||
|
||||
int bar()
|
||||
{
|
||||
return foo ();
|
||||
}
|
||||
|
||||
/* { 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\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_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" 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 } } */
|
48
gcc/testsuite/g++.target/aarch64/mv-symbols4.C
Normal file
48
gcc/testsuite/g++.target/aarch64/mv-symbols4.C
Normal file
|
@ -0,0 +1,48 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-require-ifunc "" } */
|
||||
/* { dg-options "-O0" } */
|
||||
|
||||
__attribute__((target_version("default")))
|
||||
int foo ()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
__attribute__((target_version("dotprod")))
|
||||
int foo ();
|
||||
|
||||
__attribute__((target_version("sve+sve2")))
|
||||
int foo ();
|
||||
|
||||
__attribute__((target_version("default")))
|
||||
int foo (int)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
__attribute__((target_version("dotprod")))
|
||||
int foo (int);
|
||||
|
||||
__attribute__((target_version("sve+sve2")))
|
||||
int foo (int);
|
||||
|
||||
|
||||
int bar()
|
||||
{
|
||||
return 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\._MsveMsve2:\n" 0 } } */
|
||||
/* { 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 } } */
|
||||
|
||||
/* { 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 } } */
|
56
gcc/testsuite/g++.target/aarch64/mv-symbols5.C
Normal file
56
gcc/testsuite/g++.target/aarch64/mv-symbols5.C
Normal file
|
@ -0,0 +1,56 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-require-ifunc "" } */
|
||||
/* { dg-options "-O0" } */
|
||||
|
||||
__attribute__((target_version("default")))
|
||||
int foo ();
|
||||
|
||||
__attribute__((target_version("dotprod")))
|
||||
int foo ()
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
__attribute__((target_version("sve+sve2")))
|
||||
int foo ()
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
__attribute__((target_version("default")))
|
||||
int foo (int);
|
||||
|
||||
__attribute__((target_version("dotprod")))
|
||||
int foo (int)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
__attribute__((target_version("sve+sve2")))
|
||||
int foo (int)
|
||||
{
|
||||
return 6;
|
||||
}
|
||||
|
||||
|
||||
int bar()
|
||||
{
|
||||
return foo ();
|
||||
}
|
||||
|
||||
/* When updating any of the symbol names in these tests, make sure to also
|
||||
update any tests for their absence in mvc-symbolsN.C */
|
||||
|
||||
/* { 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\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_Z3fooi\.default:\n" 0 } } */
|
||||
/* { 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 } } */
|
44
gcc/testsuite/g++.target/aarch64/mvc-symbols1.C
Normal file
44
gcc/testsuite/g++.target/aarch64/mvc-symbols1.C
Normal file
|
@ -0,0 +1,44 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-require-ifunc "" } */
|
||||
/* { dg-options "-O0" } */
|
||||
|
||||
__attribute__((target_clones("default", "dotprod", "sve+sve2")))
|
||||
int foo ()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
__attribute__((target_clones("sve+sve2", "dotprod", "default")))
|
||||
int foo (int)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
int bar()
|
||||
{
|
||||
return foo ();
|
||||
}
|
||||
|
||||
int bar(int x)
|
||||
{
|
||||
return foo (x);
|
||||
}
|
||||
|
||||
/* When updating any of the symbol names in these tests, make sure to also
|
||||
update any tests for their absence in mvc-symbolsN.C */
|
||||
|
||||
/* { 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\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_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" 1 } } */
|
||||
/* { 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 } } */
|
29
gcc/testsuite/g++.target/aarch64/mvc-symbols2.C
Normal file
29
gcc/testsuite/g++.target/aarch64/mvc-symbols2.C
Normal file
|
@ -0,0 +1,29 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-require-ifunc "" } */
|
||||
/* { dg-options "-O0" } */
|
||||
|
||||
__attribute__((target_clones("default", "dotprod", "sve+sve2")))
|
||||
int foo ()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
__attribute__((target_clones("sve+sve2", "dotprod", "default")))
|
||||
int foo (int)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* { 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\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" 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 } } */
|
35
gcc/testsuite/g++.target/aarch64/mvc-symbols3.C
Normal file
35
gcc/testsuite/g++.target/aarch64/mvc-symbols3.C
Normal file
|
@ -0,0 +1,35 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-require-ifunc "" } */
|
||||
/* { dg-options "-O0" } */
|
||||
|
||||
__attribute__((target_clones("default", "dotprod", "sve+sve2")))
|
||||
int foo ();
|
||||
|
||||
__attribute__((target_clones("sve+sve2", "dotprod", "default")))
|
||||
int foo (int);
|
||||
|
||||
int bar()
|
||||
{
|
||||
return foo ();
|
||||
}
|
||||
|
||||
int bar(int x)
|
||||
{
|
||||
return foo (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\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_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\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 } } */
|
23
gcc/testsuite/g++.target/aarch64/mvc-symbols4.C
Normal file
23
gcc/testsuite/g++.target/aarch64/mvc-symbols4.C
Normal file
|
@ -0,0 +1,23 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-require-ifunc "" } */
|
||||
/* { dg-options "-O0" } */
|
||||
|
||||
__attribute__((target_clones("default", "dotprod", "sve+sve2")))
|
||||
int foo ();
|
||||
|
||||
__attribute__((target_clones("sve+sve2", "dotprod", "default")))
|
||||
int foo (int);
|
||||
|
||||
/* { 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" 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_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" 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 } } */
|
Loading…
Add table
Reference in a new issue