[glibc] Vectorise special cases for SVE log1p(f)

Adhemerval Zanella via Glibc-cvs <[email protected]> Thu, 21 May 2026 13:06:18 +0000 (GMT)
Newsgroups gmane.comp.lib.glibc.cvs
Message-ID <[email protected]>
https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=a7b6e534629c821e456955a00cf68bf889a601a8

commit a7b6e534629c821e456955a00cf68bf889a601a8
Author: Thomas Daubney <[email protected]>
Date:   Mon May 18 16:20:53 2026 +0000

    Vectorise special cases for SVE log1p(f)
    
    This patch adds vectorised special cases for the SVE log functions
    log1p and log1pf.
    
    When built with GCC-15 and executed on a Neoverse V2 platform, the
    following benchmarking throughput uplifts were measured:
    
    log1pf -> 285% speed-up (4.85 ns/element to 1.26 ns/element)
    log1p  -> 117% speed-up (8.25 ns/element to 3.80 ns/element)
    
    Note that the numbers here are for the special case path only and that
    the fast path performance has been maintained. These changes have also
    maintained the same level of accuracy as before.

Diff:
---
 sysdeps/aarch64/fpu/log1p_sve.c        | 10 +++++++---
 sysdeps/aarch64/fpu/log1pf_sve.c       | 21 +++++++++++++++------
 sysdeps/aarch64/fpu/sv_log1pf_inline.h |  1 -
 3 files changed, 22 insertions(+), 10 deletions(-)

diff --git a/sysdeps/aarch64/fpu/log1p_sve.c b/sysdeps/aarch64/fpu/log1p_sve.c
index bde0e8a7d1..6eb0161c07 100644
--- a/sysdeps/aarch64/fpu/log1p_sve.c
+++ b/sysdeps/aarch64/fpu/log1p_sve.c
@@ -63,9 +63,13 @@ static const struct data
 #define BottomMask 0xffffffff
 
 static svfloat64_t NOINLINE
-special_case (svfloat64_t x, svfloat64_t y, svbool_t special)
+special_case (svfloat64_t x, svfloat64_t y, svbool_t special, svbool_t pg)
 {
-  return sv_call_f64 (log1p, x, y, special);
+  y = svsel (special, sv_f64 (NAN), y);
+  svbool_t ret_pinf = svcmpeq (pg, x, INFINITY);
+  svbool_t ret_minf = svcmpeq (pg, x, -1.0);
+  y = svsel (ret_pinf, sv_f64 (INFINITY), y);
+  return svsel (ret_minf, sv_f64 (-INFINITY), y);
 }
 
 /* Vector approximation for log1p using polynomial on reduced interval. Maximum
@@ -159,7 +163,7 @@ svfloat64_t SV_NAME_D1 (log1p) (svfloat64_t x, svbool_t pg)
   if (__glibc_unlikely (svptest_any (pg, special)))
     return special_case (
 	x, svmla_x (svptrue_b64 (), svadd_x (svptrue_b64 (), ylo, yhi), f2, p),
-	special);
+	special, pg);
   return svmla_x (svptrue_b64 (), svadd_x (svptrue_b64 (), ylo, yhi), f2, p);
 }
 
diff --git a/sysdeps/aarch64/fpu/log1pf_sve.c b/sysdeps/aarch64/fpu/log1pf_sve.c
index f4d409eb50..450892cedf 100644
--- a/sysdeps/aarch64/fpu/log1pf_sve.c
+++ b/sysdeps/aarch64/fpu/log1pf_sve.c
@@ -17,14 +17,21 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
+#include "../../ieee754/flt-32/math_config.h"
 #include "sv_math.h"
 #include "sv_log1pf_inline.h"
 
 static svfloat32_t NOINLINE
-special_case (svfloat32_t x, svbool_t special)
+special_case (svfloat32_t x, svfloat32_t y, svbool_t pg, svbool_t special,
+	      const struct sv_log1pf_data *d)
 {
-  return sv_call_f32 (log1pf, x, sv_log1pf_inline (x, svptrue_b32 ()),
-		      special);
+  y = svsel_f32 (special, svreinterpret_f32 (sv_u32 (d->nan)), y);
+
+  svbool_t ret_pinf = svcmpeq (pg, x, asfloat (d->inf));
+  svbool_t ret_minf = svcmpeq (pg, x, -1.0f);
+
+  y = svsel_f32 (ret_pinf, svreinterpret_f32 (sv_u32 (d->inf)), y);
+  return svsel_f32 (ret_minf, sv_f32 (-d->inf), y);
 }
 
 /* Vector log1pf approximation using polynomial on reduced interval. Worst-case
@@ -33,12 +40,14 @@ special_case (svfloat32_t x, svbool_t special)
 				 want 0x1.9f323ep-2.  */
 svfloat32_t SV_NAME_F1 (log1p) (svfloat32_t x, svbool_t pg)
 {
+
+  const struct sv_log1pf_data *d = ptr_barrier (&sv_log1pf_data);
   /* x < -1, Inf/Nan.  */
-  svbool_t special = svcmpeq (pg, svreinterpret_u32 (x), 0x7f800000);
-  special = svorn_z (pg, special, svcmpge (pg, x, -1));
+  svbool_t special = svcmpeq (pg, svreinterpret_u32 (x), d->inf);
+  special = svorn_z (pg, special, svcmpge (pg, x, -1.0f));
 
   if (__glibc_unlikely (svptest_any (pg, special)))
-    return special_case (x, special);
+    return special_case (x, sv_log1pf_inline (x, pg), pg, special, d);
 
   return sv_log1pf_inline (x, pg);
 }
diff --git a/sysdeps/aarch64/fpu/sv_log1pf_inline.h b/sysdeps/aarch64/fpu/sv_log1pf_inline.h
index 0043df952c..3677578c59 100644
--- a/sysdeps/aarch64/fpu/sv_log1pf_inline.h
+++ b/sysdeps/aarch64/fpu/sv_log1pf_inline.h
@@ -21,7 +21,6 @@
 #define AARCH64_FPU_SV_LOG1PF_INLINE_H
 
 #include "sv_math.h"
-#include "vecmath_config.h"
 
 #define SignExponentMask 0xff800000