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

Reply via email to