This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH] math: support platforms with limited FP rounding or exceptionsupport
On 05/15/2012 06:30 PM, Chris Metcalf wrote:
For some tests, just claim that fetestexcept() always returns true,
so the rest of the test can be compiled.
For libm-test, provide known bogus values for unsupported rounding
modes, so fesetround() will return failure.
Elsewhere, just add some #ifdefs to avoid code that uses particular
FP exceptions if the exceptions aren't supported.
---
With this change (and a one-line ports change to provide a value
for __FE_UNDEFINED) I can generate the libm-test-ulps file for tile,
which I will check in after this is committed.
I deleted the tile ulps values for the fma tests, since they were crazily
bad; sounds like I need to wait for bug 13304 to be fixed for tile to
have working fma().
ChangeLog | 9 +++++++++
math/bug-nextafter.c | 6 ++++++
math/bug-nexttoward.c | 6 ++++++
math/libm-test.inc | 16 ++++++++++++++++
math/test-fenv.c | 6 ++++++
math/test-misc.c | 6 ++++++
stdlib/bug-getcontext.c | 4 ++++
7 files changed, 53 insertions(+), 0 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 3554d9e..6722060 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2012-05-15 Chris Metcalf<cmetcalf@tilera.com>
+
+ * math/libm-test.c: Support platforms without multiple rounding modes.
+ * math/bug-nextafter.c: Support platforms without FP exceptions.
+ * math/bug-nexttoward.c: Likewise.
+ * math/test-fenv.c: Likewise.
+ * math/test-misc.c: Likewise.
+ * stdlib/bug-getcontext.c: Likewise.
+
2012-05-14 Andreas Jaeger<aj@suse.de>
* sysdeps/unix/sysv/linux/getcwd.c (__getcwd): Remove unused
diff --git a/math/bug-nextafter.c b/math/bug-nextafter.c
index 1d21841..055335d 100644
--- a/math/bug-nextafter.c
+++ b/math/bug-nextafter.c
@@ -4,6 +4,12 @@
#include<stdlib.h>
#include<stdio.h>
+#if !defined(FE_OVERFLOW)&& !defined(FE_UNDERFLOW)
+/* If there's no support for the exceptions this test is checking,
+ then just return success and allow the test to be compiled. */
+#define fetestexcept(e) 1
Indent:
# define
+#endif
+
float zero = 0.0;
float inf = INFINITY;
diff --git a/math/bug-nexttoward.c b/math/bug-nexttoward.c
index ff57e5e..f21f8d6 100644
--- a/math/bug-nexttoward.c
+++ b/math/bug-nexttoward.c
@@ -4,6 +4,12 @@
#include<stdlib.h>
#include<stdio.h>
+#if !defined(FE_OVERFLOW)&& !defined(FE_UNDERFLOW)
+/* If there's no support for the exceptions this test is checking,
+ then just return success and allow the test to be compiled. */
+#define fetestexcept(e) 1
Use
# define
+#endif
+
float zero = 0.0;
float inf = INFINITY;
diff --git a/math/libm-test.inc b/math/libm-test.inc
index 5a38dbf..47bbd5f 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -128,6 +128,22 @@
#include<string.h>
#include<argp.h>
+/* Allow platforms without all rounding modes to test properly,
+ assuming they provide an __FE_UNDEFINED in<bits/fenv.h> which
+ causes fesetround() to return failure. */
+#ifndef FE_TONEAREST
+# define FE_TONEAREST __FE_UNDEFINED
+#endif
+#ifndef FE_TOWARDZERO
+# define FE_TOWARDZERO __FE_UNDEFINED
+#endif
+#ifndef FE_UPWARD
+# define FE_UPWARD __FE_UNDEFINED
+#endif
+#ifndef FE_DOWNWARD
+# define FE_DOWNWARD __FE_UNDEFINED
+#endif
+
/* Possible exceptions */
#define NO_EXCEPTION 0x0
#define INVALID_EXCEPTION 0x1
diff --git a/math/test-fenv.c b/math/test-fenv.c
index 39c7c33..19e5415 100644
--- a/math/test-fenv.c
+++ b/math/test-fenv.c
@@ -664,9 +664,11 @@ feholdexcept_tests (void)
}
#endif
test_exceptions ("feholdexcept_tests 0 test", NO_EXC, 0);
+#ifdef FE_INVALID
feraiseexcept (FE_INVALID);
test_exceptions ("feholdexcept_tests FE_INVALID test",
INVALID_EXC, 0);
+#endif
res = feupdateenv (&saved);
if (res != 0)
{
@@ -684,7 +686,9 @@ feholdexcept_tests (void)
test_exceptions ("feholdexcept_tests FE_DIVBYZERO|FE_INVALID test",
DIVBYZERO_EXC | INVALID_EXC, 0);
feclearexcept (FE_ALL_EXCEPT);
+#ifdef FE_INVALID
feraiseexcept (FE_INVALID);
+#endif
#if defined FE_TONEAREST&& defined FE_UPWARD
res = fesetround (FE_UPWARD);
if (res != 0)
@@ -708,9 +712,11 @@ feholdexcept_tests (void)
}
#endif
test_exceptions ("feholdexcept_tests 0 2nd test", NO_EXC, 0);
+#ifdef FE_INEXACT
feraiseexcept (FE_INEXACT);
test_exceptions ("feholdexcept_tests FE_INEXACT test",
INEXACT_EXC, 0);
+#endif
res = feupdateenv (&saved2);
if (res != 0)
{
diff --git a/math/test-misc.c b/math/test-misc.c
index c0fe5f7..5adb50b 100644
--- a/math/test-misc.c
+++ b/math/test-misc.c
@@ -1186,12 +1186,14 @@ main (void)
(void)&f2;
feclearexcept (FE_ALL_EXCEPT);
f2 += f1;
+#if defined(FE_OVERFLOW)&& defined(FE_INEXACT)
int fe = fetestexcept (FE_ALL_EXCEPT);
if (fe != (FE_OVERFLOW | FE_INEXACT))
{
printf ("float overflow test failed: %x\n", fe);
result = 1;
}
+#endif
volatile double d1 = DBL_MAX;
volatile double d2 = DBL_MAX / 2;
@@ -1199,12 +1201,14 @@ main (void)
(void)&d2;
feclearexcept (FE_ALL_EXCEPT);
d2 += d1;
+#if defined(FE_OVERFLOW)&& defined(FE_INEXACT)
fe = fetestexcept (FE_ALL_EXCEPT);
if (fe != (FE_OVERFLOW | FE_INEXACT))
{
printf ("double overflow test failed: %x\n", fe);
result = 1;
}
+#endif
#ifndef NO_LONG_DOUBLE
volatile long double ld1 = LDBL_MAX;
@@ -1213,6 +1217,7 @@ main (void)
(void)&ld2;
feclearexcept (FE_ALL_EXCEPT);
ld2 += ld1;
+#if defined(FE_OVERFLOW)&& defined(FE_INEXACT)
fe = fetestexcept (FE_ALL_EXCEPT);
if (fe != (FE_OVERFLOW | FE_INEXACT))
{
@@ -1220,6 +1225,7 @@ main (void)
result = 1;
}
#endif
Please intend the #endif above - together with the corresponding if.
We write nested #ifs like:
#if ....
# if
# else
# endif
#endif
+#endif
#if !defined NO_LONG_DOUBLE&& LDBL_MANT_DIG == 113
volatile long double ld3 = 0x1.0000000000010000000100000001p+1;
diff --git a/stdlib/bug-getcontext.c b/stdlib/bug-getcontext.c
index 745aa1f..7db49c8 100644
--- a/stdlib/bug-getcontext.c
+++ b/stdlib/bug-getcontext.c
@@ -9,6 +9,9 @@
static int
do_test (void)
{
+#if FE_ALL_EXCEPT == 0
+ printf("Skipping test; no support for FP exceptions.\n");
+#else
int except_mask = FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW;
int status = feenableexcept (except_mask);
@@ -41,6 +44,7 @@ do_test (void)
printf("\nAt end fegetexcept() returned %d, expected: %d.\n",
mask, except_mask);
+#endif
return 0;
}
This is ok after fixing the indenting issues I mentioned.
thanks,
Andreas
--
Andreas Jaeger aj@{suse.com,opensuse.org} Twitter/Identica: jaegerandi
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn,Jennifer Guild,Felix Imendörffer,HRB16746 (AG Nürnberg)
GPG fingerprint = 93A3 365E CE47 B889 DF7F FED1 389A 563C C272 A126