[PATCH 0/4] math: Fix inaccurate sin/cos/tan for large arguments (BZ 34376)

Adhemerval Zanella adhemerval.zanella@linaro.org
Thu Jul 16 21:21:16 GMT 2026


For arguments extremely close to a multiple of pi/2, the Payne-Hanek
range reducer __branred delivers the reduced argument with insufficient
precision (about 93 significant bits, while the reduced argument can be
as small as 2^-61), making sin/cos/tan wrong by up to ~143000 ulp.
This is a regression from commit 649095838b8 ("sin/cos slow paths:
remove slow paths from huge range reduction") and commit 476d692e8a8
("math: Remove slow paths in tan [BZ #15267]"), which removed the
multiple-precision fallbacks that used to hide the inaccuracy.

The fix restores the fdlibm e_rem_pio2.c (removed as unused by commit
ca3aac57efa), trimmed to its huge-argument path since the callers
reduce smaller arguments themselves, and uses __ieee754_rem_pio2,
whose kernel computes the reduction to full precision, instead of
__branred.

The first three patches restructure the sin/cos/tan benchmark inputs
into path-oriented workloads (fast/moderate/slow) so the impact on the
huge-argument path can be measured.  Results on x86_64-v3 (minimum of
5 runs, in cycles, lower is better):

                        master             fixed
                    rthruput latency  rthruput latency   rthruput
  sin workload-slow  211.66   222.24   318.99   351.20    +51%
  cos workload-slow  217.03   226.98   319.43   350.14    +47%
  tan workload-slow  241.18   248.52   346.93   368.89    +44%

The fast and moderate workloads are unchanged (within noise).  The
slowdown is confined to the huge-argument path (|x| > 1e8), which now
produces correctly reduced results.

Adhemerval Zanella (4):
  benchtests: Add path-oriented workloads to cos
  benchtests: Add path-oriented workloads to sin
  benchtests: Add path-oriented workloads to tan
  math: Fix inaccurate sin/cos/tan for large arguments (BZ 34376)

 benchtests/cos-inputs                | 5411 ++++++++++--------
 benchtests/sin-inputs                | 7917 ++++++++++----------------
 benchtests/tan-inputs                | 5450 +++++++-----------
 math/Makefile                        |    2 +-
 math/auto-libm-test-in               |   17 +
 math/auto-libm-test-out-cos          |  252 +
 math/auto-libm-test-out-sin          |  228 +
 math/auto-libm-test-out-tan          |  183 +
 sysdeps/generic/math_private.h       |    1 -
 sysdeps/ieee754/dbl-64/Makefile      |    2 -
 sysdeps/ieee754/dbl-64/branred.c     |  143 -
 sysdeps/ieee754/dbl-64/branred.h     |   79 -
 sysdeps/ieee754/dbl-64/e_rem_pio2.c  |   76 +
 sysdeps/ieee754/dbl-64/s_sin.c       |   14 +-
 sysdeps/ieee754/dbl-64/s_sincos.c    |   10 +-
 sysdeps/ieee754/dbl-64/s_tan.c       |   11 +-
 sysdeps/m68k/m680x0/fpu/e_rem_pio2.c |    1 +
 sysdeps/x86_64/fpu/Makefile          |   12 -
 18 files changed, 8796 insertions(+), 11013 deletions(-)
 delete mode 100644 sysdeps/ieee754/dbl-64/branred.c
 delete mode 100644 sysdeps/ieee754/dbl-64/branred.h
 create mode 100644 sysdeps/ieee754/dbl-64/e_rem_pio2.c
 create mode 100644 sysdeps/m68k/m680x0/fpu/e_rem_pio2.c

-- 
2.43.0



More information about the Libc-alpha mailing list