From 53b3704180fc57bcf73b933ffa45028a33dab58b Mon Sep 17 00:00:00 2001 From: David Monniaux Date: Fri, 12 Apr 2019 22:05:51 +0200 Subject: test breaks --- test/monniaux/math/test_gsl_pow.c | 44 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 test/monniaux/math/test_gsl_pow.c (limited to 'test/monniaux/math') diff --git a/test/monniaux/math/test_gsl_pow.c b/test/monniaux/math/test_gsl_pow.c new file mode 100644 index 00000000..54e53889 --- /dev/null +++ b/test/monniaux/math/test_gsl_pow.c @@ -0,0 +1,44 @@ +#include +#include + +double gsl_pow_uint(double x, unsigned int n); + +double gsl_pow_int(double x, int n) +{ + unsigned int un; + + if(n < 0) { + x = 1.0/x; + un = -n; + } else { + un = n; + } + + return gsl_pow_uint(x, un); +} + +double gsl_pow_uint(double x, unsigned int n) +{ + double value = 1.0; + + /* repeated squaring method + * returns 0.0^0 = 1.0, so continuous in x + */ + do { + if(n & 1) value *= x; /* for n odd */ + n >>= 1; + x *= x; + } while (n); + + return value; +} + +int main() { + double y, y_expected; + for (int n = -9; n < 10; n++) { + y = gsl_pow_int (-3.14, n); + y_expected = pow (-3.14, n); + printf("%d %g %g\n", n, y, y_expected); + } + return 0; +} -- cgit From 814090921e6c3b6a61b9328f01d7bad475bdeaf6 Mon Sep 17 00:00:00 2001 From: David Monniaux Date: Sat, 13 Apr 2019 18:46:24 +0200 Subject: test for rounding modes --- test/monniaux/math/rounding.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 test/monniaux/math/rounding.c (limited to 'test/monniaux/math') diff --git a/test/monniaux/math/rounding.c b/test/monniaux/math/rounding.c new file mode 100644 index 00000000..4831c3d1 --- /dev/null +++ b/test/monniaux/math/rounding.c @@ -0,0 +1,20 @@ +#include +#include + +#pragma STDC FENV_ACCESS ON + +double inverse(double x) { + return 1.0 / x; +} + +int main() { + if (fesetround(FE_DOWNWARD)) { + printf("fesetround(FE_DOWNWARD) unsuccessful\n"); + } + double low = inverse(3.0); + if (fesetround(FE_UPWARD)) { + printf("fesetround(FE_UPWARD) unsuccessful\n"); + } + double high = inverse(3.0); + printf("%d %a\n", low==high, high-low); +} -- cgit From b19288248802ec3f3e1adbf734655068c5559052 Mon Sep 17 00:00:00 2001 From: David Monniaux Date: Sat, 13 Apr 2019 19:06:37 +0200 Subject: experiments with rounding modes --- test/monniaux/math/rounding.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) (limited to 'test/monniaux/math') diff --git a/test/monniaux/math/rounding.c b/test/monniaux/math/rounding.c index 4831c3d1..c2ce85e3 100644 --- a/test/monniaux/math/rounding.c +++ b/test/monniaux/math/rounding.c @@ -1,20 +1,36 @@ #include #include +#ifdef __K1C__ +#include +int fesetround(int rounding_mode) { + if (rounding_mode < 0 || rounding_mode > 3) return 1; + unsigned long long cs = __builtin_k1_get(K1_SFR_CS); + cs = (cs & ~(3 << 16)) | (rounding_mode << 16); + __builtin_k1_set(K1_SFR_CS, cs); + return 0; +} + +int fegetround(void) { + unsigned long long cs = __builtin_k1_get(K1_SFR_CS); + return (cs >> 16) & 3; +} +#endif + #pragma STDC FENV_ACCESS ON -double inverse(double x) { - return 1.0 / x; +double add(double x) { + return x+0.1; } int main() { if (fesetround(FE_DOWNWARD)) { printf("fesetround(FE_DOWNWARD) unsuccessful\n"); } - double low = inverse(3.0); + double low = add(3.0); if (fesetround(FE_UPWARD)) { printf("fesetround(FE_UPWARD) unsuccessful\n"); } - double high = inverse(3.0); - printf("%d %a\n", low==high, high-low); + double high = add(3.0); + printf("%d %a %d\n", low==high, high-low, fegetround()); } -- cgit From 14cb39a563f56c852d8dacbbfa9604a722079e49 Mon Sep 17 00:00:00 2001 From: David Monniaux Date: Sat, 13 Apr 2019 20:34:45 +0200 Subject: code for checking IEEE-754 exceptions --- test/monniaux/math/exceptions.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 test/monniaux/math/exceptions.c (limited to 'test/monniaux/math') diff --git a/test/monniaux/math/exceptions.c b/test/monniaux/math/exceptions.c new file mode 100644 index 00000000..d4a6a26b --- /dev/null +++ b/test/monniaux/math/exceptions.c @@ -0,0 +1,41 @@ +#include +#include +#include + +#ifdef __K1C__ +#include +int fetestexcept(int excepts) { + int mask = (K1_SFR_CS_IO_MASK | K1_SFR_CS_DZ_MASK | K1_SFR_CS_OV_MASK | K1_SFR_CS_UN_MASK | K1_SFR_CS_IN_MASK) & excepts; + unsigned long long cs = __builtin_k1_get(K1_SFR_CS); + return cs & mask; +} + +int feclearexcept(int excepts) { + int mask = (K1_SFR_CS_IO_MASK | K1_SFR_CS_DZ_MASK | K1_SFR_CS_OV_MASK | K1_SFR_CS_UN_MASK | K1_SFR_CS_IN_MASK) & excepts; + __builtin_k1_wfxl(K1_SFR_CS, mask); + return 0; +} +#endif + +#pragma STDC FENV_ACCESS ON + +double add(double x, double y) { + return x+y; +} + +double mul(double x, double y) { + return x*y; +} + +int main() { + printf("%x\n", fetestexcept(FE_ALL_EXCEPT)); + double v1 = add(3.0, 0.1); + printf("%x\n", fetestexcept(FE_ALL_EXCEPT)); + feclearexcept(FE_INEXACT); + printf("%x\n", fetestexcept(FE_ALL_EXCEPT)); + double v2 = mul(DBL_MAX, DBL_MAX); + printf("%g %x\n", v2, fetestexcept(FE_ALL_EXCEPT)); + feclearexcept(FE_ALL_EXCEPT); + double v3 = mul(DBL_MIN, DBL_MIN); + printf("%g %x\n", v3, fetestexcept(FE_ALL_EXCEPT)); +} -- cgit From dc4d89e2b91012334855bbbf184df32aa5d6d982 Mon Sep 17 00:00:00 2001 From: David Monniaux Date: Sat, 13 Apr 2019 22:11:06 +0200 Subject: some more examples --- test/monniaux/math/exceptions.c | 43 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) (limited to 'test/monniaux/math') diff --git a/test/monniaux/math/exceptions.c b/test/monniaux/math/exceptions.c index d4a6a26b..05423e62 100644 --- a/test/monniaux/math/exceptions.c +++ b/test/monniaux/math/exceptions.c @@ -2,8 +2,9 @@ #include #include -#ifdef __K1C__ -#include +#pragma STDC FENV_ACCESS ON + +#ifdef __GNUC__ int fetestexcept(int excepts) { int mask = (K1_SFR_CS_IO_MASK | K1_SFR_CS_DZ_MASK | K1_SFR_CS_OV_MASK | K1_SFR_CS_UN_MASK | K1_SFR_CS_IN_MASK) & excepts; unsigned long long cs = __builtin_k1_get(K1_SFR_CS); @@ -17,8 +18,6 @@ int feclearexcept(int excepts) { } #endif -#pragma STDC FENV_ACCESS ON - double add(double x, double y) { return x+y; } @@ -27,15 +26,51 @@ double mul(double x, double y) { return x*y; } +float double2float(double x) { + return x; +} + +float uint2float(unsigned x) { + return x; +} + +double ulong2double(unsigned long x) { + return x; +} + +unsigned double2uint(double x) { + return x; +} + int main() { printf("%x\n", fetestexcept(FE_ALL_EXCEPT)); + double v1 = add(3.0, 0.1); printf("%x\n", fetestexcept(FE_ALL_EXCEPT)); feclearexcept(FE_INEXACT); + printf("%x\n", fetestexcept(FE_ALL_EXCEPT)); double v2 = mul(DBL_MAX, DBL_MAX); printf("%g %x\n", v2, fetestexcept(FE_ALL_EXCEPT)); feclearexcept(FE_ALL_EXCEPT); + double v3 = mul(DBL_MIN, DBL_MIN); printf("%g %x\n", v3, fetestexcept(FE_ALL_EXCEPT)); + feclearexcept(FE_ALL_EXCEPT); + + double v4 = double2float(DBL_MAX); + printf("%g %x\n", v4, fetestexcept(FE_ALL_EXCEPT)); + feclearexcept(FE_ALL_EXCEPT); + + float v5 = uint2float(0xC07FDFFFU); + printf("%g %x\n", v5, fetestexcept(FE_ALL_EXCEPT)); // BUG 0 should have INEXACT + feclearexcept(FE_ALL_EXCEPT); + + double v6 = ulong2double(0x11217763AFF77C7CUL); + printf("%g %x\n", v6, fetestexcept(FE_ALL_EXCEPT)); // BUG 0 should have INEXACT + feclearexcept(FE_ALL_EXCEPT); + + unsigned v7 = double2uint(-0.25); // softfloat says "0 and inexact" but here we have "0 and overflow" (due to negative input for unsigned?) + printf("%u %x\n", v7, fetestexcept(FE_ALL_EXCEPT)); + feclearexcept(FE_ALL_EXCEPT); } -- cgit From 7110f7a9ec67f999c68092cfce7072ff8134e991 Mon Sep 17 00:00:00 2001 From: David Monniaux Date: Sat, 13 Apr 2019 22:18:13 +0200 Subject: various bugs in FP --- test/monniaux/math/exceptions.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'test/monniaux/math') diff --git a/test/monniaux/math/exceptions.c b/test/monniaux/math/exceptions.c index 05423e62..ad3047a0 100644 --- a/test/monniaux/math/exceptions.c +++ b/test/monniaux/math/exceptions.c @@ -73,4 +73,10 @@ int main() { unsigned v7 = double2uint(-0.25); // softfloat says "0 and inexact" but here we have "0 and overflow" (due to negative input for unsigned?) printf("%u %x\n", v7, fetestexcept(FE_ALL_EXCEPT)); feclearexcept(FE_ALL_EXCEPT); + + // +41F.307672C5496EF + double d8 = 0x1.307672C5496EFp32; + unsigned v8 = double2uint(d8); + printf("%g %x %x\n", d8, v8, fetestexcept(FE_ALL_EXCEPT)); // BUG reports 307672C5 and inexact, but should report overflow + feclearexcept(FE_ALL_EXCEPT); } -- cgit From 4dd6603a4500e4de1315f2f1015dc615911d4c3d Mon Sep 17 00:00:00 2001 From: David Monniaux Date: Sat, 13 Apr 2019 22:57:11 +0200 Subject: identify bug from x86 --- test/monniaux/math/exceptions.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'test/monniaux/math') diff --git a/test/monniaux/math/exceptions.c b/test/monniaux/math/exceptions.c index ad3047a0..72107066 100644 --- a/test/monniaux/math/exceptions.c +++ b/test/monniaux/math/exceptions.c @@ -4,7 +4,7 @@ #pragma STDC FENV_ACCESS ON -#ifdef __GNUC__ +#if defined(__K1C__) && !defined(__COMPCERT__) int fetestexcept(int excepts) { int mask = (K1_SFR_CS_IO_MASK | K1_SFR_CS_DZ_MASK | K1_SFR_CS_OV_MASK | K1_SFR_CS_UN_MASK | K1_SFR_CS_IN_MASK) & excepts; unsigned long long cs = __builtin_k1_get(K1_SFR_CS); @@ -77,6 +77,8 @@ int main() { // +41F.307672C5496EF double d8 = 0x1.307672C5496EFp32; unsigned v8 = double2uint(d8); - printf("%g %x %x\n", d8, v8, fetestexcept(FE_ALL_EXCEPT)); // BUG reports 307672C5 and inexact, but should report overflow + printf("%g %x %x\n", d8, v8, fetestexcept(FE_ALL_EXCEPT)); + // BUG reports 307672C5 and inexact, but should report overflow + // bug comes from x86 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89175 feclearexcept(FE_ALL_EXCEPT); } -- cgit From a5ae2da4c92214bc202f70cbcff6f871156ce633 Mon Sep 17 00:00:00 2001 From: David Monniaux Date: Sun, 28 Apr 2019 12:50:20 +0200 Subject: more insf detection --- test/monniaux/math/exceptions.c | 42 ++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) (limited to 'test/monniaux/math') diff --git a/test/monniaux/math/exceptions.c b/test/monniaux/math/exceptions.c index 72107066..5d669510 100644 --- a/test/monniaux/math/exceptions.c +++ b/test/monniaux/math/exceptions.c @@ -18,11 +18,15 @@ int feclearexcept(int excepts) { } #endif -double add(double x, double y) { +double add_double(double x, double y) { return x+y; } -double mul(double x, double y) { +double mul_double(double x, double y) { + return x*y; +} + +float mul_float(float x, float y) { return x*y; } @@ -45,16 +49,16 @@ unsigned double2uint(double x) { int main() { printf("%x\n", fetestexcept(FE_ALL_EXCEPT)); - double v1 = add(3.0, 0.1); + double v1 = add_double(3.0, 0.1); printf("%x\n", fetestexcept(FE_ALL_EXCEPT)); feclearexcept(FE_INEXACT); printf("%x\n", fetestexcept(FE_ALL_EXCEPT)); - double v2 = mul(DBL_MAX, DBL_MAX); + double v2 = mul_double(DBL_MAX, DBL_MAX); printf("%g %x\n", v2, fetestexcept(FE_ALL_EXCEPT)); feclearexcept(FE_ALL_EXCEPT); - double v3 = mul(DBL_MIN, DBL_MIN); + double v3 = mul_double(DBL_MIN, DBL_MIN); printf("%g %x\n", v3, fetestexcept(FE_ALL_EXCEPT)); feclearexcept(FE_ALL_EXCEPT); @@ -67,18 +71,42 @@ int main() { feclearexcept(FE_ALL_EXCEPT); double v6 = ulong2double(0x11217763AFF77C7CUL); - printf("%g %x\n", v6, fetestexcept(FE_ALL_EXCEPT)); // BUG 0 should have INEXACT + printf("%a %x\n", v6, fetestexcept(FE_ALL_EXCEPT)); // BUG 0 should have INEXACT; correct on x86 + feclearexcept(FE_ALL_EXCEPT); + + double v6b = ulong2double(0xFFFFFFFFFFFFFFFFUL); + printf("%a %x\n", v6b, fetestexcept(FE_ALL_EXCEPT)); // BUG 0 should have INEXACT; correct on x86 feclearexcept(FE_ALL_EXCEPT); unsigned v7 = double2uint(-0.25); // softfloat says "0 and inexact" but here we have "0 and overflow" (due to negative input for unsigned?) + // unsure if (unsigned) (-0.25) should be 0 or an error + // BUG C99 annex F says that the error is invalid op not overflow printf("%u %x\n", v7, fetestexcept(FE_ALL_EXCEPT)); feclearexcept(FE_ALL_EXCEPT); - // +41F.307672C5496EF + // +41F.307672C5496EF in Berkeley Soft Float test double d8 = 0x1.307672C5496EFp32; unsigned v8 = double2uint(d8); printf("%g %x %x\n", d8, v8, fetestexcept(FE_ALL_EXCEPT)); // BUG reports 307672C5 and inexact, but should report overflow // bug comes from x86 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89175 feclearexcept(FE_ALL_EXCEPT); + // all f64_to_ui32_rx_minMag errors explained by + // 1) round to uin64 2) take 32 low order bits no precautions + + double d8b = 0x1.307672C5496EFp70; + unsigned v8b = double2uint(d8b); + printf("d8b %g %x %x\n", d8b, v8b, fetestexcept(FE_ALL_EXCEPT)); + feclearexcept(FE_ALL_EXCEPT); + + // +380.FFFFFFFFFFFFF => +01.000000 ...ux expected +01.000000 ....x + // Bug in soft float? + double v9 = double2float(0x1.FFFFFFFFFFFFFp-127); + printf("%a %x\n", v9, fetestexcept(FE_ALL_EXCEPT)); + feclearexcept(FE_ALL_EXCEPT); + + // +00.7FFFFF +7F.000001 => +01.000000 ...ux expected +01.000000 ....x + float v10 = mul_float(0x0.7FFFFFp-126, 0x1.000001p+0); + printf("%a %x\n", v10, fetestexcept(FE_ALL_EXCEPT)); + feclearexcept(FE_ALL_EXCEPT); } -- cgit From 1de15fa090646f0b96ea9b29a312af4e286dc22d Mon Sep 17 00:00:00 2001 From: David Monniaux Date: Sun, 28 Apr 2019 12:51:11 +0200 Subject: Revert "more insf detection" This reverts commit a5ae2da4c92214bc202f70cbcff6f871156ce633. --- test/monniaux/math/exceptions.c | 42 +++++++---------------------------------- 1 file changed, 7 insertions(+), 35 deletions(-) (limited to 'test/monniaux/math') diff --git a/test/monniaux/math/exceptions.c b/test/monniaux/math/exceptions.c index 5d669510..72107066 100644 --- a/test/monniaux/math/exceptions.c +++ b/test/monniaux/math/exceptions.c @@ -18,15 +18,11 @@ int feclearexcept(int excepts) { } #endif -double add_double(double x, double y) { +double add(double x, double y) { return x+y; } -double mul_double(double x, double y) { - return x*y; -} - -float mul_float(float x, float y) { +double mul(double x, double y) { return x*y; } @@ -49,16 +45,16 @@ unsigned double2uint(double x) { int main() { printf("%x\n", fetestexcept(FE_ALL_EXCEPT)); - double v1 = add_double(3.0, 0.1); + double v1 = add(3.0, 0.1); printf("%x\n", fetestexcept(FE_ALL_EXCEPT)); feclearexcept(FE_INEXACT); printf("%x\n", fetestexcept(FE_ALL_EXCEPT)); - double v2 = mul_double(DBL_MAX, DBL_MAX); + double v2 = mul(DBL_MAX, DBL_MAX); printf("%g %x\n", v2, fetestexcept(FE_ALL_EXCEPT)); feclearexcept(FE_ALL_EXCEPT); - double v3 = mul_double(DBL_MIN, DBL_MIN); + double v3 = mul(DBL_MIN, DBL_MIN); printf("%g %x\n", v3, fetestexcept(FE_ALL_EXCEPT)); feclearexcept(FE_ALL_EXCEPT); @@ -71,42 +67,18 @@ int main() { feclearexcept(FE_ALL_EXCEPT); double v6 = ulong2double(0x11217763AFF77C7CUL); - printf("%a %x\n", v6, fetestexcept(FE_ALL_EXCEPT)); // BUG 0 should have INEXACT; correct on x86 - feclearexcept(FE_ALL_EXCEPT); - - double v6b = ulong2double(0xFFFFFFFFFFFFFFFFUL); - printf("%a %x\n", v6b, fetestexcept(FE_ALL_EXCEPT)); // BUG 0 should have INEXACT; correct on x86 + printf("%g %x\n", v6, fetestexcept(FE_ALL_EXCEPT)); // BUG 0 should have INEXACT feclearexcept(FE_ALL_EXCEPT); unsigned v7 = double2uint(-0.25); // softfloat says "0 and inexact" but here we have "0 and overflow" (due to negative input for unsigned?) - // unsure if (unsigned) (-0.25) should be 0 or an error - // BUG C99 annex F says that the error is invalid op not overflow printf("%u %x\n", v7, fetestexcept(FE_ALL_EXCEPT)); feclearexcept(FE_ALL_EXCEPT); - // +41F.307672C5496EF in Berkeley Soft Float test + // +41F.307672C5496EF double d8 = 0x1.307672C5496EFp32; unsigned v8 = double2uint(d8); printf("%g %x %x\n", d8, v8, fetestexcept(FE_ALL_EXCEPT)); // BUG reports 307672C5 and inexact, but should report overflow // bug comes from x86 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89175 feclearexcept(FE_ALL_EXCEPT); - // all f64_to_ui32_rx_minMag errors explained by - // 1) round to uin64 2) take 32 low order bits no precautions - - double d8b = 0x1.307672C5496EFp70; - unsigned v8b = double2uint(d8b); - printf("d8b %g %x %x\n", d8b, v8b, fetestexcept(FE_ALL_EXCEPT)); - feclearexcept(FE_ALL_EXCEPT); - - // +380.FFFFFFFFFFFFF => +01.000000 ...ux expected +01.000000 ....x - // Bug in soft float? - double v9 = double2float(0x1.FFFFFFFFFFFFFp-127); - printf("%a %x\n", v9, fetestexcept(FE_ALL_EXCEPT)); - feclearexcept(FE_ALL_EXCEPT); - - // +00.7FFFFF +7F.000001 => +01.000000 ...ux expected +01.000000 ....x - float v10 = mul_float(0x0.7FFFFFp-126, 0x1.000001p+0); - printf("%a %x\n", v10, fetestexcept(FE_ALL_EXCEPT)); - feclearexcept(FE_ALL_EXCEPT); } -- cgit