summaryrefslogtreecommitdiffstats
path: root/tools/regression
diff options
context:
space:
mode:
authordas <das@FreeBSD.org>2013-05-27 08:50:10 +0000
committerdas <das@FreeBSD.org>2013-05-27 08:50:10 +0000
commite7b0a63c190c7ecb475b09f41387a75952540f49 (patch)
treefe26b077920f74a021643eb895e508cd1a90d404 /tools/regression
parente97a0dc9656bc3f5214866731094513064e59725 (diff)
downloadFreeBSD-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.c44
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);
}
}
OpenPOWER on IntegriCloud