[PATCH] AArch64: Remove prefer_sve_ifuncs

Wilco Dijkstra Wilco.Dijkstra@arm.com
Mon Mar 16 14:38:52 GMT 2026


Remove the prefer_sve_ifuncs CPU feature since it was intended for older
kernels. Current distros all use modern Linux kernels with improved support for
SVE save/restore, making this check redundant.

OK for commit?

---

diff --git a/sysdeps/aarch64/cpu-features.h b/sysdeps/aarch64/cpu-features.h
index 1fe35d986b14a14fd55d6e4d3ac59fbb21e55f71..a6ec3eebe9a5f3dba9367d0f9b7a48b4de54c08c 100644
--- a/sysdeps/aarch64/cpu-features.h
+++ b/sysdeps/aarch64/cpu-features.h
@@ -70,7 +70,7 @@ struct cpu_features
   /* Currently, the GLIBC memory tagging tunable only defines 8 bits.  */
   uint8_t mte_state;
   bool sve;
-  bool prefer_sve_ifuncs;
+  bool unused;
   bool mops;
 };
 
diff --git a/sysdeps/aarch64/dl-diagnostics-cpu.c b/sysdeps/aarch64/dl-diagnostics-cpu.c
index 48212e43077e1a9b294746b3261b5d24b5286515..697868cb25a6b52616791d8538b529a4bfcafb07 100644
--- a/sysdeps/aarch64/dl-diagnostics-cpu.c
+++ b/sysdeps/aarch64/dl-diagnostics-cpu.c
@@ -47,8 +47,6 @@ _dl_diagnostics_cpu (void)
   print_cpu_features_value ("mops", GLRO (dl_aarch64_cpu_features).mops);
   print_cpu_features_value ("mte_state",
                             GLRO (dl_aarch64_cpu_features).mte_state);
-  print_cpu_features_value ("prefer_sve_ifuncs",
-                            GLRO (dl_aarch64_cpu_features).prefer_sve_ifuncs);
   print_cpu_features_value ("sve", GLRO (dl_aarch64_cpu_features).sve);
   print_cpu_features_value ("zva_size",
                             GLRO (dl_aarch64_cpu_features).zva_size);
diff --git a/sysdeps/aarch64/multiarch/init-arch.h b/sysdeps/aarch64/multiarch/init-arch.h
index 4357461cb91d5ecb6d5365ff8bccdb515fb4414b..8afd91164fadb683367229a424612224c5f5ee20 100644
--- a/sysdeps/aarch64/multiarch/init-arch.h
+++ b/sysdeps/aarch64/multiarch/init-arch.h
@@ -36,7 +36,5 @@
     MTE_ENABLED ();							      \
   bool __attribute__((unused)) sve =					      \
     GLRO(dl_aarch64_cpu_features).sve;					      \
-  bool __attribute__((unused)) prefer_sve_ifuncs =			      \
-    GLRO(dl_aarch64_cpu_features).prefer_sve_ifuncs;			      \
   bool __attribute__((unused)) mops =					      \
     GLRO(dl_aarch64_cpu_features).mops;
diff --git a/sysdeps/aarch64/multiarch/memcpy.c b/sysdeps/aarch64/multiarch/memcpy.c
index be5ca1d4da761a0534b09650a7bc338aaeb7861f..8b678ddb76f098df3a58506f51798c2bce2d1956 100644
--- a/sysdeps/aarch64/multiarch/memcpy.c
+++ b/sysdeps/aarch64/multiarch/memcpy.c
@@ -51,7 +51,7 @@ select_memcpy_ifunc (void)
 
       if (IS_A64FX (midr))
 	return __memcpy_a64fx;
-      return prefer_sve_ifuncs ? __memcpy_sve : __memcpy_generic;
+      return __memcpy_sve;
     }
 
   if (IS_ORYON1 (midr))
diff --git a/sysdeps/aarch64/multiarch/memmove.c b/sysdeps/aarch64/multiarch/memmove.c
index 49a9a8e6c06e74c484e157eba6c80d56bf00f760..cec32104be8d7631ea3e4931e668116405300a0a 100644
--- a/sysdeps/aarch64/multiarch/memmove.c
+++ b/sysdeps/aarch64/multiarch/memmove.c
@@ -45,7 +45,7 @@ select_memmove_ifunc (void)
     {
       if (IS_A64FX (midr))
 	return __memmove_a64fx;
-      return prefer_sve_ifuncs ? __memmove_sve : __memmove_generic;
+      return __memmove_sve;
     }
 
   return __memmove_generic;
diff --git a/sysdeps/aarch64/multiarch/memset.c b/sysdeps/aarch64/multiarch/memset.c
index 76c6532b811e3bfab31bb60b4270305c8b60a811..19f170e861e87fd2a3e9bf327e5277992077c2e4 100644
--- a/sysdeps/aarch64/multiarch/memset.c
+++ b/sysdeps/aarch64/multiarch/memset.c
@@ -51,7 +51,7 @@ select_memset_ifunc (void)
       if (IS_A64FX (midr) && zva_size == 256)
 	return __memset_a64fx;
 
-      if (prefer_sve_ifuncs && zva_size == 64)
+      if (zva_size == 64)
 	return __memset_sve_zva64;
     }
 
diff --git a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
index 15aed15a667e89abd2790a22a319a8a6aaecba02..1e4f8a86b1017e5682aec29e975061a31160af46 100644
--- a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
+++ b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
@@ -65,46 +65,6 @@ get_midr_from_mcpu (const struct tunable_str_t *mcpu)
   return UINT64_MAX;
 }
 
-#if __LINUX_KERNEL_VERSION < 0x060200
-
-/* Return true if we prefer using SVE in string ifuncs.  Old kernels disable
-   SVE after every system call which results in unnecessary traps if memcpy
-   uses SVE.  This is true for kernels between 4.15.0 and before 6.2.0, except
-   for 5.14.0 which was patched.  For these versions return false to avoid using
-   SVE ifuncs.
-   Parse the kernel version into a 24-bit kernel.major.minor value without
-   calling any library functions.  If uname() is not supported or if the version
-   format is not recognized, assume the kernel is modern and return true.  */
-
-static inline bool
-prefer_sve_ifuncs (void)
-{
-  struct utsname buf;
-  const char *p = &buf.release[0];
-  int kernel = 0;
-  int val;
-
-  if (__uname (&buf) < 0)
-    return true;
-
-  for (int shift = 16; shift >= 0; shift -= 8)
-    {
-      for (val = 0; *p >= '0' && *p <= '9'; p++)
-	val = val * 10 + *p - '0';
-      kernel |= (val & 255) << shift;
-      if (*p++ != '.')
-	break;
-    }
-
-  if (kernel >= 0x060200 || kernel == 0x050e00)
-    return true;
-  if (kernel >= 0x040f00)
-    return false;
-  return true;
-}
-
-#endif
-
 static inline void
 init_cpu_features (struct cpu_features *cpu_features)
 {
@@ -171,13 +131,6 @@ init_cpu_features (struct cpu_features *cpu_features)
   /* Check if SVE is supported.  */
   cpu_features->sve = GLRO (dl_hwcap) & HWCAP_SVE;
 
-  cpu_features->prefer_sve_ifuncs = cpu_features->sve;
-
-#if __LINUX_KERNEL_VERSION < 0x060200
-  if (cpu_features->sve)
-    cpu_features->prefer_sve_ifuncs = prefer_sve_ifuncs ();
-#endif
-
   /* Check if MOPS is supported.  */
   cpu_features->mops = GLRO (dl_hwcap2) & HWCAP2_MOPS;
 



More information about the Libc-alpha mailing list