Hi Yury,

> -----Original Message-----
> From: Yury Khrustalev <yury.khrusta...@arm.com>
> Sent: Wednesday, July 23, 2025 9:45 AM
> To: gcc-patches@gcc.gnu.org
> Cc: Andrew Pinski <pins...@gmail.com>; Richard Sandiford
> <richard.sandif...@arm.com>; Tamar Christina <tamar.christ...@arm.com>;
> Alfie Richards <alfie.richa...@arm.com>; Alice Carlotti 
> <alice.carlo...@arm.com>;
> Victor Do Nascimento <victor.donascime...@arm.com>
> Subject: [PATCH v2 2/3] testsuite: Add tests for 
> __init_cpu_features_constructor
> 
> Add tests that would call __init_cpu_features_resolver() directly
> from an ifunc resolver that would in tern call the function under
> test __init_cpu_features_constructor() using synthetic parameters
> for different sizes of the 2nd argument.
> 
> gcc/testsuite/ChangeLog:
> 
>       * gcc.target/aarch64/ifunc-resolver.in: add core test functions.
>       * gcc.target/aarch64/ifunc-resolver-0.c: new test.
>       * gcc.target/aarch64/ifunc-resolver-1.c: ditto.
>       * gcc.target/aarch64/ifunc-resolver-2.c: ditto.
>       * gcc.target/aarch64/ifunc-resolver-3.c: ditto.
>       * gcc.target/aarch64/ifunc-resolver-4.c: as above.
> ---
>  .../gcc.target/aarch64/ifunc-resolver-0.c     | 11 +++++
>  .../gcc.target/aarch64/ifunc-resolver-1.c     | 12 +++++
>  .../gcc.target/aarch64/ifunc-resolver-2.c     | 13 +++++
>  .../gcc.target/aarch64/ifunc-resolver-3.c     | 14 ++++++
>  .../gcc.target/aarch64/ifunc-resolver-4.c     | 15 ++++++
>  .../gcc.target/aarch64/ifunc-resolver.in      | 48 +++++++++++++++++++
>  6 files changed, 113 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/ifunc-resolver-0.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/ifunc-resolver-1.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/ifunc-resolver-2.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/ifunc-resolver-3.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/ifunc-resolver-4.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/ifunc-resolver.in
> 
> diff --git a/gcc/testsuite/gcc.target/aarch64/ifunc-resolver-0.c
> b/gcc/testsuite/gcc.target/aarch64/ifunc-resolver-0.c
> new file mode 100644
> index 00000000000..4e2c67068a1
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/ifunc-resolver-0.c
> @@ -0,0 +1,11 @@
> +/* { dg-do run }  */
> +/* { dg-require-ifunc "" } */
> +/* { dg-options "-Wno-experimental-fmv-target" } */
> +
> +#include <stdint.h>
> +
> +typedef struct {
> +  uint64_t size;
> +} ifunc_arg_t;
> +
> +#include "ifunc-resolver.in"

Possibly silly question, but do we only support ifuncs on platforms
with mmap support? I'm wondering if these tests shouldn't also
require { dg-require-effective-target mmap } */

Thanks,
Tamar

> diff --git a/gcc/testsuite/gcc.target/aarch64/ifunc-resolver-1.c
> b/gcc/testsuite/gcc.target/aarch64/ifunc-resolver-1.c
> new file mode 100644
> index 00000000000..c19be8f30df
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/ifunc-resolver-1.c
> @@ -0,0 +1,12 @@
> +/* { dg-do run }  */
> +/* { dg-require-ifunc "" } */
> +/* { dg-options "-Wno-experimental-fmv-target" } */
> +
> +#include <stdint.h>
> +
> +typedef struct {
> +  uint64_t size;
> +  uint64_t hwcap;
> +} ifunc_arg_t;
> +
> +#include "ifunc-resolver.in"
> diff --git a/gcc/testsuite/gcc.target/aarch64/ifunc-resolver-2.c
> b/gcc/testsuite/gcc.target/aarch64/ifunc-resolver-2.c
> new file mode 100644
> index 00000000000..f43e812bd1c
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/ifunc-resolver-2.c
> @@ -0,0 +1,13 @@
> +/* { dg-do run }  */
> +/* { dg-require-ifunc "" } */
> +/* { dg-options "-Wno-experimental-fmv-target" } */
> +
> +#include <stdint.h>
> +
> +typedef struct {
> +  uint64_t size;
> +  uint64_t hwcap;
> +  uint64_t hwcap2;
> +} ifunc_arg_t;
> +
> +#include "ifunc-resolver.in"
> diff --git a/gcc/testsuite/gcc.target/aarch64/ifunc-resolver-3.c
> b/gcc/testsuite/gcc.target/aarch64/ifunc-resolver-3.c
> new file mode 100644
> index 00000000000..274eb255cf3
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/ifunc-resolver-3.c
> @@ -0,0 +1,14 @@
> +/* { dg-do run }  */
> +/* { dg-require-ifunc "" } */
> +/* { dg-options "-Wno-experimental-fmv-target" } */
> +
> +#include <stdint.h>
> +
> +typedef struct {
> +  uint64_t size;
> +  uint64_t hwcap;
> +  uint64_t hwcap2;
> +  uint64_t hwcap3;
> +} ifunc_arg_t;
> +
> +#include "ifunc-resolver.in"
> diff --git a/gcc/testsuite/gcc.target/aarch64/ifunc-resolver-4.c
> b/gcc/testsuite/gcc.target/aarch64/ifunc-resolver-4.c
> new file mode 100644
> index 00000000000..6c18a3d770a
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/ifunc-resolver-4.c
> @@ -0,0 +1,15 @@
> +/* { dg-do run }  */
> +/* { dg-require-ifunc "" } */
> +/* { dg-options "-Wno-experimental-fmv-target" } */
> +
> +#include <stdint.h>
> +
> +typedef struct {
> +  uint64_t size;
> +  uint64_t hwcap;
> +  uint64_t hwcap2;
> +  uint64_t hwcap3;
> +  uint64_t hwcap4;
> +} ifunc_arg_t;
> +
> +#include "ifunc-resolver.in"
> diff --git a/gcc/testsuite/gcc.target/aarch64/ifunc-resolver.in
> b/gcc/testsuite/gcc.target/aarch64/ifunc-resolver.in
> new file mode 100644
> index 00000000000..ada0b337f39
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/ifunc-resolver.in
> @@ -0,0 +1,48 @@
> +#include <unistd.h>
> +#include <string.h>
> +#include <sys/mman.h>
> +
> +/* Allocate memory buffer of size LEN with a protected page
> +   following right after the buffer end so that any memory
> +   accesses past the end of the buffer would trigger SEGFAUL.  */
> +void *allocate_mem (size_t len)
> +{
> +  size_t pagesize = sysconf (_SC_PAGESIZE);
> +  char *m = mmap (NULL, pagesize * 2,
> +               PROT_READ | PROT_WRITE,
> +               MAP_PRIVATE | MAP_ANONYMOUS,
> +               -1, 0);
> +  mprotect (m + pagesize, pagesize, PROT_NONE);
> +  m = m + pagesize - len;
> +  memset(m, 0, len);
> +  return m;
> +}
> +
> +int impl ()
> +{
> +  return 0;
> +}
> +
> +#ifndef _IFUNC_ARG_HWCAP
> +#define _IFUNC_ARG_HWCAP (1ULL << 62)
> +#endif
> +
> +void
> +__init_cpu_features_resolver (unsigned long hwcap, const void *arg);
> +
> +static void *
> +fun_resolver (uint64_t a0, const uint64_t *a1)
> +{
> +  ifunc_arg_t *arg = allocate_mem (sizeof (ifunc_arg_t));
> +  arg->size = sizeof (ifunc_arg_t);
> +  /* Call this function with synthetic ifunc_arg_t arg.  */
> +  __init_cpu_features_resolver (_IFUNC_ARG_HWCAP, arg);
> +  return (void *)(uintptr_t)impl;
> +}
> +
> +int fun (void) __attribute__ ((ifunc ("fun_resolver")));
> +
> +int main (int argc, char *argv[])
> +{
> +  return fun ();
> +}
> --
> 2.39.5

Reply via email to