math: remove exp10 wrappers

Message ID PAWPR08MB8982B890E56F47D87BCFD2E483692@PAWPR08MB8982.eurprd08.prod.outlook.com
State Committed
Headers
Series math: remove exp10 wrappers |

Checks

Context Check Description
redhat-pt-bot/TryBot-apply_patch success Patch applied to master at the time it was sent
redhat-pt-bot/TryBot-32bit success Build for i686
linaro-tcwg-bot/tcwg_glibc_build--master-arm success Testing passed
linaro-tcwg-bot/tcwg_glibc_build--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_glibc_check--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_glibc_check--master-arm success Testing passed

Commit Message

Wilco Dijkstra Jan. 10, 2024, 4:03 p.m. UTC
  Remove the error handling wrapper from exp10.  This is very similar to
the changes done to exp and exp2, except that we also need to handle
pow10 and pow10l.

Passes build-many-glibcs.py and regress on AArch64.  OK for commit?

---
  

Comments

Adhemerval Zanella Netto Jan. 10, 2024, 6:48 p.m. UTC | #1
On 10/01/24 13:03, Wilco Dijkstra wrote:
> Remove the error handling wrapper from exp10.  This is very similar to
> the changes done to exp and exp2, except that we also need to handle
> pow10 and pow10l.
> 
> Passes build-many-glibcs.py and regress on AArch64.  OK for commit?

LGTM, thanks.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>

As a side node, I am checking if it is possible to remove the i686 version
in favor of the generic one and it seems that the double_t usage on generic
implementation does not guarantee either a faster or conformant implementation
(i386 uses FLT_EVAL_METHOD=2 and the resulting exp10 shows a lot precision
issues with math tests).  Does it really need to use double_t?

> 
> ---
> 
> diff --git a/math/Versions b/math/Versions
> index 759b5fac7f43739de9bf63fcb5d41fae071ee86b..26e15cedea26c1d6ed63da6f5fe60716089d135f 100644
> --- a/math/Versions
> +++ b/math/Versions
> @@ -635,4 +635,8 @@ libm {
>      # No SVID compatible error handling.
>      fmod; fmodf;
>    }
> +  GLIBC_2.39 {
> +    # No SVID compatible error handling.
> +    exp10;
> +  }
>  }

Ok.

> diff --git a/math/w_exp10_compat.c b/math/w_exp10_compat.c
> index b13592d29c934c58f4a55b9b03408e0a6a911cb5..3f717813fdbdcf2112bdd45f1e8d6000b495e904 100644
> --- a/math/w_exp10_compat.c
> +++ b/math/w_exp10_compat.c
> @@ -25,9 +25,15 @@
>  #include <math-svid-compat.h>
>  #include <libm-alias-double.h>
>  
> -#if LIBM_SVID_COMPAT
> +#ifndef NO_COMPAT_NEEDED
> +# define NO_COMPAT_NEEDED 0
> +#endif
> +
> +#if LIBM_SVID_COMPAT && (SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_39) \
> +			 || defined NO_LONG_DOUBLE \
> +			 || defined LONG_DOUBLE_COMPAT)
>  double
> -__exp10 (double x)
> +__exp10_compat (double x)
>  {
>    double z = __ieee754_exp10 (x);
>    if (__builtin_expect (!isfinite (z) || z == 0, 0)
> @@ -37,14 +43,30 @@ __exp10 (double x)
>  
>    return z;
>  }
> -libm_alias_double (__exp10, exp10)
> +# if NO_COMPAT_NEEDED
> +#  ifdef SHARED
> +libm_alias_double (__exp10_compat, exp10)
> +#  endif
> +#else
> +#  if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_39)
> +compat_symbol (libm, __exp10_compat, exp10, GLIBC_2_1);
> +#  endif
> +#  ifdef NO_LONG_DOUBLE
> +weak_alias (__exp10_compat, exp10l)
> +#  endif
> +#  ifdef LONG_DOUBLE_COMPAT
> +LONG_DOUBLE_COMPAT_CHOOSE_libm_exp10l (
> +  compat_symbol (libm, __exp10_compat, exp10l, FIRST_VERSION_libm_exp10l), );
> +#  endif
> +# endif
> +
>  # if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_27)
> -strong_alias (__exp10, __pow10)
> +strong_alias (__exp10_compat, __pow10)
>  compat_symbol (libm, __pow10, pow10, GLIBC_2_1);
>  # endif
>  # ifdef NO_LONG_DOUBLE
>  #  if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_27)
> -strong_alias (__exp10l, __pow10l)
> +strong_alias (exp10l, __pow10l)
>  compat_symbol (libm, __pow10l, pow10l, GLIBC_2_1);
>  #  endif
>  # endif
> diff --git a/sysdeps/i386/fpu/w_exp10_compat.c b/sysdeps/i386/fpu/w_exp10_compat.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..402356ae9977b54e39b4a068541122e46b05633b
> --- /dev/null
> +++ b/sysdeps/i386/fpu/w_exp10_compat.c
> @@ -0,0 +1,3 @@
> +/* i386 provides an optimized __ieee752_exp10.  */

s/__ieee752_exp10/__ieee754_exp10

> +#define NO_COMPAT_NEEDED 1
> +#include <math/w_exp10_compat.c>
> diff --git a/sysdeps/ieee754/dbl-64/e_exp10.c b/sysdeps/ieee754/dbl-64/e_exp10.c
> index 08069140c076d0b1c9c49454aaf6fe3740c80205..0fa9b11aae9355c115699df0b1e337b1d455c5e4 100644
> --- a/sysdeps/ieee754/dbl-64/e_exp10.c
> +++ b/sysdeps/ieee754/dbl-64/e_exp10.c
> @@ -18,9 +18,9 @@
>  #include <math.h>
>  #include <math-barriers.h>
>  #include <math-narrow-eval.h>
> -#include <math_private.h>
> -#include <float.h>
> +#include <math-svid-compat.h>
>  #include <libm-alias-finite.h>
> +#include <libm-alias-double.h>
>  #include "math_config.h"
>  
>  #define N (1 << EXP_TABLE_BITS)
> @@ -75,7 +75,7 @@ special_case (uint64_t sbits, double_t tmp, uint64_t ki)
>  
>  /* Double-precision 10^x approximation. Largest observed error is ~0.513 ULP.  */
>  double
> -__ieee754_exp10 (double x)
> +__exp10 (double x)
>  {
>    uint64_t ix = asuint64 (x);
>    uint32_t abstop = (ix >> 52) & 0x7ff;
> @@ -144,4 +144,11 @@ __ieee754_exp10 (double x)
>    return s * y + s;
>  }
>  
> +strong_alias (__exp10, __ieee754_exp10)
>  libm_alias_finite (__ieee754_exp10, __exp10)
> +#if LIBM_SVID_COMPAT
> +versioned_symbol (libm, __exp10, exp10, GLIBC_2_39);
> +libm_alias_double_other (__exp10, exp10)
> +#else
> +libm_alias_double (__exp10, exp10)
> +#endif

Ok.

> diff --git a/sysdeps/ieee754/dbl-64/w_exp10.c b/sysdeps/ieee754/dbl-64/w_exp10.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..1cc8931700702e65d29a6e2af287175d23c6b182
> --- /dev/null
> +++ b/sysdeps/ieee754/dbl-64/w_exp10.c
> @@ -0,0 +1 @@
> +/* Not needed.  */

Ok.

> diff --git a/sysdeps/m68k/m680x0/fpu/w_exp10_compat.c b/sysdeps/m68k/m680x0/fpu/w_exp10_compat.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..07287923d74fb50698dec1ff7a51431b827aa004
> --- /dev/null
> +++ b/sysdeps/m68k/m680x0/fpu/w_exp10_compat.c
> @@ -0,0 +1,3 @@
> +/* m68k provides an optimized __ieee752_exp10.  */
> +#define NO_COMPAT_NEEDED 1
> +#include <math/w_exp10_compat.c>

Ok.

> diff --git a/sysdeps/unix/sysv/linux/aarch64/libm.abilist b/sysdeps/unix/sysv/linux/aarch64/libm.abilist
> index e3924c3499d290fc96e4e6919bc8a26da8f7777c..f0da228fbba6e6fdb8f1fd24285478bdda333a16 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/aarch64/libm.abilist
> @@ -1148,3 +1148,4 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
> diff --git a/sysdeps/unix/sysv/linux/alpha/libm.abilist b/sysdeps/unix/sysv/linux/alpha/libm.abilist
> index 066dd1a6b371d060eea4196f83fd86d8dacdf614..f5d8023d624e9cb0ae24a088b6dd0e00c2a9d560 100644
> --- a/sysdeps/unix/sysv/linux/alpha/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/alpha/libm.abilist
> @@ -1205,6 +1205,7 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
>  GLIBC_2.4 __clog10l F
>  GLIBC_2.4 __finitel F
>  GLIBC_2.4 __fpclassifyl F
> diff --git a/sysdeps/unix/sysv/linux/arm/be/libm.abilist b/sysdeps/unix/sysv/linux/arm/be/libm.abilist
> index 4adfed072b0239d5508559c2442cf30cb064d7b7..f020a8a9043d4d211e2404b7dbb3095eeb792fd3 100644
> --- a/sysdeps/unix/sysv/linux/arm/be/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/arm/be/libm.abilist
> @@ -535,6 +535,7 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
>  GLIBC_2.4 _LIB_VERSION D 0x4
>  GLIBC_2.4 __clog10 F
>  GLIBC_2.4 __clog10f F
> diff --git a/sysdeps/unix/sysv/linux/arm/le/libm.abilist b/sysdeps/unix/sysv/linux/arm/le/libm.abilist
> index 4adfed072b0239d5508559c2442cf30cb064d7b7..f020a8a9043d4d211e2404b7dbb3095eeb792fd3 100644
> --- a/sysdeps/unix/sysv/linux/arm/le/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/arm/le/libm.abilist
> @@ -535,6 +535,7 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
>  GLIBC_2.4 _LIB_VERSION D 0x4
>  GLIBC_2.4 __clog10 F
>  GLIBC_2.4 __clog10f F
> diff --git a/sysdeps/unix/sysv/linux/hppa/libm.abilist b/sysdeps/unix/sysv/linux/hppa/libm.abilist
> index 5c3f47caefe8d89a95d0fbd3663c623eaefa5778..450ac03223c0258af2c5d23a031d54b24461cc24 100644
> --- a/sysdeps/unix/sysv/linux/hppa/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/hppa/libm.abilist
> @@ -846,4 +846,5 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
>  GLIBC_2.4 exp2l F
> diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist
> index 4adfed072b0239d5508559c2442cf30cb064d7b7..f020a8a9043d4d211e2404b7dbb3095eeb792fd3 100644
> --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist
> @@ -535,6 +535,7 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
>  GLIBC_2.4 _LIB_VERSION D 0x4
>  GLIBC_2.4 __clog10 F
>  GLIBC_2.4 __clog10f F
> diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libm.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libm.abilist
> index ea0dbd4b727a618bc9598a27ea2dd4a2bd1b8a30..1f7f63f60cd7b9fbe1e1ef240afda3b3c3bd20c0 100644
> --- a/sysdeps/unix/sysv/linux/microblaze/be/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/microblaze/be/libm.abilist
> @@ -847,3 +847,4 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
> diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libm.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libm.abilist
> index ea0dbd4b727a618bc9598a27ea2dd4a2bd1b8a30..1f7f63f60cd7b9fbe1e1ef240afda3b3c3bd20c0 100644
> --- a/sysdeps/unix/sysv/linux/microblaze/le/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/microblaze/le/libm.abilist
> @@ -847,3 +847,4 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips32/libm.abilist b/sysdeps/unix/sysv/linux/mips/mips32/libm.abilist
> index 7c94a8db706e39147886da035e4a07fa12032bb7..797071aee8c56f9f8538bf5a50d44b164c5e26c4 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips32/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips32/libm.abilist
> @@ -846,4 +846,5 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
>  GLIBC_2.4 exp2l F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/libm.abilist b/sysdeps/unix/sysv/linux/mips/mips64/libm.abilist
> index 0d08245adf0e1e652aa0a6eb4707509208bc582b..14758703cfb72749902907dec5cfa288116a76cf 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips64/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips64/libm.abilist
> @@ -1148,3 +1148,4 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
> diff --git a/sysdeps/unix/sysv/linux/nios2/libm.abilist b/sysdeps/unix/sysv/linux/nios2/libm.abilist
> index a3b776fece3a4f5b50fb4c88500384027eea9e37..c0ebe119dc05aea86cbc48c3eff6c9b090069607 100644
> --- a/sysdeps/unix/sysv/linux/nios2/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/nios2/libm.abilist
> @@ -847,3 +847,4 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist
> index c696215739f408f4b16008a76d1007fa80d52f5a..4f88e0af9ca9d30c9e9fe5172803464d400a25d0 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist
> @@ -892,6 +892,7 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
>  GLIBC_2.4 __clog10l F
>  GLIBC_2.4 __finitel F
>  GLIBC_2.4 __fpclassifyl F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist
> index a5ce9b1997939909e3239fe5b694246a410aeb56..edc26140dca7b309f9412d870cf6cca1771aeb98 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist
> @@ -891,6 +891,7 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
>  GLIBC_2.4 __clog10l F
>  GLIBC_2.4 __finitel F
>  GLIBC_2.4 __fpclassifyl F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libm.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libm.abilist
> index 8e41056d0d4a588b4f8346e4b8bab3742036cdd0..0a8a1433d765358734ea688c71b23d097a70b92c 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libm.abilist
> @@ -885,6 +885,7 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
>  GLIBC_2.4 __clog10l F
>  GLIBC_2.4 __finitel F
>  GLIBC_2.4 __fpclassifyl F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libm.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libm.abilist
> index 939f29a0f28023d1307bb7e84c62be8161bfdd71..5174d20032330b26d4f66ce8525a4ede9c1bd2dc 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libm.abilist
> @@ -1320,3 +1320,4 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
> diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist
> index 4baefb1217b27d42023c0f39cb5425fd5ac35ee6..5ff11fb54f26696433f9c0d577ae429aafc42878 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist
> @@ -1149,6 +1149,7 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
>  GLIBC_2.4 __clog10l F
>  GLIBC_2.4 __finitel F
>  GLIBC_2.4 __fpclassifyl F
> diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist
> index debb767575907b5ff5e1a335aaf06b0ee8b41d18..0e246c2c54f537ede4bdd1d8f23ce3f98da682f2 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist
> @@ -1149,6 +1149,7 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
>  GLIBC_2.4 __clog10l F
>  GLIBC_2.4 __finitel F
>  GLIBC_2.4 __fpclassifyl F
> diff --git a/sysdeps/unix/sysv/linux/sh/be/libm.abilist b/sysdeps/unix/sysv/linux/sh/be/libm.abilist
> index fb94386fffdc81329031c0f26545ea22ddb4cc8e..7b43a866e20c4f51f06fcf4bcd10ec1534bc1a8d 100644
> --- a/sysdeps/unix/sysv/linux/sh/be/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/sh/be/libm.abilist
> @@ -846,4 +846,5 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
>  GLIBC_2.4 exp2l F
> diff --git a/sysdeps/unix/sysv/linux/sh/le/libm.abilist b/sysdeps/unix/sysv/linux/sh/le/libm.abilist
> index fb94386fffdc81329031c0f26545ea22ddb4cc8e..7b43a866e20c4f51f06fcf4bcd10ec1534bc1a8d 100644
> --- a/sysdeps/unix/sysv/linux/sh/le/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/sh/le/libm.abilist
> @@ -846,4 +846,5 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
>  GLIBC_2.4 exp2l F
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist
> index 2fdb5ff14508606311e2a24595c5f46552bda578..e3dcf3d4e7ecf3f07ca67ebec75c5497e018c127 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist
> @@ -1156,6 +1156,7 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
>  GLIBC_2.4 __clog10l F
>  GLIBC_2.4 __finitel F
>  GLIBC_2.4 __fpclassifyl F
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist
> index 02d4c3a754862f8205267f6baf69a020df9dfa99..20fef20c8b5e04c756b2a3b7797830745632beab 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist
> @@ -1148,3 +1148,4 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
> diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libm.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libm.abilist
> index cc8be5b510d832d77d11b6e89e424492bc42dba1..c1c5c76e26189bee20892d6ea15a3d22ab22d834 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/64/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/64/libm.abilist
> @@ -1181,3 +1181,4 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
> diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist
> index fda4df265316c534102192201474b8b26c4e9a47..fac219d45ab2f03e16574d0d119bfce2c62795d8 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist
> @@ -1181,3 +1181,4 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
> 

Ok.
  
Wilco Dijkstra Jan. 10, 2024, 9:35 p.m. UTC | #2
Hi Adhemerval,

> As a side node, I am checking if it is possible to remove the i686 version
> in favor of the generic one and it seems that the double_t usage on generic
> implementation does not guarantee either a faster or conformant implementation
> (i386 uses FLT_EVAL_METHOD=2 and the resulting exp10 shows a lot precision
> issues with math tests).  Does it really need to use double_t?

Yes it would be great to remove target specific math implementations. With IA64
removed I think the only ones left are x86 and m68k. Both would be better off using
the generic math code.

We added double_t to use wider internal precision without storing to memory all the
time. In principle it should be faster overall. Exp10 uses double_t like exp and exp2,
so I'm surprised it doesn't work. I do notice both exp/exp2 do ki = asuint64 (kd);
while exp10 just does ki = kd, but it's not clear that would make a difference on x86.

Cheers,
Wilco
  
Joseph Myers Jan. 11, 2024, 2:11 a.m. UTC | #3
On Wed, 10 Jan 2024, Wilco Dijkstra wrote:

> Yes it would be great to remove target specific math implementations. 
> With IA64 removed I think the only ones left are x86 and m68k. Both 
> would be better off using the generic math code.

Note that for ldbl-96, some functions may not have "generic" versions, 
just architecture-specific ones (for x86, m68k, and formerly ia64) - 
though in most cases likely generic functions for float and double are 
indeed preferable to x86 ones (subject to benchmarking).
  
Andreas Schwab Jan. 11, 2024, 9:06 a.m. UTC | #4
On Jan 11 2024, Joseph Myers wrote:

> Note that for ldbl-96, some functions may not have "generic" versions, 
> just architecture-specific ones (for x86, m68k, and formerly ia64) - 

Also, ldbl-96 differs between x86 and m68k.
  
Adhemerval Zanella Netto Jan. 11, 2024, 12:35 p.m. UTC | #5
On 10/01/24 18:35, Wilco Dijkstra wrote:
> Hi Adhemerval,
> 
>> As a side node, I am checking if it is possible to remove the i686 version
>> in favor of the generic one and it seems that the double_t usage on generic
>> implementation does not guarantee either a faster or conformant implementation
>> (i386 uses FLT_EVAL_METHOD=2 and the resulting exp10 shows a lot precision
>> issues with math tests).  Does it really need to use double_t?
> 
> Yes it would be great to remove target specific math implementations. With IA64
> removed I think the only ones left are x86 and m68k. Both would be better off using
> the generic math code.
> 
> We added double_t to use wider internal precision without storing to memory all the
> time. In principle it should be faster overall. Exp10 uses double_t like exp and exp2,
> so I'm surprised it doesn't work. I do notice both exp/exp2 do ki = asuint64 (kd);
> while exp10 just does ki = kd, but it's not clear that would make a difference on x86.
> 

The patch below fixes the numerical stability I found on i686:

diff --git a/sysdeps/ieee754/dbl-64/e_exp10.c b/sysdeps/ieee754/dbl-64/e_exp10.c
index 225fc74c4c..f961d58398 100644
--- a/sysdeps/ieee754/dbl-64/e_exp10.c
+++ b/sysdeps/ieee754/dbl-64/e_exp10.c
@@ -99,7 +99,7 @@ __exp10 (double x)

   /* Reduce x: z = x * N / log10(2), k = round(z).  */
   double_t z = __exp_data.invlog10_2N * x;
-  double_t kd;
+  double kd;
   int64_t ki;
 #if TOINT_INTRINSICS
   kd = roundtoint (z);

And I think we haven't see it because all ABIs with FLT_EVAL_METHOD=2 uses
assembly implementations for exp/exp2/exp10 (this is the case for i386
and m68k).

Furthermore, at least with i686 the use of double_t also does not show 
better performance either. The current sysdeps/i386/fpu/e_exp10.S
on a recent CPU (Ryzen 9 5900X) with gcc version 13.2.1:

$ ./benchtests/bench-exp10
  "exp10": {
   "": {
    "duration": 3.71309e+09,
    "iterations": 5.8534e+07,
    "max": 116.55,
    "min": 62.974,
    "mean": 63.4348
   }

The fixed version using double_t:

$ ./benchtests/bench-exp10
  "exp10": {
   "": {
    "duration": 3.71002e+09,
    "iterations": 6.5653e+07,
    "max": 130.499,
    "min": 50.282,
    "mean": 56.5096
   }

And just using double instead of double_t:

$ ./benchtests/bench-exp10
  "exp10": {
   "": {
    "duration": 3.71803e+09,
    "iterations": 7.3563e+07,
    "max": 123.062,
    "min": 43.549,
    "mean": 50.5421
   }
  }

So I am not sure if double_t is really helpful here.
  
Andreas K. Huettel Jan. 11, 2024, 9:46 p.m. UTC | #6
Am Mittwoch, 10. Januar 2024, 17:03:34 CET schrieb Wilco Dijkstra:
> Remove the error handling wrapper from exp10.  This is very similar to
> the changes done to exp and exp2, except that we also need to handle
> pow10 and pow10l.
> 
> Passes build-many-glibcs.py and regress on AArch64.  OK for commit?
> 

OK

> ---
> 
> diff --git a/math/Versions b/math/Versions
> index 759b5fac7f43739de9bf63fcb5d41fae071ee86b..26e15cedea26c1d6ed63da6f5fe60716089d135f 100644
> --- a/math/Versions
> +++ b/math/Versions
> @@ -635,4 +635,8 @@ libm {
>      # No SVID compatible error handling.
>      fmod; fmodf;
>    }
> +  GLIBC_2.39 {
> +    # No SVID compatible error handling.
> +    exp10;
> +  }
>  }
> diff --git a/math/w_exp10_compat.c b/math/w_exp10_compat.c
> index b13592d29c934c58f4a55b9b03408e0a6a911cb5..3f717813fdbdcf2112bdd45f1e8d6000b495e904 100644
> --- a/math/w_exp10_compat.c
> +++ b/math/w_exp10_compat.c
> @@ -25,9 +25,15 @@
>  #include <math-svid-compat.h>
>  #include <libm-alias-double.h>
>  
> -#if LIBM_SVID_COMPAT
> +#ifndef NO_COMPAT_NEEDED
> +# define NO_COMPAT_NEEDED 0
> +#endif
> +
> +#if LIBM_SVID_COMPAT && (SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_39) \
> +			 || defined NO_LONG_DOUBLE \
> +			 || defined LONG_DOUBLE_COMPAT)
>  double
> -__exp10 (double x)
> +__exp10_compat (double x)
>  {
>    double z = __ieee754_exp10 (x);
>    if (__builtin_expect (!isfinite (z) || z == 0, 0)
> @@ -37,14 +43,30 @@ __exp10 (double x)
>  
>    return z;
>  }
> -libm_alias_double (__exp10, exp10)
> +# if NO_COMPAT_NEEDED
> +#  ifdef SHARED
> +libm_alias_double (__exp10_compat, exp10)
> +#  endif
> +#else
> +#  if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_39)
> +compat_symbol (libm, __exp10_compat, exp10, GLIBC_2_1);
> +#  endif
> +#  ifdef NO_LONG_DOUBLE
> +weak_alias (__exp10_compat, exp10l)
> +#  endif
> +#  ifdef LONG_DOUBLE_COMPAT
> +LONG_DOUBLE_COMPAT_CHOOSE_libm_exp10l (
> +  compat_symbol (libm, __exp10_compat, exp10l, FIRST_VERSION_libm_exp10l), );
> +#  endif
> +# endif
> +
>  # if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_27)
> -strong_alias (__exp10, __pow10)
> +strong_alias (__exp10_compat, __pow10)
>  compat_symbol (libm, __pow10, pow10, GLIBC_2_1);
>  # endif
>  # ifdef NO_LONG_DOUBLE
>  #  if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_27)
> -strong_alias (__exp10l, __pow10l)
> +strong_alias (exp10l, __pow10l)
>  compat_symbol (libm, __pow10l, pow10l, GLIBC_2_1);
>  #  endif
>  # endif
> diff --git a/sysdeps/i386/fpu/w_exp10_compat.c b/sysdeps/i386/fpu/w_exp10_compat.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..402356ae9977b54e39b4a068541122e46b05633b
> --- /dev/null
> +++ b/sysdeps/i386/fpu/w_exp10_compat.c
> @@ -0,0 +1,3 @@
> +/* i386 provides an optimized __ieee752_exp10.  */
> +#define NO_COMPAT_NEEDED 1
> +#include <math/w_exp10_compat.c>
> diff --git a/sysdeps/ieee754/dbl-64/e_exp10.c b/sysdeps/ieee754/dbl-64/e_exp10.c
> index 08069140c076d0b1c9c49454aaf6fe3740c80205..0fa9b11aae9355c115699df0b1e337b1d455c5e4 100644
> --- a/sysdeps/ieee754/dbl-64/e_exp10.c
> +++ b/sysdeps/ieee754/dbl-64/e_exp10.c
> @@ -18,9 +18,9 @@
>  #include <math.h>
>  #include <math-barriers.h>
>  #include <math-narrow-eval.h>
> -#include <math_private.h>
> -#include <float.h>
> +#include <math-svid-compat.h>
>  #include <libm-alias-finite.h>
> +#include <libm-alias-double.h>
>  #include "math_config.h"
>  
>  #define N (1 << EXP_TABLE_BITS)
> @@ -75,7 +75,7 @@ special_case (uint64_t sbits, double_t tmp, uint64_t ki)
>  
>  /* Double-precision 10^x approximation. Largest observed error is ~0.513 ULP.  */
>  double
> -__ieee754_exp10 (double x)
> +__exp10 (double x)
>  {
>    uint64_t ix = asuint64 (x);
>    uint32_t abstop = (ix >> 52) & 0x7ff;
> @@ -144,4 +144,11 @@ __ieee754_exp10 (double x)
>    return s * y + s;
>  }
>  
> +strong_alias (__exp10, __ieee754_exp10)
>  libm_alias_finite (__ieee754_exp10, __exp10)
> +#if LIBM_SVID_COMPAT
> +versioned_symbol (libm, __exp10, exp10, GLIBC_2_39);
> +libm_alias_double_other (__exp10, exp10)
> +#else
> +libm_alias_double (__exp10, exp10)
> +#endif
> diff --git a/sysdeps/ieee754/dbl-64/w_exp10.c b/sysdeps/ieee754/dbl-64/w_exp10.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..1cc8931700702e65d29a6e2af287175d23c6b182
> --- /dev/null
> +++ b/sysdeps/ieee754/dbl-64/w_exp10.c
> @@ -0,0 +1 @@
> +/* Not needed.  */
> diff --git a/sysdeps/m68k/m680x0/fpu/w_exp10_compat.c b/sysdeps/m68k/m680x0/fpu/w_exp10_compat.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..07287923d74fb50698dec1ff7a51431b827aa004
> --- /dev/null
> +++ b/sysdeps/m68k/m680x0/fpu/w_exp10_compat.c
> @@ -0,0 +1,3 @@
> +/* m68k provides an optimized __ieee752_exp10.  */
> +#define NO_COMPAT_NEEDED 1
> +#include <math/w_exp10_compat.c>
> diff --git a/sysdeps/unix/sysv/linux/aarch64/libm.abilist b/sysdeps/unix/sysv/linux/aarch64/libm.abilist
> index e3924c3499d290fc96e4e6919bc8a26da8f7777c..f0da228fbba6e6fdb8f1fd24285478bdda333a16 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/aarch64/libm.abilist
> @@ -1148,3 +1148,4 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
> diff --git a/sysdeps/unix/sysv/linux/alpha/libm.abilist b/sysdeps/unix/sysv/linux/alpha/libm.abilist
> index 066dd1a6b371d060eea4196f83fd86d8dacdf614..f5d8023d624e9cb0ae24a088b6dd0e00c2a9d560 100644
> --- a/sysdeps/unix/sysv/linux/alpha/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/alpha/libm.abilist
> @@ -1205,6 +1205,7 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
>  GLIBC_2.4 __clog10l F
>  GLIBC_2.4 __finitel F
>  GLIBC_2.4 __fpclassifyl F
> diff --git a/sysdeps/unix/sysv/linux/arm/be/libm.abilist b/sysdeps/unix/sysv/linux/arm/be/libm.abilist
> index 4adfed072b0239d5508559c2442cf30cb064d7b7..f020a8a9043d4d211e2404b7dbb3095eeb792fd3 100644
> --- a/sysdeps/unix/sysv/linux/arm/be/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/arm/be/libm.abilist
> @@ -535,6 +535,7 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
>  GLIBC_2.4 _LIB_VERSION D 0x4
>  GLIBC_2.4 __clog10 F
>  GLIBC_2.4 __clog10f F
> diff --git a/sysdeps/unix/sysv/linux/arm/le/libm.abilist b/sysdeps/unix/sysv/linux/arm/le/libm.abilist
> index 4adfed072b0239d5508559c2442cf30cb064d7b7..f020a8a9043d4d211e2404b7dbb3095eeb792fd3 100644
> --- a/sysdeps/unix/sysv/linux/arm/le/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/arm/le/libm.abilist
> @@ -535,6 +535,7 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
>  GLIBC_2.4 _LIB_VERSION D 0x4
>  GLIBC_2.4 __clog10 F
>  GLIBC_2.4 __clog10f F
> diff --git a/sysdeps/unix/sysv/linux/hppa/libm.abilist b/sysdeps/unix/sysv/linux/hppa/libm.abilist
> index 5c3f47caefe8d89a95d0fbd3663c623eaefa5778..450ac03223c0258af2c5d23a031d54b24461cc24 100644
> --- a/sysdeps/unix/sysv/linux/hppa/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/hppa/libm.abilist
> @@ -846,4 +846,5 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
>  GLIBC_2.4 exp2l F
> diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist
> index 4adfed072b0239d5508559c2442cf30cb064d7b7..f020a8a9043d4d211e2404b7dbb3095eeb792fd3 100644
> --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist
> @@ -535,6 +535,7 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
>  GLIBC_2.4 _LIB_VERSION D 0x4
>  GLIBC_2.4 __clog10 F
>  GLIBC_2.4 __clog10f F
> diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libm.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libm.abilist
> index ea0dbd4b727a618bc9598a27ea2dd4a2bd1b8a30..1f7f63f60cd7b9fbe1e1ef240afda3b3c3bd20c0 100644
> --- a/sysdeps/unix/sysv/linux/microblaze/be/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/microblaze/be/libm.abilist
> @@ -847,3 +847,4 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
> diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libm.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libm.abilist
> index ea0dbd4b727a618bc9598a27ea2dd4a2bd1b8a30..1f7f63f60cd7b9fbe1e1ef240afda3b3c3bd20c0 100644
> --- a/sysdeps/unix/sysv/linux/microblaze/le/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/microblaze/le/libm.abilist
> @@ -847,3 +847,4 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips32/libm.abilist b/sysdeps/unix/sysv/linux/mips/mips32/libm.abilist
> index 7c94a8db706e39147886da035e4a07fa12032bb7..797071aee8c56f9f8538bf5a50d44b164c5e26c4 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips32/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips32/libm.abilist
> @@ -846,4 +846,5 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
>  GLIBC_2.4 exp2l F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/libm.abilist b/sysdeps/unix/sysv/linux/mips/mips64/libm.abilist
> index 0d08245adf0e1e652aa0a6eb4707509208bc582b..14758703cfb72749902907dec5cfa288116a76cf 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips64/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips64/libm.abilist
> @@ -1148,3 +1148,4 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
> diff --git a/sysdeps/unix/sysv/linux/nios2/libm.abilist b/sysdeps/unix/sysv/linux/nios2/libm.abilist
> index a3b776fece3a4f5b50fb4c88500384027eea9e37..c0ebe119dc05aea86cbc48c3eff6c9b090069607 100644
> --- a/sysdeps/unix/sysv/linux/nios2/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/nios2/libm.abilist
> @@ -847,3 +847,4 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist
> index c696215739f408f4b16008a76d1007fa80d52f5a..4f88e0af9ca9d30c9e9fe5172803464d400a25d0 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist
> @@ -892,6 +892,7 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
>  GLIBC_2.4 __clog10l F
>  GLIBC_2.4 __finitel F
>  GLIBC_2.4 __fpclassifyl F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist
> index a5ce9b1997939909e3239fe5b694246a410aeb56..edc26140dca7b309f9412d870cf6cca1771aeb98 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist
> @@ -891,6 +891,7 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
>  GLIBC_2.4 __clog10l F
>  GLIBC_2.4 __finitel F
>  GLIBC_2.4 __fpclassifyl F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libm.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libm.abilist
> index 8e41056d0d4a588b4f8346e4b8bab3742036cdd0..0a8a1433d765358734ea688c71b23d097a70b92c 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libm.abilist
> @@ -885,6 +885,7 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
>  GLIBC_2.4 __clog10l F
>  GLIBC_2.4 __finitel F
>  GLIBC_2.4 __fpclassifyl F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libm.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libm.abilist
> index 939f29a0f28023d1307bb7e84c62be8161bfdd71..5174d20032330b26d4f66ce8525a4ede9c1bd2dc 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libm.abilist
> @@ -1320,3 +1320,4 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
> diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist
> index 4baefb1217b27d42023c0f39cb5425fd5ac35ee6..5ff11fb54f26696433f9c0d577ae429aafc42878 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist
> @@ -1149,6 +1149,7 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
>  GLIBC_2.4 __clog10l F
>  GLIBC_2.4 __finitel F
>  GLIBC_2.4 __fpclassifyl F
> diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist
> index debb767575907b5ff5e1a335aaf06b0ee8b41d18..0e246c2c54f537ede4bdd1d8f23ce3f98da682f2 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist
> @@ -1149,6 +1149,7 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
>  GLIBC_2.4 __clog10l F
>  GLIBC_2.4 __finitel F
>  GLIBC_2.4 __fpclassifyl F
> diff --git a/sysdeps/unix/sysv/linux/sh/be/libm.abilist b/sysdeps/unix/sysv/linux/sh/be/libm.abilist
> index fb94386fffdc81329031c0f26545ea22ddb4cc8e..7b43a866e20c4f51f06fcf4bcd10ec1534bc1a8d 100644
> --- a/sysdeps/unix/sysv/linux/sh/be/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/sh/be/libm.abilist
> @@ -846,4 +846,5 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
>  GLIBC_2.4 exp2l F
> diff --git a/sysdeps/unix/sysv/linux/sh/le/libm.abilist b/sysdeps/unix/sysv/linux/sh/le/libm.abilist
> index fb94386fffdc81329031c0f26545ea22ddb4cc8e..7b43a866e20c4f51f06fcf4bcd10ec1534bc1a8d 100644
> --- a/sysdeps/unix/sysv/linux/sh/le/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/sh/le/libm.abilist
> @@ -846,4 +846,5 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
>  GLIBC_2.4 exp2l F
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist
> index 2fdb5ff14508606311e2a24595c5f46552bda578..e3dcf3d4e7ecf3f07ca67ebec75c5497e018c127 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist
> @@ -1156,6 +1156,7 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
>  GLIBC_2.4 __clog10l F
>  GLIBC_2.4 __finitel F
>  GLIBC_2.4 __fpclassifyl F
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist
> index 02d4c3a754862f8205267f6baf69a020df9dfa99..20fef20c8b5e04c756b2a3b7797830745632beab 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist
> @@ -1148,3 +1148,4 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
> diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libm.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libm.abilist
> index cc8be5b510d832d77d11b6e89e424492bc42dba1..c1c5c76e26189bee20892d6ea15a3d22ab22d834 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/64/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/64/libm.abilist
> @@ -1181,3 +1181,4 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
> diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist
> index fda4df265316c534102192201474b8b26c4e9a47..fac219d45ab2f03e16574d0d119bfce2c62795d8 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist
> @@ -1181,3 +1181,4 @@ GLIBC_2.35 hypot F
>  GLIBC_2.35 hypotf F
>  GLIBC_2.38 fmod F
>  GLIBC_2.38 fmodf F
> +GLIBC_2.39 exp10 F
> 
>
  
Wilco Dijkstra Jan. 16, 2024, 3:41 p.m. UTC | #7
Hi Adhemerval,

> The patch below fixes the numerical stability I found on i686:

So it looks like it is due to incorrect uses of math_narrow_eval with
double_t expressions: kd = math_narrow_eval (z + Shift);
This needs to be: kd = math_narrow_eval ((double) (z + Shift));

> And I think we haven't see it because all ABIs with FLT_EVAL_METHOD=2 uses
> assembly implementations for exp/exp2/exp10 (this is the case for i386
> and m68k).

Indeed.

> Furthermore, at least with i686 the use of double_t also does not show
> better performance either. The current sysdeps/i386/fpu/e_exp10.S
> on a recent CPU (Ryzen 9 5900X) with gcc version 13.2.1:

That's surprising. What happens is that we build with -std=gnu11 which implies
-fexcess-precision=fast. I double-checked on a SkyLake - using double_t is slower
as well. So overall it seems best to let the compiler decide where to use excess
precision.

> So I am not sure if double_t is really helpful here.

Unless we decide to move to -fexcess-precision=standard by default I guess -
but there doesn't seem to be an advantage in doing so given that double_t
is slower.

Cheers,
Wilco
  
Szabolcs Nagy Jan. 16, 2024, 4:08 p.m. UTC | #8
The 01/16/2024 15:41, Wilco Dijkstra wrote:
> Hi Adhemerval,
> 
> > The patch below fixes the numerical stability I found on i686:
> 
> So it looks like it is due to incorrect uses of math_narrow_eval with
> double_t expressions: kd = math_narrow_eval (z + Shift);
> This needs to be: kd = math_narrow_eval ((double) (z + Shift));
> 
> > And I think we haven't see it because all ABIs with FLT_EVAL_METHOD=2 uses
> > assembly implementations for exp/exp2/exp10 (this is the case for i386
> > and m68k).
> 
> Indeed.
> 
> > Furthermore, at least with i686 the use of double_t also does not show
> > better performance either. The current sysdeps/i386/fpu/e_exp10.S
> > on a recent CPU (Ryzen 9 5900X) with gcc version 13.2.1:
> 
> That's surprising. What happens is that we build with -std=gnu11 which implies
> -fexcess-precision=fast. I double-checked on a SkyLake - using double_t is slower
> as well. So overall it seems best to let the compiler decide where to use excess
> precision.
> 
> > So I am not sure if double_t is really helpful here.
> 
> Unless we decide to move to -fexcess-precision=standard by default I guess -
> but there doesn't seem to be an advantage in doing so given that double_t
> is slower.

the code was written with standard conformance in mind.
(i.e. it should have reliable semantics with any iso c
compiler.)

glibc does not build in standard confrom excess precision
mode, so i was using float_t and double_t to avoid changing
semantics depending on cflags. (the narrow eval issue was
an oversight that can be fixed with a cast.)

i did not expect double ops with non-standard excess
precision handling to have different performance than long
double ops on i386.

if that's the case then indeed using float/double directly
may be better than float_t/double_t (but keep in mind if
somebody builds the code outside the glibc tree to do
tests or other analysis the behaviour will be fragile on
targets like i386 and m68k. same if we ever want to change
the glibc build flags to iso c mode on those targets.)
  
Adhemerval Zanella Netto Jan. 16, 2024, 4:11 p.m. UTC | #9
On 16/01/24 13:08, Szabolcs Nagy wrote:
> The 01/16/2024 15:41, Wilco Dijkstra wrote:
>> Hi Adhemerval,
>>
>>> The patch below fixes the numerical stability I found on i686:
>>
>> So it looks like it is due to incorrect uses of math_narrow_eval with
>> double_t expressions: kd = math_narrow_eval (z + Shift);
>> This needs to be: kd = math_narrow_eval ((double) (z + Shift));
>>
>>> And I think we haven't see it because all ABIs with FLT_EVAL_METHOD=2 uses
>>> assembly implementations for exp/exp2/exp10 (this is the case for i386
>>> and m68k).
>>
>> Indeed.
>>
>>> Furthermore, at least with i686 the use of double_t also does not show
>>> better performance either. The current sysdeps/i386/fpu/e_exp10.S
>>> on a recent CPU (Ryzen 9 5900X) with gcc version 13.2.1:
>>
>> That's surprising. What happens is that we build with -std=gnu11 which implies
>> -fexcess-precision=fast. I double-checked on a SkyLake - using double_t is slower
>> as well. So overall it seems best to let the compiler decide where to use excess
>> precision.
>>
>>> So I am not sure if double_t is really helpful here.
>>
>> Unless we decide to move to -fexcess-precision=standard by default I guess -
>> but there doesn't seem to be an advantage in doing so given that double_t
>> is slower.
> 
> the code was written with standard conformance in mind.
> (i.e. it should have reliable semantics with any iso c
> compiler.)
> 
> glibc does not build in standard confrom excess precision
> mode, so i was using float_t and double_t to avoid changing
> semantics depending on cflags. (the narrow eval issue was
> an oversight that can be fixed with a cast.)
> 
> i did not expect double ops with non-standard excess
> precision handling to have different performance than long
> double ops on i386.
> 
> if that's the case then indeed using float/double directly
> may be better than float_t/double_t (but keep in mind if
> somebody builds the code outside the glibc tree to do
> tests or other analysis the behaviour will be fragile on
> targets like i386 and m68k. same if we ever want to change
> the glibc build flags to iso c mode on those targets.)

My plan is to send some fixes to allow remove some remaining assembly
implementations from i386.  I don't think it would worth to change
the current code besides the numerical stability I have found.
  
Wilco Dijkstra Jan. 18, 2024, 2:26 p.m. UTC | #10
Hi Adhemerval,

>> if that's the case then indeed using float/double directly
>> may be better than float_t/double_t (but keep in mind if
>> somebody builds the code outside the glibc tree to do
>> tests or other analysis the behaviour will be fragile on
>> targets like i386 and m68k. same if we ever want to change
>> the glibc build flags to iso c mode on those targets.)
>
> My plan is to send some fixes to allow remove some remaining assembly
> implementations from i386.  I don't think it would worth to change
> the current code besides the numerical stability I have found.

I agree doing the fixes first (eg. by adding a cast to double) is best.
Improving the macro to do this automatically may be an idea.

In my measurements on exp10, using double instead of double_t was
22% faster (due to fewer store-load sequences). With -fpmath=sse it
is 36% faster (LLVM does that by default). So given GCC prefers double
and LLVM uses faster SSE already, there doesn't appear to be any benefit
from supporting double_t.

Cheers,
Wilco
  
Szabolcs Nagy Jan. 18, 2024, 3:30 p.m. UTC | #11
The 01/18/2024 14:26, Wilco Dijkstra wrote:
> Hi Adhemerval,
> 
> >> if that's the case then indeed using float/double directly
> >> may be better than float_t/double_t (but keep in mind if
> >> somebody builds the code outside the glibc tree to do
> >> tests or other analysis the behaviour will be fragile on
> >> targets like i386 and m68k. same if we ever want to change
> >> the glibc build flags to iso c mode on those targets.)
> >
> > My plan is to send some fixes to allow remove some remaining assembly
> > implementations from i386.  I don't think it would worth to change
> > the current code besides the numerical stability I have found.
> 
> I agree doing the fixes first (eg. by adding a cast to double) is best.
> Improving the macro to do this automatically may be an idea.
> 
> In my measurements on exp10, using double instead of double_t was
> 22% faster (due to fewer store-load sequences). With -fpmath=sse it
> is 36% faster (LLVM does that by default). So given GCC prefers double
> and LLVM uses faster SSE already, there doesn't appear to be any benefit
> from supporting double_t.

the benefit is portability to standard conform modes.

my understanding is that 'fast' excess precision handling is
opportunistic, so the behaviour is different depending on where
the compiler decided to spill registers (and thus introduce an
intermediate rounding). this is not the end of the world (similar
to fma contraction) so for glibc it may be better to use double
and float exclusively. i guess we can do this by changing double_t
to xdouble_t in the code and typedef that to double.
(i would not change the code to use double, because that loses the
information about which variables may use excess precision.)
  

Patch

diff --git a/math/Versions b/math/Versions
index 759b5fac7f43739de9bf63fcb5d41fae071ee86b..26e15cedea26c1d6ed63da6f5fe60716089d135f 100644
--- a/math/Versions
+++ b/math/Versions
@@ -635,4 +635,8 @@  libm {
     # No SVID compatible error handling.
     fmod; fmodf;
   }
+  GLIBC_2.39 {
+    # No SVID compatible error handling.
+    exp10;
+  }
 }
diff --git a/math/w_exp10_compat.c b/math/w_exp10_compat.c
index b13592d29c934c58f4a55b9b03408e0a6a911cb5..3f717813fdbdcf2112bdd45f1e8d6000b495e904 100644
--- a/math/w_exp10_compat.c
+++ b/math/w_exp10_compat.c
@@ -25,9 +25,15 @@ 
 #include <math-svid-compat.h>
 #include <libm-alias-double.h>
 
-#if LIBM_SVID_COMPAT
+#ifndef NO_COMPAT_NEEDED
+# define NO_COMPAT_NEEDED 0
+#endif
+
+#if LIBM_SVID_COMPAT && (SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_39) \
+			 || defined NO_LONG_DOUBLE \
+			 || defined LONG_DOUBLE_COMPAT)
 double
-__exp10 (double x)
+__exp10_compat (double x)
 {
   double z = __ieee754_exp10 (x);
   if (__builtin_expect (!isfinite (z) || z == 0, 0)
@@ -37,14 +43,30 @@  __exp10 (double x)
 
   return z;
 }
-libm_alias_double (__exp10, exp10)
+# if NO_COMPAT_NEEDED
+#  ifdef SHARED
+libm_alias_double (__exp10_compat, exp10)
+#  endif
+#else
+#  if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_39)
+compat_symbol (libm, __exp10_compat, exp10, GLIBC_2_1);
+#  endif
+#  ifdef NO_LONG_DOUBLE
+weak_alias (__exp10_compat, exp10l)
+#  endif
+#  ifdef LONG_DOUBLE_COMPAT
+LONG_DOUBLE_COMPAT_CHOOSE_libm_exp10l (
+  compat_symbol (libm, __exp10_compat, exp10l, FIRST_VERSION_libm_exp10l), );
+#  endif
+# endif
+
 # if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_27)
-strong_alias (__exp10, __pow10)
+strong_alias (__exp10_compat, __pow10)
 compat_symbol (libm, __pow10, pow10, GLIBC_2_1);
 # endif
 # ifdef NO_LONG_DOUBLE
 #  if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_27)
-strong_alias (__exp10l, __pow10l)
+strong_alias (exp10l, __pow10l)
 compat_symbol (libm, __pow10l, pow10l, GLIBC_2_1);
 #  endif
 # endif
diff --git a/sysdeps/i386/fpu/w_exp10_compat.c b/sysdeps/i386/fpu/w_exp10_compat.c
new file mode 100644
index 0000000000000000000000000000000000000000..402356ae9977b54e39b4a068541122e46b05633b
--- /dev/null
+++ b/sysdeps/i386/fpu/w_exp10_compat.c
@@ -0,0 +1,3 @@ 
+/* i386 provides an optimized __ieee752_exp10.  */
+#define NO_COMPAT_NEEDED 1
+#include <math/w_exp10_compat.c>
diff --git a/sysdeps/ieee754/dbl-64/e_exp10.c b/sysdeps/ieee754/dbl-64/e_exp10.c
index 08069140c076d0b1c9c49454aaf6fe3740c80205..0fa9b11aae9355c115699df0b1e337b1d455c5e4 100644
--- a/sysdeps/ieee754/dbl-64/e_exp10.c
+++ b/sysdeps/ieee754/dbl-64/e_exp10.c
@@ -18,9 +18,9 @@ 
 #include <math.h>
 #include <math-barriers.h>
 #include <math-narrow-eval.h>
-#include <math_private.h>
-#include <float.h>
+#include <math-svid-compat.h>
 #include <libm-alias-finite.h>
+#include <libm-alias-double.h>
 #include "math_config.h"
 
 #define N (1 << EXP_TABLE_BITS)
@@ -75,7 +75,7 @@  special_case (uint64_t sbits, double_t tmp, uint64_t ki)
 
 /* Double-precision 10^x approximation. Largest observed error is ~0.513 ULP.  */
 double
-__ieee754_exp10 (double x)
+__exp10 (double x)
 {
   uint64_t ix = asuint64 (x);
   uint32_t abstop = (ix >> 52) & 0x7ff;
@@ -144,4 +144,11 @@  __ieee754_exp10 (double x)
   return s * y + s;
 }
 
+strong_alias (__exp10, __ieee754_exp10)
 libm_alias_finite (__ieee754_exp10, __exp10)
+#if LIBM_SVID_COMPAT
+versioned_symbol (libm, __exp10, exp10, GLIBC_2_39);
+libm_alias_double_other (__exp10, exp10)
+#else
+libm_alias_double (__exp10, exp10)
+#endif
diff --git a/sysdeps/ieee754/dbl-64/w_exp10.c b/sysdeps/ieee754/dbl-64/w_exp10.c
new file mode 100644
index 0000000000000000000000000000000000000000..1cc8931700702e65d29a6e2af287175d23c6b182
--- /dev/null
+++ b/sysdeps/ieee754/dbl-64/w_exp10.c
@@ -0,0 +1 @@ 
+/* Not needed.  */
diff --git a/sysdeps/m68k/m680x0/fpu/w_exp10_compat.c b/sysdeps/m68k/m680x0/fpu/w_exp10_compat.c
new file mode 100644
index 0000000000000000000000000000000000000000..07287923d74fb50698dec1ff7a51431b827aa004
--- /dev/null
+++ b/sysdeps/m68k/m680x0/fpu/w_exp10_compat.c
@@ -0,0 +1,3 @@ 
+/* m68k provides an optimized __ieee752_exp10.  */
+#define NO_COMPAT_NEEDED 1
+#include <math/w_exp10_compat.c>
diff --git a/sysdeps/unix/sysv/linux/aarch64/libm.abilist b/sysdeps/unix/sysv/linux/aarch64/libm.abilist
index e3924c3499d290fc96e4e6919bc8a26da8f7777c..f0da228fbba6e6fdb8f1fd24285478bdda333a16 100644
--- a/sysdeps/unix/sysv/linux/aarch64/libm.abilist
+++ b/sysdeps/unix/sysv/linux/aarch64/libm.abilist
@@ -1148,3 +1148,4 @@  GLIBC_2.35 hypot F
 GLIBC_2.35 hypotf F
 GLIBC_2.38 fmod F
 GLIBC_2.38 fmodf F
+GLIBC_2.39 exp10 F
diff --git a/sysdeps/unix/sysv/linux/alpha/libm.abilist b/sysdeps/unix/sysv/linux/alpha/libm.abilist
index 066dd1a6b371d060eea4196f83fd86d8dacdf614..f5d8023d624e9cb0ae24a088b6dd0e00c2a9d560 100644
--- a/sysdeps/unix/sysv/linux/alpha/libm.abilist
+++ b/sysdeps/unix/sysv/linux/alpha/libm.abilist
@@ -1205,6 +1205,7 @@  GLIBC_2.35 hypot F
 GLIBC_2.35 hypotf F
 GLIBC_2.38 fmod F
 GLIBC_2.38 fmodf F
+GLIBC_2.39 exp10 F
 GLIBC_2.4 __clog10l F
 GLIBC_2.4 __finitel F
 GLIBC_2.4 __fpclassifyl F
diff --git a/sysdeps/unix/sysv/linux/arm/be/libm.abilist b/sysdeps/unix/sysv/linux/arm/be/libm.abilist
index 4adfed072b0239d5508559c2442cf30cb064d7b7..f020a8a9043d4d211e2404b7dbb3095eeb792fd3 100644
--- a/sysdeps/unix/sysv/linux/arm/be/libm.abilist
+++ b/sysdeps/unix/sysv/linux/arm/be/libm.abilist
@@ -535,6 +535,7 @@  GLIBC_2.35 hypot F
 GLIBC_2.35 hypotf F
 GLIBC_2.38 fmod F
 GLIBC_2.38 fmodf F
+GLIBC_2.39 exp10 F
 GLIBC_2.4 _LIB_VERSION D 0x4
 GLIBC_2.4 __clog10 F
 GLIBC_2.4 __clog10f F
diff --git a/sysdeps/unix/sysv/linux/arm/le/libm.abilist b/sysdeps/unix/sysv/linux/arm/le/libm.abilist
index 4adfed072b0239d5508559c2442cf30cb064d7b7..f020a8a9043d4d211e2404b7dbb3095eeb792fd3 100644
--- a/sysdeps/unix/sysv/linux/arm/le/libm.abilist
+++ b/sysdeps/unix/sysv/linux/arm/le/libm.abilist
@@ -535,6 +535,7 @@  GLIBC_2.35 hypot F
 GLIBC_2.35 hypotf F
 GLIBC_2.38 fmod F
 GLIBC_2.38 fmodf F
+GLIBC_2.39 exp10 F
 GLIBC_2.4 _LIB_VERSION D 0x4
 GLIBC_2.4 __clog10 F
 GLIBC_2.4 __clog10f F
diff --git a/sysdeps/unix/sysv/linux/hppa/libm.abilist b/sysdeps/unix/sysv/linux/hppa/libm.abilist
index 5c3f47caefe8d89a95d0fbd3663c623eaefa5778..450ac03223c0258af2c5d23a031d54b24461cc24 100644
--- a/sysdeps/unix/sysv/linux/hppa/libm.abilist
+++ b/sysdeps/unix/sysv/linux/hppa/libm.abilist
@@ -846,4 +846,5 @@  GLIBC_2.35 hypot F
 GLIBC_2.35 hypotf F
 GLIBC_2.38 fmod F
 GLIBC_2.38 fmodf F
+GLIBC_2.39 exp10 F
 GLIBC_2.4 exp2l F
diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist
index 4adfed072b0239d5508559c2442cf30cb064d7b7..f020a8a9043d4d211e2404b7dbb3095eeb792fd3 100644
--- a/sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist
+++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist
@@ -535,6 +535,7 @@  GLIBC_2.35 hypot F
 GLIBC_2.35 hypotf F
 GLIBC_2.38 fmod F
 GLIBC_2.38 fmodf F
+GLIBC_2.39 exp10 F
 GLIBC_2.4 _LIB_VERSION D 0x4
 GLIBC_2.4 __clog10 F
 GLIBC_2.4 __clog10f F
diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libm.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libm.abilist
index ea0dbd4b727a618bc9598a27ea2dd4a2bd1b8a30..1f7f63f60cd7b9fbe1e1ef240afda3b3c3bd20c0 100644
--- a/sysdeps/unix/sysv/linux/microblaze/be/libm.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/be/libm.abilist
@@ -847,3 +847,4 @@  GLIBC_2.35 hypot F
 GLIBC_2.35 hypotf F
 GLIBC_2.38 fmod F
 GLIBC_2.38 fmodf F
+GLIBC_2.39 exp10 F
diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libm.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libm.abilist
index ea0dbd4b727a618bc9598a27ea2dd4a2bd1b8a30..1f7f63f60cd7b9fbe1e1ef240afda3b3c3bd20c0 100644
--- a/sysdeps/unix/sysv/linux/microblaze/le/libm.abilist
+++ b/sysdeps/unix/sysv/linux/microblaze/le/libm.abilist
@@ -847,3 +847,4 @@  GLIBC_2.35 hypot F
 GLIBC_2.35 hypotf F
 GLIBC_2.38 fmod F
 GLIBC_2.38 fmodf F
+GLIBC_2.39 exp10 F
diff --git a/sysdeps/unix/sysv/linux/mips/mips32/libm.abilist b/sysdeps/unix/sysv/linux/mips/mips32/libm.abilist
index 7c94a8db706e39147886da035e4a07fa12032bb7..797071aee8c56f9f8538bf5a50d44b164c5e26c4 100644
--- a/sysdeps/unix/sysv/linux/mips/mips32/libm.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips32/libm.abilist
@@ -846,4 +846,5 @@  GLIBC_2.35 hypot F
 GLIBC_2.35 hypotf F
 GLIBC_2.38 fmod F
 GLIBC_2.38 fmodf F
+GLIBC_2.39 exp10 F
 GLIBC_2.4 exp2l F
diff --git a/sysdeps/unix/sysv/linux/mips/mips64/libm.abilist b/sysdeps/unix/sysv/linux/mips/mips64/libm.abilist
index 0d08245adf0e1e652aa0a6eb4707509208bc582b..14758703cfb72749902907dec5cfa288116a76cf 100644
--- a/sysdeps/unix/sysv/linux/mips/mips64/libm.abilist
+++ b/sysdeps/unix/sysv/linux/mips/mips64/libm.abilist
@@ -1148,3 +1148,4 @@  GLIBC_2.35 hypot F
 GLIBC_2.35 hypotf F
 GLIBC_2.38 fmod F
 GLIBC_2.38 fmodf F
+GLIBC_2.39 exp10 F
diff --git a/sysdeps/unix/sysv/linux/nios2/libm.abilist b/sysdeps/unix/sysv/linux/nios2/libm.abilist
index a3b776fece3a4f5b50fb4c88500384027eea9e37..c0ebe119dc05aea86cbc48c3eff6c9b090069607 100644
--- a/sysdeps/unix/sysv/linux/nios2/libm.abilist
+++ b/sysdeps/unix/sysv/linux/nios2/libm.abilist
@@ -847,3 +847,4 @@  GLIBC_2.35 hypot F
 GLIBC_2.35 hypotf F
 GLIBC_2.38 fmod F
 GLIBC_2.38 fmodf F
+GLIBC_2.39 exp10 F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist
index c696215739f408f4b16008a76d1007fa80d52f5a..4f88e0af9ca9d30c9e9fe5172803464d400a25d0 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist
@@ -892,6 +892,7 @@  GLIBC_2.35 hypot F
 GLIBC_2.35 hypotf F
 GLIBC_2.38 fmod F
 GLIBC_2.38 fmodf F
+GLIBC_2.39 exp10 F
 GLIBC_2.4 __clog10l F
 GLIBC_2.4 __finitel F
 GLIBC_2.4 __fpclassifyl F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist
index a5ce9b1997939909e3239fe5b694246a410aeb56..edc26140dca7b309f9412d870cf6cca1771aeb98 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist
@@ -891,6 +891,7 @@  GLIBC_2.35 hypot F
 GLIBC_2.35 hypotf F
 GLIBC_2.38 fmod F
 GLIBC_2.38 fmodf F
+GLIBC_2.39 exp10 F
 GLIBC_2.4 __clog10l F
 GLIBC_2.4 __finitel F
 GLIBC_2.4 __fpclassifyl F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libm.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libm.abilist
index 8e41056d0d4a588b4f8346e4b8bab3742036cdd0..0a8a1433d765358734ea688c71b23d097a70b92c 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libm.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libm.abilist
@@ -885,6 +885,7 @@  GLIBC_2.35 hypot F
 GLIBC_2.35 hypotf F
 GLIBC_2.38 fmod F
 GLIBC_2.38 fmodf F
+GLIBC_2.39 exp10 F
 GLIBC_2.4 __clog10l F
 GLIBC_2.4 __finitel F
 GLIBC_2.4 __fpclassifyl F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libm.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libm.abilist
index 939f29a0f28023d1307bb7e84c62be8161bfdd71..5174d20032330b26d4f66ce8525a4ede9c1bd2dc 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libm.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libm.abilist
@@ -1320,3 +1320,4 @@  GLIBC_2.35 hypot F
 GLIBC_2.35 hypotf F
 GLIBC_2.38 fmod F
 GLIBC_2.38 fmodf F
+GLIBC_2.39 exp10 F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist
index 4baefb1217b27d42023c0f39cb5425fd5ac35ee6..5ff11fb54f26696433f9c0d577ae429aafc42878 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist
@@ -1149,6 +1149,7 @@  GLIBC_2.35 hypot F
 GLIBC_2.35 hypotf F
 GLIBC_2.38 fmod F
 GLIBC_2.38 fmodf F
+GLIBC_2.39 exp10 F
 GLIBC_2.4 __clog10l F
 GLIBC_2.4 __finitel F
 GLIBC_2.4 __fpclassifyl F
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist
index debb767575907b5ff5e1a335aaf06b0ee8b41d18..0e246c2c54f537ede4bdd1d8f23ce3f98da682f2 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist
@@ -1149,6 +1149,7 @@  GLIBC_2.35 hypot F
 GLIBC_2.35 hypotf F
 GLIBC_2.38 fmod F
 GLIBC_2.38 fmodf F
+GLIBC_2.39 exp10 F
 GLIBC_2.4 __clog10l F
 GLIBC_2.4 __finitel F
 GLIBC_2.4 __fpclassifyl F
diff --git a/sysdeps/unix/sysv/linux/sh/be/libm.abilist b/sysdeps/unix/sysv/linux/sh/be/libm.abilist
index fb94386fffdc81329031c0f26545ea22ddb4cc8e..7b43a866e20c4f51f06fcf4bcd10ec1534bc1a8d 100644
--- a/sysdeps/unix/sysv/linux/sh/be/libm.abilist
+++ b/sysdeps/unix/sysv/linux/sh/be/libm.abilist
@@ -846,4 +846,5 @@  GLIBC_2.35 hypot F
 GLIBC_2.35 hypotf F
 GLIBC_2.38 fmod F
 GLIBC_2.38 fmodf F
+GLIBC_2.39 exp10 F
 GLIBC_2.4 exp2l F
diff --git a/sysdeps/unix/sysv/linux/sh/le/libm.abilist b/sysdeps/unix/sysv/linux/sh/le/libm.abilist
index fb94386fffdc81329031c0f26545ea22ddb4cc8e..7b43a866e20c4f51f06fcf4bcd10ec1534bc1a8d 100644
--- a/sysdeps/unix/sysv/linux/sh/le/libm.abilist
+++ b/sysdeps/unix/sysv/linux/sh/le/libm.abilist
@@ -846,4 +846,5 @@  GLIBC_2.35 hypot F
 GLIBC_2.35 hypotf F
 GLIBC_2.38 fmod F
 GLIBC_2.38 fmodf F
+GLIBC_2.39 exp10 F
 GLIBC_2.4 exp2l F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist
index 2fdb5ff14508606311e2a24595c5f46552bda578..e3dcf3d4e7ecf3f07ca67ebec75c5497e018c127 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist
@@ -1156,6 +1156,7 @@  GLIBC_2.35 hypot F
 GLIBC_2.35 hypotf F
 GLIBC_2.38 fmod F
 GLIBC_2.38 fmodf F
+GLIBC_2.39 exp10 F
 GLIBC_2.4 __clog10l F
 GLIBC_2.4 __finitel F
 GLIBC_2.4 __fpclassifyl F
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist
index 02d4c3a754862f8205267f6baf69a020df9dfa99..20fef20c8b5e04c756b2a3b7797830745632beab 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist
@@ -1148,3 +1148,4 @@  GLIBC_2.35 hypot F
 GLIBC_2.35 hypotf F
 GLIBC_2.38 fmod F
 GLIBC_2.38 fmodf F
+GLIBC_2.39 exp10 F
diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libm.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libm.abilist
index cc8be5b510d832d77d11b6e89e424492bc42dba1..c1c5c76e26189bee20892d6ea15a3d22ab22d834 100644
--- a/sysdeps/unix/sysv/linux/x86_64/64/libm.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/64/libm.abilist
@@ -1181,3 +1181,4 @@  GLIBC_2.35 hypot F
 GLIBC_2.35 hypotf F
 GLIBC_2.38 fmod F
 GLIBC_2.38 fmodf F
+GLIBC_2.39 exp10 F
diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist
index fda4df265316c534102192201474b8b26c4e9a47..fac219d45ab2f03e16574d0d119bfce2c62795d8 100644
--- a/sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist
+++ b/sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist
@@ -1181,3 +1181,4 @@  GLIBC_2.35 hypot F
 GLIBC_2.35 hypotf F
 GLIBC_2.38 fmod F
 GLIBC_2.38 fmodf F
+GLIBC_2.39 exp10 F