Module Name: src Committed By: martin Date: Wed Oct 2 12:46:13 UTC 2024
Modified Files: src/distrib/sets/lists/debug [netbsd-10]: mi src/distrib/sets/lists/tests [netbsd-10]: mi src/lib/libm/src [netbsd-10]: s_remquo.c src/tests/lib/libm [netbsd-10]: Makefile Added Files: src/tests/lib/libm [netbsd-10]: t_remquo.c Log Message: Pull up following revision(s) (requested by gdt in ticket #912): distrib/sets/lists/debug/mi: revision 1.449 lib/libm/src/s_remquo.c: revision 1.3 lib/libm/src/s_remquo.c: revision 1.4 distrib/sets/lists/tests/mi: revision 1.1339 tests/lib/libm/t_remquo.c: revision 1.1 tests/lib/libm/t_remquo.c: revision 1.2 tests/lib/libm/Makefile: revision 1.51 tests: Add test for remquo This test currently fails, because remquo has bugs. (A bugfix will be committed soon.) Test vectors derived from results from code by Charles Karney in GeodesicLib/proj, and manually inspected. t_remquo: Work around missing remquo(3) for vax Part of PR port-vax/57881 libm/remquo: Fix bug where wrong quotient was returned Fix taken from FreeBSD: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=166463 https://cgit.freebsd.org/src/commit/lib/msun/src/s_remquo.c?id=1cbd288942b08217e99bf889e0967895d53af00c FreeBSD commit message: Fix a bug in remquo{,f,l}, in which the quotient didn't always have the correct sign when the remainder was 0. Fix a separate bug in remquo alone, in which the remainder and quotient were both off by a bit in certain cases involving subnormal remainders. The bugs affected all platforms except amd64 and i386, on which the routines are implemented in assembly. (On NetBSD, this bug manifests on amd64.) libm/remquo: Fix bug where remquo returned wrong sign of quo ISO C requires that quo be congruent to the quotient mod 2^k and have a particular sign. The current code can return 0 when it should be negative. Because the code chooses k=31 (for the requirement of congruence modulo 2^k), the only value available (in ILP32 or LP64) that is negative and congruent to 0 is 0x80000000. In the specific case of wanting "-0", return 0x80000000. Resolves t_remquo test failure. To generate a diff of this commit: cvs rdiff -u -r1.394.2.9 -r1.394.2.10 src/distrib/sets/lists/debug/mi cvs rdiff -u -r1.1238.2.11 -r1.1238.2.12 src/distrib/sets/lists/tests/mi cvs rdiff -u -r1.1 -r1.1.56.1 src/lib/libm/src/s_remquo.c cvs rdiff -u -r1.48 -r1.48.2.1 src/tests/lib/libm/Makefile cvs rdiff -u -r0 -r1.2.2.2 src/tests/lib/libm/t_remquo.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/distrib/sets/lists/debug/mi diff -u src/distrib/sets/lists/debug/mi:1.394.2.9 src/distrib/sets/lists/debug/mi:1.394.2.10 --- src/distrib/sets/lists/debug/mi:1.394.2.9 Thu Sep 5 09:22:43 2024 +++ src/distrib/sets/lists/debug/mi Wed Oct 2 12:46:13 2024 @@ -1,4 +1,4 @@ -# $NetBSD: mi,v 1.394.2.9 2024/09/05 09:22:43 martin Exp $ +# $NetBSD: mi,v 1.394.2.10 2024/10/02 12:46:13 martin Exp $ ./etc/mtree/set.debug comp-sys-root ./usr/lib comp-sys-usr compatdir ./usr/lib/i18n/libBIG5_g.a comp-c-debuglib debuglib,compatfile @@ -2319,6 +2319,7 @@ ./usr/libdata/debug/usr/tests/lib/libm/t_modf.debug tests-lib-debug debug,atf,compattestfile ./usr/libdata/debug/usr/tests/lib/libm/t_pow.debug tests-lib-debug debug,atf,compattestfile ./usr/libdata/debug/usr/tests/lib/libm/t_precision.debug tests-lib-debug debug,atf,compattestfile +./usr/libdata/debug/usr/tests/lib/libm/t_remquo.debug tests-lib-debug debug,atf,compattestfile ./usr/libdata/debug/usr/tests/lib/libm/t_round.debug tests-lib-debug debug,atf,compattestfile ./usr/libdata/debug/usr/tests/lib/libm/t_scalbn.debug tests-lib-debug debug,atf,compattestfile ./usr/libdata/debug/usr/tests/lib/libm/t_sin.debug tests-lib-debug debug,atf,compattestfile Index: src/distrib/sets/lists/tests/mi diff -u src/distrib/sets/lists/tests/mi:1.1238.2.11 src/distrib/sets/lists/tests/mi:1.1238.2.12 --- src/distrib/sets/lists/tests/mi:1.1238.2.11 Thu Sep 5 09:27:13 2024 +++ src/distrib/sets/lists/tests/mi Wed Oct 2 12:46:13 2024 @@ -1,4 +1,4 @@ -# $NetBSD: mi,v 1.1238.2.11 2024/09/05 09:27:13 martin Exp $ +# $NetBSD: mi,v 1.1238.2.12 2024/10/02 12:46:13 martin Exp $ # # Note: don't delete entries from here - mark them as "obsolete" instead. # @@ -3927,6 +3927,7 @@ ./usr/tests/lib/libm/t_modf tests-lib-tests compattestfile,atf ./usr/tests/lib/libm/t_pow tests-lib-tests compattestfile,atf ./usr/tests/lib/libm/t_precision tests-lib-tests compattestfile,atf +./usr/tests/lib/libm/t_remquo tests-lib-tests compattestfile,atf ./usr/tests/lib/libm/t_round tests-lib-tests compattestfile,atf ./usr/tests/lib/libm/t_scalbn tests-lib-tests compattestfile,atf ./usr/tests/lib/libm/t_sin tests-lib-tests compattestfile,atf Index: src/lib/libm/src/s_remquo.c diff -u src/lib/libm/src/s_remquo.c:1.1 src/lib/libm/src/s_remquo.c:1.1.56.1 --- src/lib/libm/src/s_remquo.c:1.1 Sun Feb 6 01:53:38 2011 +++ src/lib/libm/src/s_remquo.c Wed Oct 2 12:46:13 2024 @@ -50,7 +50,7 @@ remquo(double x, double y, int *quo) goto fixup; /* |x|<|y| return x or x-y */ } if(lx==ly) { - *quo = 1; + *quo = (sxy ? -1 : 1); return Zero[(u_int32_t)sx>>31]; /* |x|=|y| return x*0*/ } } @@ -113,6 +113,7 @@ remquo(double x, double y, int *quo) /* convert back to floating value and restore the sign */ if((hx|lx)==0) { /* return sign(x)*0 */ + q &= 0x7fffffff; *quo = (sxy ? -q : q); return Zero[(u_int32_t)sx>>31]; } @@ -128,9 +129,9 @@ remquo(double x, double y, int *quo) lx = (lx>>n)|((u_int32_t)hx<<(32-n)); hx >>= n; } else if (n<=31) { - lx = (hx<<(32-n))|(lx>>n); hx = sx; + lx = (hx<<(32-n))|(lx>>n); hx = 0; } else { - lx = hx>>(n-32); hx = sx; + lx = hx>>(n-32); hx = 0; } } fixup: @@ -149,5 +150,12 @@ fixup: SET_HIGH_WORD(x,hx^sx); q &= 0x7fffffff; *quo = (sxy ? -q : q); + /* + * If q is 0 and we need to return negative, we have to choose + * the largest negative number (in 32 bits) because it is the + * only value that is negative and congruent to 0 mod 2^31. + */ + if (q == 0 && sxy) + *quo = 0x80000000; return x; } Index: src/tests/lib/libm/Makefile diff -u src/tests/lib/libm/Makefile:1.48 src/tests/lib/libm/Makefile:1.48.2.1 --- src/tests/lib/libm/Makefile:1.48 Sat Aug 27 08:31:58 2022 +++ src/tests/lib/libm/Makefile Wed Oct 2 12:46:13 2024 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.48 2022/08/27 08:31:58 christos Exp $ +# $NetBSD: Makefile,v 1.48.2.1 2024/10/02 12:46:13 martin Exp $ .include <bsd.own.mk> @@ -37,6 +37,7 @@ TESTS_C+= t_log TESTS_C+= t_modf TESTS_C+= t_pow TESTS_C+= t_precision +TESTS_C+= t_remquo TESTS_C+= t_round TESTS_C+= t_scalbn TESTS_C+= t_sin Added files: Index: src/tests/lib/libm/t_remquo.c diff -u /dev/null src/tests/lib/libm/t_remquo.c:1.2.2.2 --- /dev/null Wed Oct 2 12:46:13 2024 +++ src/tests/lib/libm/t_remquo.c Wed Oct 2 12:46:13 2024 @@ -0,0 +1,126 @@ +/* $NetBSD: t_remquo.c,v 1.2.2.2 2024/10/02 12:46:13 martin Exp $ */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jukka Ruohonen and Greg Troxel. + * + * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +#include <assert.h> +#include <atf-c.h> +#include <float.h> +#include <math.h> + +/* + * remquo(3) + */ +ATF_TC(remquo_args); +ATF_TC_HEAD(remquo_args, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test some selected arguments"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, remquo_args); + + return atf_no_error(); +} + +#ifdef __vax__ + +ATF_TC_BODY(remquo_args, tc) +{ + atf_tc_expect_fail("PR 57881: vax libm is missing various symbols"); + atf_tc_fail("missing remquo on vax"); +} + +#else /* !__vax__ */ + +static const struct { + double x; + double y; + double r; /* expected */ + int quo; /* expected */ +} args[] = { + { -135.0, -90.0, 45.0, 2 }, + { -45.0, -90.0, -45.0, 8 }, + { 45.0, -90.0, 45.0, -8 }, + { 135.0, -90.0, -45.0, -2 }, + { -180.0, 90.0, -0.0, -2 }, + { -135.0, 90.0, 45.0, -2 }, + { -90.0, 90.0, -0.0, -1 }, + { -45.0, 90.0, -45.0, -8 }, + { 0.0, 90.0, 0.0, 0 }, + { 45.0, 90.0, 45.0, 8 }, + { 90.0, 90.0, 0.0, 1 }, + { 135.0, 90.0, -45.0, 2 }, + { 180.0, 90.0, 0.0, 2 }, +}; + +ATF_TC_BODY(remquo_args, tc) +{ + const double eps = DBL_EPSILON; + size_t i; + + for (i = 0; i < __arraycount(args); i++) { + double x = args[i].x; + double y = args[i].y; + double r; + double r_exp = args[i].r; + int quo; + int quo_exp = args[i].quo; + + bool ok = true; + + r = remquo(x, y, &quo); + + ok &= (fabs(r - r_exp) <= eps); + + /* + * For now, consider 0 to have positive sign. + */ + if (quo_exp < 0 && quo >= 0) + ok = false; + if (quo_exp >= 0 && quo < 0) + ok = false; + + /* + * The specification requires that quo be congruent to + * the integer remainder modulo 2^k for some k >=3. + */ + ok &= ((quo & 0x7) == (quo_exp & 0x7)); + + if (!ok) { + atf_tc_fail_nonfatal("remquo(%g, %g) " + "r/quo expected %g/%d != %g/%d", + x, y, r_exp, quo_exp, r, quo); + } + } +} + +#endif /* !__vax__ */