On Tue, Aug 11, 2026 at 04:11:24PM +0000, [email protected] wrote:
> 
> This patch adds support for ACLE system hint intrinsics
> __yield(), __wfe(), __wfi(), __sev() and __sevl() and their
> corresponding AArch64 builtins. The ACLE specification is
> available at [1].
> 
> Regression tested on aarch64-none-linux-gnu with no regressions.
> 
> Ok for trunk?
> 
> Thanks,
> Srinath
> 
> gcc/ChangeLog:
> 
>         * config/aarch64/aarch64-builtins.cc (enum aarch64_builtins): Add
>       AARCH64_BUILTIN_YIELD, AARCH64_BUILTIN_WFE, AARCH64_BUILTIN_WFI,
>       AARCH64_BUILTIN_SEV and AARCH64_BUILTIN_SEVL.
>         (aarch64_init_syshintop_builtins): New function.
>         (aarch64_general_init_builtins): Call aarch64_init_syshintop_builtins.
>         (aarch64_general_expand_builtin): Expand the system hint builtins.
>         * config/aarch64/aarch64.md (unspecv): Add UNSPECV_YIELD, UNSPECV_WFE,
>       UNSPECV_WFI, UNSPECV_SEV and UNSPECV_SEVL.
>       (yield): New insn pattern.
>       (wfe): Likewise.
>         (wfi): Likewise.
>         (sev): Likewise.
>         (sevl): Likewise.
>         * config/aarch64/arm_acle.h (__yield): Define hint intrinsics.
>         (__wfe): Likewise.
>         (__wfi): Likewise.
>         (__sev): Likewise.
>         (__sevl): Likewise.
> 
> gcc/testsuite/ChangeLog:
> 
>         * gcc.target/aarch64/acle/hint-1.c: New test.
>         * gcc.target/aarch64/acle/hint-2.c: Likewise.
> 
> [1] https://github.com/ARM-software/acle/blob/main/main/acle.md#hints
> ---
>  gcc/config/aarch64/aarch64-builtins.cc        | 51 ++++++++++++
>  gcc/config/aarch64/aarch64.md                 | 45 +++++++++++
>  gcc/config/aarch64/arm_acle.h                 | 16 ++++
>  .../gcc.target/aarch64/acle/hint-1.c          | 26 +++++++
>  .../gcc.target/aarch64/acle/hint-2.c          | 77 +++++++++++++++++++
>  5 files changed, 215 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/acle/hint-1.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/acle/hint-2.c
> 

> diff --git a/gcc/config/aarch64/aarch64-builtins.cc 
> b/gcc/config/aarch64/aarch64-builtins.cc
> index 8cd1bc4b1a2..5cc5d1491e5 100644
> --- a/gcc/config/aarch64/aarch64-builtins.cc
> +++ b/gcc/config/aarch64/aarch64-builtins.cc
> @@ -751,6 +751,12 @@ enum aarch64_builtins
>    AARCH64_BUILTIN_STSHH_SF,
>    AARCH64_BUILTIN_STSHH_DF,
>    AARCH64_BUILTIN_STSHH_PTR,
> +  /* System Hint Operation builtins.  */
> +  AARCH64_BUILTIN_YIELD,
> +  AARCH64_BUILTIN_WFE,
> +  AARCH64_BUILTIN_WFI,
> +  AARCH64_BUILTIN_SEV,
> +  AARCH64_BUILTIN_SEVL,
>    AARCH64_BUILTIN_MAX
>  };
>  
> @@ -1261,6 +1267,30 @@ aarch64_get_attributes (unsigned int f, machine_mode 
> mode)
>    return aarch64_add_attribute ("leaf", attrs);
>  }
>  
> +/* System Hint Operation builtins.  */
> +void
> +aarch64_init_syshintop_builtins (void)
> +{
> +  tree vtype_node
> +    = build_function_type_list (void_type_node, NULL);
> +
> +  aarch64_builtin_decls[AARCH64_BUILTIN_YIELD]
> +    = aarch64_general_add_builtin ("__builtin_aarch64_yield",
> +                                vtype_node, AARCH64_BUILTIN_YIELD);
> +  aarch64_builtin_decls[AARCH64_BUILTIN_WFE]
> +    = aarch64_general_add_builtin ("__builtin_aarch64_wfe",
> +                                vtype_node, AARCH64_BUILTIN_WFE);
> +  aarch64_builtin_decls[AARCH64_BUILTIN_WFI]
> +    = aarch64_general_add_builtin ("__builtin_aarch64_wfi",
> +                                vtype_node, AARCH64_BUILTIN_WFI);
> +  aarch64_builtin_decls[AARCH64_BUILTIN_SEV]
> +    = aarch64_general_add_builtin ("__builtin_aarch64_sev",
> +                                vtype_node, AARCH64_BUILTIN_SEV);
> +  aarch64_builtin_decls[AARCH64_BUILTIN_SEVL]
> +    = aarch64_general_add_builtin ("__builtin_aarch64_sevl",
> +                                vtype_node, AARCH64_BUILTIN_SEVL);
> +}
> +

We should define the user-facing names directly, using
aarch64_general_simulate_builtin.

>  /* Due to the architecture not providing lane variant of the lane 
> instructions
>     for fcmla we can't use the standard simd builtin expansion code, but we
>     still want the majority of the validation that would normally be done.  */
> @@ -2377,6 +2407,7 @@ aarch64_general_init_builtins (void)
>  
>    aarch64_init_gcs_builtins ();
>    aarch64_init_pcdphint_builtins ();
> +  aarch64_init_syshintop_builtins ();
>  
>    if (in_lto_p)
>      handle_arm_acle_h ();
> @@ -4354,6 +4385,26 @@ aarch64_general_expand_builtin (unsigned int fcode, 
> tree exp, rtx target,
>       return ops[0].value;
>        }
>  
> +    case AARCH64_BUILTIN_YIELD:
> +      emit_insn (GEN_FCN (CODE_FOR_yield) ());
> +      return NULL_RTX;
> +
> +    case AARCH64_BUILTIN_WFE:
> +      emit_insn (GEN_FCN (CODE_FOR_wfe) ());
> +      return NULL_RTX;
> +
> +    case AARCH64_BUILTIN_WFI:
> +      emit_insn (GEN_FCN (CODE_FOR_wfi) ());
> +      return NULL_RTX;
> +
> +    case AARCH64_BUILTIN_SEV:
> +      emit_insn (GEN_FCN (CODE_FOR_sev) ());
> +      return NULL_RTX;
> +
> +    case AARCH64_BUILTIN_SEVL:
> +      emit_insn (GEN_FCN (CODE_FOR_sevl) ());
> +      return NULL_RTX;
> +
>      case AARCH64_SIMD_BUILTIN_FCMLA_LANEQ0_V2SF:
>      case AARCH64_SIMD_BUILTIN_FCMLA_LANEQ90_V2SF:
>      case AARCH64_SIMD_BUILTIN_FCMLA_LANEQ180_V2SF:
> diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
> index 9cb55602c36..60dd72e4935 100644
> --- a/gcc/config/aarch64/aarch64.md
> +++ b/gcc/config/aarch64/aarch64.md
> @@ -425,6 +425,11 @@ (define_c_enum "unspecv" [
>      UNSPECV_BLOCKAGE         ; Represent a blockage
>      UNSPECV_PROBE_STACK_RANGE        ; Represent stack range probing.
>      UNSPECV_SPECULATION_BARRIER ; Represent speculation barrier.
> +    UNSPECV_YIELD            ; Represent yield instruction.
> +    UNSPECV_WFE                      ; Represent wfe instruction.
> +    UNSPECV_WFI                      ; Represent wfi instruction.
> +    UNSPECV_SEV                      ; Represent sev instruction.
> +    UNSPECV_SEVL             ; Represent sevl instruction.
>      UNSPECV_BTI_NOARG                ; Represent BTI.
>      UNSPECV_BTI_C            ; Represent BTI c.
>      UNSPECV_BTI_J            ; Represent BTI j.
> @@ -1334,6 +1339,46 @@ (define_insn "nop"
>    [(set_attr "type" "no_insn")]
>  )
>  
> +(define_insn "yield"
> +  [(unspec_volatile [(const_int 0)] UNSPECV_YIELD)
> +   (clobber (mem:BLK (scratch)))]
> +  ""
> +  "yield"
> +  [(set_attr "type" "nop")]
> +)
> +
> +(define_insn "wfe"
> +  [(unspec_volatile [(const_int 0)] UNSPECV_WFE)
> +   (clobber (mem:BLK (scratch)))]
> +  ""
> +  "wfe"
> +  [(set_attr "type" "nop")]
> +)
> +
> +(define_insn "wfi"
> +  [(unspec_volatile [(const_int 0)] UNSPECV_WFI)
> +   (clobber (mem:BLK (scratch)))]
> +  ""
> +  "wfi"
> +  [(set_attr "type" "nop")]
> +)
> +
> +(define_insn "sev"
> +  [(unspec_volatile [(const_int 0)] UNSPECV_SEV)
> +   (clobber (mem:BLK (scratch)))]
> +  ""
> +  "sev"
> +  [(set_attr "type" "nop")]
> +)
> +
> +(define_insn "sevl"
> +  [(unspec_volatile [(const_int 0)] UNSPECV_SEVL)
> +   (clobber (mem:BLK (scratch)))]
> +  ""
> +  "sevl"
> +  [(set_attr "type" "nop")]
> +)
> +

When do we include "aarch64" in an insn name?  It might be better to avoid
potential clashes with generic names.

>  (define_insn "prefetch"
>    [(prefetch (match_operand:DI 0 "aarch64_prefetch_operand" "Dp")
>              (match_operand:QI 1 "const_int_operand" "")
> diff --git a/gcc/config/aarch64/arm_acle.h b/gcc/config/aarch64/arm_acle.h
> index b31e23e6cba..be3b2dc0552 100644
> --- a/gcc/config/aarch64/arm_acle.h
> +++ b/gcc/config/aarch64/arm_acle.h
> @@ -353,6 +353,22 @@ __rndrrs (uint64_t *__res)
>  
>  #pragma GCC pop_options
>  
> +/* Sytem hint operations.  */
> +#define __yield() \
> +  __builtin_aarch64_yield ()
> +
> +#define __wfe() \
> +  __builtin_aarch64_wfe ()
> +
> +#define __wfi() \
> +  __builtin_aarch64_wfi ()
> +
> +#define __sev() \
> +  __builtin_aarch64_sev ()
> +
> +#define __sevl() \
> +  __builtin_aarch64_sevl ()
> +
>  #ifdef __cplusplus
>  }
>  #endif
> diff --git a/gcc/testsuite/gcc.target/aarch64/acle/hint-1.c 
> b/gcc/testsuite/gcc.target/aarch64/acle/hint-1.c
> new file mode 100644
> index 00000000000..17372a09617
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/acle/hint-1.c
> @@ -0,0 +1,26 @@
> +/* Test the ACLE hint intrinsics.  */
> +/* { dg-do compile } */
> +/* { dg-final { check-function-bodies "**" "" } } */
> +
> +#include <arm_acle.h>
> +
> +/*
> +** test_hint:
> +** ...
> +**   yield
> +**   wfe
> +**   sev
> +**   sevl
> +**   wfi
> +**...
> +**   ret
> +*/
> +void
> +test_hint ()
> +{
> +  __yield ();
> +  __wfe ();
> +  __sev ();
> +  __sevl ();
> +  __wfi ();
> +}
> diff --git a/gcc/testsuite/gcc.target/aarch64/acle/hint-2.c 
> b/gcc/testsuite/gcc.target/aarch64/acle/hint-2.c
> new file mode 100644
> index 00000000000..151fd690fa2
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/acle/hint-2.c
> @@ -0,0 +1,77 @@
> + /* Test the ACLE hint intrinsics effect on memory.  */
> +/* { dg-do compile } */
> +/* { dg-options "-O2" } */
> +/* { dg-final { check-function-bodies "**" "" } } */
> +
> +#include <arm_acle.h>
> +
> +/*
> +** foo:
> +** ...
> +**   mov     w[0-9]+, 5
> +**   str     w[0-9]+, \[x0\]
> +**   yield
> +**   mov     w[0-9]+, 4
> +**   str     w[0-9]+, \[x0\]
> +**   wfe
> +**   mov     w[0-9]+, 3
> +**   str     w[0-9]+, \[x0\]
> +**   sev
> +**   str     w[0-9]+, \[x0\]
> +**   sevl
> +**   mov     w[0-9]+, 9
> +**   str     w[0-9]+, \[x0\]
> +**   wfi
> +**   mov     w0, 0
> +**   ret
> +*/
> +int foo (int* counter)
> +{
> +  *counter = 5;
> +  __yield();
> +  *counter = 4;
> +  __wfe();
> +  *counter = 3;
> +  __sev();
> +  *counter = 4;
> +  __sevl();
> +  *counter = 9;
> +  __wfi();
> +  return 0;
> +}
> +
> +/*
> +** foo1:
> +** ...
> +**   mov     w[0-9]+, 5
> +**   str     w[0-9]+, \[x0\]
> +**   yield
> +**   mov     w[0-9]+, 4
> +**   str     w[0-9]+, \[x0\]
> +**   yield
> +**   mov     w[0-9]+, 3
> +**   str     w[0-9]+, \[x0\]
> +**   yield
> +**   mov     w[0-9]+, 6
> +**   str     w[0-9]+, \[x0\]
> +**   yield
> +**   mov     w[0-9]+, 9
> +**   str     w[0-9]+, \[x0\]
> +**   yield
> +**   mov     w0, 0
> +**   ret
> +*/
> +int foo1 (int* counter)
> +{
> +  *counter = 5;
> +  __yield();
> +  *counter = 4;
> +  __yield();
> +  *counter = 3;
> +  __yield();
> +  *counter = 6;
> +  __yield();
> +  *counter = 9;
> +  __yield();
> +  return 0;
> +}

Reply via email to