gcc/testsuite/ChangeLog: * g++.target/aarch64/mv-cpu-features.C: new test. --- .../g++.target/aarch64/mv-cpu-features.C | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 gcc/testsuite/g++.target/aarch64/mv-cpu-features.C
diff --git a/gcc/testsuite/g++.target/aarch64/mv-cpu-features.C b/gcc/testsuite/g++.target/aarch64/mv-cpu-features.C new file mode 100644 index 00000000000..00a0cf1ecc4 --- /dev/null +++ b/gcc/testsuite/g++.target/aarch64/mv-cpu-features.C @@ -0,0 +1,65 @@ +/* { dg-do run } */ +/* { dg-require-ifunc "" } */ +/* { dg-options "-Wno-experimental-fmv-target" } */ + +#include <cstdint> +#include <sys/auxv.h> + +__attribute__((target_version ("default"))) +int foo () +{ + return 0; +} + +__attribute__((target_version ("rng"))) +int foo () +{ + return 1; +} + +__attribute__((target_version ("lse"))) +int foo () +{ + return 2; +} + +typedef struct { + uint64_t size; + uint64_t hwcap; + uint64_t hwcap2; + uint64_t hwcap3; + uint64_t hwcap4; +} ifunc_arg_t; + +int impl () +{ + return 0; +} + +#ifndef _IFUNC_ARG_HWCAP +#define _IFUNC_ARG_HWCAP (1ULL << 62) +#endif + +extern "C" void +__init_cpu_features_resolver (unsigned long hwcap, const ifunc_arg_t *arg); + +extern "C" void * +fun_resolver (uint64_t a0, const ifunc_arg_t *a1) +{ + ifunc_arg_t arg = {}; + arg.size = sizeof (ifunc_arg_t); + arg.hwcap = HWCAP_ATOMICS; + arg.hwcap2 = HWCAP2_RNG; + __init_cpu_features_resolver (arg.hwcap | _IFUNC_ARG_HWCAP, &arg); + return (void *)(uintptr_t)impl; +} + +extern "C" int fun (void) __attribute__((ifunc ("fun_resolver"))); + +int main () +{ + int res = fun (); + if (res == 0 && foo () == 2) + return 0; + return 1; +} -- 2.39.5