Date: Sun, 27 Dec 2015 21:15:58 +0000 (UTC) From: Garrett Cooper <ngie@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r292800 - stable/9/tools/regression/lib/msun Message-ID: <201512272115.tBRLFwJs098775@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: ngie Date: Sun Dec 27 21:15:58 2015 New Revision: 292800 URL: https://svnweb.freebsd.org/changeset/base/292800 Log: MFstable/10 r226377,r292799: r226377 (by das): Add some tests for double-rounding bugs in fma(). r292799: MFC r292492,r292495,r292647: r292492: - Use nitems instead of handrolling the macro - Use a separate variable for tracking the testcase count instead of hardcoding the offset for the testcases Sponsored by: EMC / Isilon Storage Division r292495: Initialize j so it doesn't print out a garbage index Use it consistently instead of i in the first loop Sponsored by: EMC / Isilon Storage Division r292647: Use j instead of a hardcoded index (9) and increment it after running the NaNs testcases Pointyhat to: ngie Sponsored by: EMC / Isilon Storage Division Modified: stable/9/tools/regression/lib/msun/test-fma.c Directory Properties: stable/9/ (props changed) stable/9/tools/ (props changed) stable/9/tools/regression/ (props changed) Modified: stable/9/tools/regression/lib/msun/test-fma.c ============================================================================== --- stable/9/tools/regression/lib/msun/test-fma.c Sun Dec 27 21:08:46 2015 (r292799) +++ stable/9/tools/regression/lib/msun/test-fma.c Sun Dec 27 21:15:58 2015 (r292800) @@ -31,6 +31,7 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#include <sys/param.h> #include <assert.h> #include <fenv.h> #include <float.h> @@ -364,45 +365,107 @@ test_accuracy(void) #endif } +static void +test_double_rounding(void) +{ + + /* + * a = 0x1.8000000000001p0 + * b = 0x1.8000000000001p0 + * c = -0x0.0000000000000000000000000080...1p+1 + * a * b = 0x1.2000000000001800000000000080p+1 + * + * The correct behavior is to round DOWN to 0x1.2000000000001p+1 in + * round-to-nearest mode. An implementation that computes a*b+c in + * double+double precision, however, will get 0x1.20000000000018p+1, + * and then round UP. + */ + fesetround(FE_TONEAREST); + test(fma, 0x1.8000000000001p0, 0x1.8000000000001p0, + -0x1.0000000000001p-104, 0x1.2000000000001p+1, + ALL_STD_EXCEPT, FE_INEXACT); + fesetround(FE_DOWNWARD); + test(fma, 0x1.8000000000001p0, 0x1.8000000000001p0, + -0x1.0000000000001p-104, 0x1.2000000000001p+1, + ALL_STD_EXCEPT, FE_INEXACT); + fesetround(FE_UPWARD); + test(fma, 0x1.8000000000001p0, 0x1.8000000000001p0, + -0x1.0000000000001p-104, 0x1.2000000000002p+1, + ALL_STD_EXCEPT, FE_INEXACT); + + fesetround(FE_TONEAREST); + test(fmaf, 0x1.800002p+0, 0x1.800002p+0, -0x1.000002p-46, 0x1.200002p+1, + ALL_STD_EXCEPT, FE_INEXACT); + fesetround(FE_DOWNWARD); + test(fmaf, 0x1.800002p+0, 0x1.800002p+0, -0x1.000002p-46, 0x1.200002p+1, + ALL_STD_EXCEPT, FE_INEXACT); + fesetround(FE_UPWARD); + test(fmaf, 0x1.800002p+0, 0x1.800002p+0, -0x1.000002p-46, 0x1.200004p+1, + ALL_STD_EXCEPT, FE_INEXACT); + + fesetround(FE_TONEAREST); +#if LDBL_MANT_DIG == 64 + test(fmal, 0x1.4p+0L, 0x1.0000000000000004p+0L, 0x1p-128L, + 0x1.4000000000000006p+0L, ALL_STD_EXCEPT, FE_INEXACT); +#elif LDBL_MANT_DIG == 113 + /* XXX untested test */ + test(fmal, 0x1.4p+0L, 0x1.0000000000000000000000000002p+0L, 0x1p-224L, + 0x1.4000000000000000000000000003p+0L, ALL_STD_EXCEPT, FE_INEXACT); +#endif + +} + int main(int argc, char *argv[]) { int rmodes[] = { FE_TONEAREST, FE_UPWARD, FE_DOWNWARD, FE_TOWARDZERO }; - int i; + int i, j; - printf("1..18\n"); + j = 1; - for (i = 0; i < 4; i++) { + printf("1..19\n"); + + for (i = 0; i < nitems(rmodes); i++, j++) { + printf("rmode = %d\n", rmodes[i]); fesetround(rmodes[i]); test_zeroes(); - printf("ok %d - fma zeroes\n", i + 1); + printf("ok %d - fma zeroes\n", j); } - for (i = 0; i < 4; i++) { + for (i = 0; i < nitems(rmodes); i++, j++) { + printf("rmode = %d\n", rmodes[i]); fesetround(rmodes[i]); test_infinities(); - printf("ok %d - fma infinities\n", i + 5); + printf("ok %d - fma infinities\n", j); } fesetround(FE_TONEAREST); test_nans(); - printf("ok 9 - fma NaNs\n"); + printf("ok %d - fma NaNs\n", j); + j++; - for (i = 0; i < 4; i++) { + for (i = 0; i < nitems(rmodes); i++, j++) { + printf("rmode = %d\n", rmodes[i]); fesetround(rmodes[i]); test_small_z(); - printf("ok %d - fma small z\n", i + 10); + printf("ok %d - fma small z\n", j); } - for (i = 0; i < 4; i++) { + for (i = 0; i < nitems(rmodes); i++, j++) { + printf("rmode = %d\n", rmodes[i]); fesetround(rmodes[i]); test_big_z(); - printf("ok %d - fma big z\n", i + 14); + printf("ok %d - fma big z\n", j); } fesetround(FE_TONEAREST); test_accuracy(); - printf("ok 18 - fma accuracy\n"); + printf("ok %d - fma accuracy\n", j); + j++; + + test_double_rounding(); + printf("ok %d - fma double rounding\n", j); + j++; /* * TODO:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201512272115.tBRLFwJs098775>