diff options
author | das <das@FreeBSD.org> | 2013-05-27 08:50:10 +0000 |
---|---|---|
committer | das <das@FreeBSD.org> | 2013-05-27 08:50:10 +0000 |
commit | e7b0a63c190c7ecb475b09f41387a75952540f49 (patch) | |
tree | fe26b077920f74a021643eb895e508cd1a90d404 /tools/regression | |
parent | e97a0dc9656bc3f5214866731094513064e59725 (diff) | |
download | FreeBSD-src-e7b0a63c190c7ecb475b09f41387a75952540f49.zip FreeBSD-src-e7b0a63c190c7ecb475b09f41387a75952540f49.tar.gz |
Fix some regressions caused by the switch from gcc to clang. The fixes
are workarounds for various symptoms of the problem described in clang
bugs 3929, 8100, 8241, 10409, and 12958.
The regression tests did their job: they failed, someone brought it
up on the mailing lists, and then the issue got ignored for 6 months.
Oops. There may still be some regressions for functions we don't have
test coverage for yet.
Diffstat (limited to 'tools/regression')
-rw-r--r-- | tools/regression/lib/msun/test-fma.c | 44 |
1 files changed, 25 insertions, 19 deletions
diff --git a/tools/regression/lib/msun/test-fma.c b/tools/regression/lib/msun/test-fma.c index 1237a60..c17ef45 100644 --- a/tools/regression/lib/msun/test-fma.c +++ b/tools/regression/lib/msun/test-fma.c @@ -77,6 +77,12 @@ __FBSDID("$FreeBSD$"); } while (0) /* + * This is needed because clang constant-folds fma in ways that are incorrect + * in rounding modes other than FE_TONEAREST. + */ +volatile double one = 1.0; + +/* * Determine whether x and y are equal, with two special rules: * +0.0 != -0.0 * NaN == NaN @@ -108,9 +114,9 @@ test_zeroes(void) testall(-0.0, 0.0, -0.0, -0.0, ALL_STD_EXCEPT, 0); testall(0.0, -0.0, -0.0, -0.0, ALL_STD_EXCEPT, 0); - testall(-1.0, 1.0, 1.0, rd ? -0.0 : 0.0, ALL_STD_EXCEPT, 0); - testall(1.0, -1.0, 1.0, rd ? -0.0 : 0.0, ALL_STD_EXCEPT, 0); - testall(-1.0, -1.0, -1.0, rd ? -0.0 : 0.0, ALL_STD_EXCEPT, 0); + testall(-one, one, one, rd ? -0.0 : 0.0, ALL_STD_EXCEPT, 0); + testall(one, -one, one, rd ? -0.0 : 0.0, ALL_STD_EXCEPT, 0); + testall(-one, -one, -one, rd ? -0.0 : 0.0, ALL_STD_EXCEPT, 0); switch (fegetround()) { case FE_TONEAREST: @@ -190,53 +196,53 @@ test_small_z(void) /* x*y positive, z positive */ if (fegetround() == FE_UPWARD) { - test(fmaf, 1.0, 1.0, 0x1.0p-100, 1.0 + FLT_EPSILON, + test(fmaf, one, one, 0x1.0p-100, 1.0 + FLT_EPSILON, ALL_STD_EXCEPT, FE_INEXACT); - test(fma, 1.0, 1.0, 0x1.0p-200, 1.0 + DBL_EPSILON, + test(fma, one, one, 0x1.0p-200, 1.0 + DBL_EPSILON, ALL_STD_EXCEPT, FE_INEXACT); - test(fmal, 1.0, 1.0, 0x1.0p-200, 1.0 + LDBL_EPSILON, + test(fmal, one, one, 0x1.0p-200, 1.0 + LDBL_EPSILON, ALL_STD_EXCEPT, FE_INEXACT); } else { - testall(0x1.0p100, 1.0, 0x1.0p-100, 0x1.0p100, + testall(0x1.0p100, one, 0x1.0p-100, 0x1.0p100, ALL_STD_EXCEPT, FE_INEXACT); } /* x*y negative, z negative */ if (fegetround() == FE_DOWNWARD) { - test(fmaf, -1.0, 1.0, -0x1.0p-100, -(1.0 + FLT_EPSILON), + test(fmaf, -one, one, -0x1.0p-100, -(1.0 + FLT_EPSILON), ALL_STD_EXCEPT, FE_INEXACT); - test(fma, -1.0, 1.0, -0x1.0p-200, -(1.0 + DBL_EPSILON), + test(fma, -one, one, -0x1.0p-200, -(1.0 + DBL_EPSILON), ALL_STD_EXCEPT, FE_INEXACT); - test(fmal, -1.0, 1.0, -0x1.0p-200, -(1.0 + LDBL_EPSILON), + test(fmal, -one, one, -0x1.0p-200, -(1.0 + LDBL_EPSILON), ALL_STD_EXCEPT, FE_INEXACT); } else { - testall(0x1.0p100, -1.0, -0x1.0p-100, -0x1.0p100, + testall(0x1.0p100, -one, -0x1.0p-100, -0x1.0p100, ALL_STD_EXCEPT, FE_INEXACT); } /* x*y positive, z negative */ if (fegetround() == FE_DOWNWARD || fegetround() == FE_TOWARDZERO) { - test(fmaf, 1.0, 1.0, -0x1.0p-100, 1.0 - FLT_EPSILON / 2, + test(fmaf, one, one, -0x1.0p-100, 1.0 - FLT_EPSILON / 2, ALL_STD_EXCEPT, FE_INEXACT); - test(fma, 1.0, 1.0, -0x1.0p-200, 1.0 - DBL_EPSILON / 2, + test(fma, one, one, -0x1.0p-200, 1.0 - DBL_EPSILON / 2, ALL_STD_EXCEPT, FE_INEXACT); - test(fmal, 1.0, 1.0, -0x1.0p-200, 1.0 - LDBL_EPSILON / 2, + test(fmal, one, one, -0x1.0p-200, 1.0 - LDBL_EPSILON / 2, ALL_STD_EXCEPT, FE_INEXACT); } else { - testall(0x1.0p100, 1.0, -0x1.0p-100, 0x1.0p100, + testall(0x1.0p100, one, -0x1.0p-100, 0x1.0p100, ALL_STD_EXCEPT, FE_INEXACT); } /* x*y negative, z positive */ if (fegetround() == FE_UPWARD || fegetround() == FE_TOWARDZERO) { - test(fmaf, -1.0, 1.0, 0x1.0p-100, -1.0 + FLT_EPSILON / 2, + test(fmaf, -one, one, 0x1.0p-100, -1.0 + FLT_EPSILON / 2, ALL_STD_EXCEPT, FE_INEXACT); - test(fma, -1.0, 1.0, 0x1.0p-200, -1.0 + DBL_EPSILON / 2, + test(fma, -one, one, 0x1.0p-200, -1.0 + DBL_EPSILON / 2, ALL_STD_EXCEPT, FE_INEXACT); - test(fmal, -1.0, 1.0, 0x1.0p-200, -1.0 + LDBL_EPSILON / 2, + test(fmal, -one, one, 0x1.0p-200, -1.0 + LDBL_EPSILON / 2, ALL_STD_EXCEPT, FE_INEXACT); } else { - testall(-0x1.0p100, 1.0, 0x1.0p-100, -0x1.0p100, + testall(-0x1.0p100, one, 0x1.0p-100, -0x1.0p100, ALL_STD_EXCEPT, FE_INEXACT); } } |