git: e38f2308273c - main - lib/msun: Fix tgammal(3) on IEEE 128-bit platforms

From: Mark Murray <markm_at_FreeBSD.org>
Date: Mon, 18 Mar 2024 09:53:48 UTC
The branch main has been updated by markm:

URL: https://cgit.FreeBSD.org/src/commit/?id=e38f2308273c8a51ec45f013d22c963590917cca

commit e38f2308273c8a51ec45f013d22c963590917cca
Author:     Mark Murray <markm@FreeBSD.org>
AuthorDate: 2024-03-01 15:53:58 +0000
Commit:     Mark Murray <markm@FreeBSD.org>
CommitDate: 2024-03-18 09:48:43 +0000

    lib/msun: Fix tgammal(3) on IEEE 128-bit platforms
    
    Undo the 80-bit "stub" implementation of the 128-bit long double
    tgammal(3) function. The latest (as of Feb 2024) version of the
    src/contrib/arm-optimised-routines library includes a standalone,
    full 128-bit replacement. This needs a small bit of wrapping to
    fit it in, but is otherwise a drop-in replacement.
    
    Testing this is hard, as most maths packages blow up as soon as
    their 80-bit floating-point capability is exceeded. With 128-bit
    tgammal(), this is easy to do, and this is the range that needs to
    be checked the most carefully. Using my copy of Maple, I was able
    to check that the output was within a few ULP of the correct answer,
    right up to the point of 128-bit over- and underflow. Additionally,
    the results are no worse, and indeed better than the 80-bit version.
    
    Steve Kargl sent me his libm testing code, which I used to verify
    that the excpetions for certain key values were correct. Tested in
    this case were +-Inf, +-NaN, +-1 and +-0.
    
    Differential Revision:  https://reviews.freebsd.org/D44168
    Reviewed by:    theraven, andrew, imp
---
 lib/msun/Makefile          |  2 +-
 lib/msun/ld128/b_tgammal.c | 53 +++++-----------------------------------------
 lib/msun/man/lgamma.3      | 19 ++++++++---------
 3 files changed, 15 insertions(+), 59 deletions(-)

diff --git a/lib/msun/Makefile b/lib/msun/Makefile
index 6c8c6c3e8009..24989749a502 100644
--- a/lib/msun/Makefile
+++ b/lib/msun/Makefile
@@ -26,7 +26,7 @@ CFLAGS+=	-I${.CURDIR}/x86
 CFLAGS+=	-I${.CURDIR}/ld80
 .elif ${LDBL_PREC} == 113
 .PATH:  ${.CURDIR}/ld128
-CFLAGS+=	-I${.CURDIR}/ld128
+CFLAGS+=	-I${.CURDIR}/ld128 -I${SRCTOP}/contrib/arm-optimized-routines/math
 .endif
 
 CFLAGS+=	-I${.CURDIR}/${ARCH_SUBDIR}
diff --git a/lib/msun/ld128/b_tgammal.c b/lib/msun/ld128/b_tgammal.c
index 4bae4f3aded6..6df7264a4c9e 100644
--- a/lib/msun/ld128/b_tgammal.c
+++ b/lib/msun/ld128/b_tgammal.c
@@ -1,55 +1,12 @@
 /*-
  * SPDX-License-Identifier: BSD-2-Clause
  *
- * Copyright (c) 2013 David Chisnall
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
+ * Copyright (c) 2024 The FreeBSD Foundation
  */
 
-#include <float.h>
-#include <math.h>
-
 /*
- * If long double is not the same size as double, then these will lose
- * precision and we should emit a warning whenever something links against
- * them.
+ * This is a pure C function generously donated by ARM.
+ * See src/contrib/arm-optimized-routines/math/tgamma128.[ch].
  */
-#if (LDBL_MANT_DIG > 53)
-#define WARN_IMPRECISE(x) \
-	__warn_references(x, # x " has lower than advertised precision");
-#else
-#define WARN_IMPRECISE(x)
-#endif
-/*
- * Declare the functions as weak variants so that other libraries providing
- * real versions can override them.
- */
-#define	DECLARE_WEAK(x)\
-	__weak_reference(imprecise_## x, x);\
-	WARN_IMPRECISE(x)
-
-#define DECLARE_IMPRECISE(f) \
-	long double imprecise_ ## f ## l(long double v) { return f(v); }\
-	DECLARE_WEAK(f ## l)
-
-DECLARE_IMPRECISE(tgamma);
+#define tgamma128 tgammal
+#include "tgamma128.c"
diff --git a/lib/msun/man/lgamma.3 b/lib/msun/man/lgamma.3
index 8c0298ec8299..a77d524373fb 100644
--- a/lib/msun/man/lgamma.3
+++ b/lib/msun/man/lgamma.3
@@ -25,7 +25,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd December 8, 2017
+.Dd March 1, 2024
 .Dt LGAMMA 3
 .Os
 .Sh NAME
@@ -167,15 +167,6 @@ non-positive integers.
 For large non-integer negative values,
 .Fn tgamma
 will underflow.
-.Sh BUGS
-To conform with newer C/C++ standards, a stub implementation for
-.Nm tgammal
-was committed to the math library, where
-.Nm tgammal
-is mapped to
-.Nm tgamma .
-Thus, the numerical accuracy is at most that of the 53-bit double
-precision implementation.
 .Sh SEE ALSO
 .Xr math 3
 .Sh STANDARDS
@@ -212,3 +203,11 @@ The
 .Fn tgamma
 function appeared in
 .Fx 5.0 .
+The 128-bit
+.Ft long double
+version of
+.Fn tgammal
+replaced the 80-bit stub version in
+version in
+.Fx 16 ,
+thanks to an appropriate implementation from Arm.