> -----Original Message-----
> From: Andrea Pinski <[email protected]>
> Sent: 26 September 2026 05:54
> To: Wilco Dijkstra <[email protected]>
> Cc: gcc-patches mailing list <[email protected]>; Kyrylo Tkachov
> <[email protected]>; Tamar Christina <[email protected]>; Alex
> Coplan <[email protected]>; Alice Carlotti <[email protected]>;
> Richard Earnshaw <[email protected]>
> Subject: Re: [PATCH v2] libatomic: Use HWCAPs in AArch64 ifunc tests
> 
> On Tue, Sep 22, 2026 at 8:25 AM Wilco Dijkstra <[email protected]>
> wrote:
> >
> >
> > Feedback from the kernel team suggests that it's best to only use HWCAPs
> > rather than also use low-level checks as done by has_lse128() and
> has_rcpc3().
> > So change these to just use HWCAPs which simplifies the code and speeds
> up
> > ifunc selection by avoiding expensive system register accesses.
> >

I do wonder though, the access itself was only ever used as a fall-back when 
HWCAPS
failed.  If I'm not mistaken this was added because at the time the concern was 
older
kernels which didn't have the HWCAPs bit for these extensions.

So I wonder if the performance was really a problem here, given any kernel with 
the HWCAPS
never gets to the sysreg read, but also, have every kernel that don't have 
these HWCAPS gone
out of support?

If not are we not pessimisting atomics for binaries ran on older kernels?

Thanks,
Tamar

> > libatomic:
> >         * config/linux/aarch64/host-config.h (has_lse2): Mark unused arg.
> >         (has_lse128): Change to use HWCAPs and check size of struct.
> >         (has_rcpc3): Likewise.
> 
> Ok.
> 
> >
> > ---
> >
> > diff --git a/libatomic/config/linux/aarch64/host-config.h
> b/libatomic/config/linux/aarch64/host-config.h
> > index
> 7f91528de5b2d04c4cda0a29622b32cdb1b442aa..78f56bad5aee39afc6138
> 36ebaea66fe6cf76790 100644
> > --- a/libatomic/config/linux/aarch64/host-config.h
> > +++ b/libatomic/config/linux/aarch64/host-config.h
> > @@ -90,7 +90,7 @@ typedef struct __ifunc_arg_t {
> >  #define MIDR_PARTNUM(midr)     (((midr) >> 4) & 0xfff)
> >
> >  static inline bool
> > -has_lse2 (unsigned long hwcap, const __ifunc_arg_t *features)
> > +has_lse2 (unsigned long hwcap, const __ifunc_arg_t *features UNUSED)
> >  {
> >    /* Check for LSE2.  */
> >    if (hwcap & HWCAP_USCAT)
> > @@ -109,50 +109,23 @@ has_lse2 (unsigned long hwcap, const
> __ifunc_arg_t *features)
> >    return false;
> >  }
> >
> > -/* LSE128 atomic support encoded in ID_AA64ISAR0_EL1.Atomic,
> bits[23:20].
> > -   The minimum value for LSE128 is 0b0011.  */
> > -
> > -#define AT_FEAT_FIELD(isar0)   (((isar0) >> 20) & 15)
> > -
> >  static inline bool
> >  has_lse128 (unsigned long hwcap, const __ifunc_arg_t *features)
> >  {
> > -  if (hwcap & _IFUNC_ARG_HWCAP && features->_hwcap2 &
> HWCAP2_LSE128)
> > -    return true;
> > -
> > -  /* If LSE2 and CPUID are supported, check for LSE128.  */
> > -  if (hwcap & HWCAP_CPUID && hwcap & HWCAP_USCAT)
> > -    {
> > -      unsigned long isar0;
> > -      asm volatile ("mrs %0, ID_AA64ISAR0_EL1" : "=r" (isar0));
> > -      return AT_FEAT_FIELD (isar0) >= 3;
> > -    }
> > -
> > -  return false;
> > +  return (hwcap & _IFUNC_ARG_HWCAP
> > +         && features->_size > offsetof (__ifunc_arg_t, _hwcap2)
> > +         && features->_hwcap2 & HWCAP2_LSE128);
> >  }
> >
> > -/* LRCPC atomic support encoded in ID_AA64ISAR1_EL1.Atomic,
> bits[23:20].
> > -   The minimum value for LRCPC3 is 0b0011.  */
> > -
> >  static inline bool
> >  has_rcpc3 (unsigned long hwcap, const __ifunc_arg_t *features)
> >  {
> >    /* LSE2 is a prerequisite for atomic LDIAPP/STILP - check HWCAP_USCAT
> since
> > -     has_lse2 is more expensive and Neoverse N1 does not have LRCPC3. */
> > -  if (!(hwcap & HWCAP_USCAT))
> > -    return false;
> > -
> > -  if (hwcap & _IFUNC_ARG_HWCAP && features->_hwcap2 &
> HWCAP2_LRCPC3)
> > -    return true;
> > -
> > -  if (hwcap & HWCAP_CPUID)
> > -    {
> > -      unsigned long isar1;
> > -      asm volatile ("mrs %0, ID_AA64ISAR1_EL1" : "=r" (isar1));
> > -      return AT_FEAT_FIELD (isar1) >= 3;
> > -    }
> > -
> > -  return false;
> > +     has_lse2 is more expensive and Neoverse N1 does not have LRCPC3.  */
> > +  return (hwcap & _IFUNC_ARG_HWCAP
> > +         && features->_size > offsetof (__ifunc_arg_t, _hwcap2)
> > +         && features->_hwcap & HWCAP_USCAT
> > +         && features->_hwcap2 & HWCAP2_LRCPC3);
> >  }
> >
> >  #endif /* HAVE_IFUNC */
> >

Reply via email to