svn commit: r292800 - stable/9/tools/regression/lib/msun
Garrett Cooper
ngie at FreeBSD.org
Sun Dec 27 21:16:00 UTC 2015
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:
More information about the svn-src-stable-9
mailing list