diff options
author | Joseph Myers <joseph@codesourcery.com> | 2012-09-29 18:31:54 +0000 |
---|---|---|
committer | Joseph Myers <joseph@codesourcery.com> | 2012-09-29 18:31:54 +0000 |
commit | 8ec5b01346114da38e806ca1867da688d3a360e2 (patch) | |
tree | 8a55bd704c2a6ca8164202217e2048bb33a7dacb /math | |
parent | b1fa802e1ad4104060fe93b4b3b078ba46be0933 (diff) | |
download | glibc-8ec5b01346114da38e806ca1867da688d3a360e2.tar.gz glibc-8ec5b01346114da38e806ca1867da688d3a360e2.tar.xz glibc-8ec5b01346114da38e806ca1867da688d3a360e2.zip |
Fix sign of exact zero return from fma (bug 14638).
Diffstat (limited to 'math')
-rw-r--r-- | math/libm-test.inc | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/math/libm-test.inc b/math/libm-test.inc index e8398bd0ee..007eea1f30 100644 --- a/math/libm-test.inc +++ b/math/libm-test.inc @@ -4546,6 +4546,36 @@ fma_test (void) TEST_fff_f (fma, minus_infty, minus_infty, plus_infty, plus_infty); TEST_fff_f (fma, plus_infty, minus_infty, minus_infty, minus_infty); + TEST_fff_f (fma, plus_zero, plus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, plus_zero, minus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, minus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, minus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, minus_zero, plus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, minus_zero, plus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, minus_zero, minus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, minus_zero, minus_zero, minus_zero, plus_zero); + TEST_fff_f (fma, 1.0, plus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, 1.0, plus_zero, minus_zero, plus_zero); + TEST_fff_f (fma, 1.0, minus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, 1.0, minus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, -1.0, plus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, -1.0, plus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, -1.0, minus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, -1.0, minus_zero, minus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, 1.0, plus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, 1.0, minus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, -1.0, plus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, -1.0, minus_zero, minus_zero); + TEST_fff_f (fma, minus_zero, 1.0, plus_zero, plus_zero); + TEST_fff_f (fma, minus_zero, 1.0, minus_zero, minus_zero); + TEST_fff_f (fma, minus_zero, -1.0, plus_zero, plus_zero); + TEST_fff_f (fma, minus_zero, -1.0, minus_zero, plus_zero); + + TEST_fff_f (fma, 1.0, 1.0, -1.0, plus_zero); + TEST_fff_f (fma, 1.0, -1.0, 1.0, plus_zero); + TEST_fff_f (fma, -1.0, 1.0, 1.0, plus_zero); + TEST_fff_f (fma, -1.0, -1.0, -1.0, plus_zero); + #if defined (TEST_FLOAT) && FLT_MANT_DIG == 24 TEST_fff_f (fma, 0x1.7ff8p+13, 0x1.000002p+0, 0x1.ffffp-24, 0x1.7ff802p+13); TEST_fff_f (fma, 0x1.fffp+0, 0x1.00001p+0, -0x1.fffp+0, 0x1.fffp-20); @@ -4608,6 +4638,147 @@ fma_test (void) static void +fma_test_towardzero (void) +{ + int save_round_mode; + START (fma_towardzero); + + save_round_mode = fegetround (); + + if (!fesetround (FE_TOWARDZERO)) + { + TEST_fff_f (fma, plus_zero, plus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, plus_zero, minus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, minus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, minus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, minus_zero, plus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, minus_zero, plus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, minus_zero, minus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, minus_zero, minus_zero, minus_zero, plus_zero); + TEST_fff_f (fma, 1.0, plus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, 1.0, plus_zero, minus_zero, plus_zero); + TEST_fff_f (fma, 1.0, minus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, 1.0, minus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, -1.0, plus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, -1.0, plus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, -1.0, minus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, -1.0, minus_zero, minus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, 1.0, plus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, 1.0, minus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, -1.0, plus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, -1.0, minus_zero, minus_zero); + TEST_fff_f (fma, minus_zero, 1.0, plus_zero, plus_zero); + TEST_fff_f (fma, minus_zero, 1.0, minus_zero, minus_zero); + TEST_fff_f (fma, minus_zero, -1.0, plus_zero, plus_zero); + TEST_fff_f (fma, minus_zero, -1.0, minus_zero, plus_zero); + + TEST_fff_f (fma, 1.0, 1.0, -1.0, plus_zero); + TEST_fff_f (fma, 1.0, -1.0, 1.0, plus_zero); + TEST_fff_f (fma, -1.0, 1.0, 1.0, plus_zero); + TEST_fff_f (fma, -1.0, -1.0, -1.0, plus_zero); + } + + fesetround (save_round_mode); + + END (fma_towardzero); +} + + +static void +fma_test_downward (void) +{ + int save_round_mode; + START (fma_downward); + + save_round_mode = fegetround (); + + if (!fesetround (FE_DOWNWARD)) + { + TEST_fff_f (fma, plus_zero, plus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, plus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, plus_zero, minus_zero, plus_zero, minus_zero); + TEST_fff_f (fma, plus_zero, minus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, minus_zero, plus_zero, plus_zero, minus_zero); + TEST_fff_f (fma, minus_zero, plus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, minus_zero, minus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, minus_zero, minus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, 1.0, plus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, 1.0, plus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, 1.0, minus_zero, plus_zero, minus_zero); + TEST_fff_f (fma, 1.0, minus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, -1.0, plus_zero, plus_zero, minus_zero); + TEST_fff_f (fma, -1.0, plus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, -1.0, minus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, -1.0, minus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, plus_zero, 1.0, plus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, 1.0, minus_zero, minus_zero); + TEST_fff_f (fma, plus_zero, -1.0, plus_zero, minus_zero); + TEST_fff_f (fma, plus_zero, -1.0, minus_zero, minus_zero); + TEST_fff_f (fma, minus_zero, 1.0, plus_zero, minus_zero); + TEST_fff_f (fma, minus_zero, 1.0, minus_zero, minus_zero); + TEST_fff_f (fma, minus_zero, -1.0, plus_zero, plus_zero); + TEST_fff_f (fma, minus_zero, -1.0, minus_zero, minus_zero); + + TEST_fff_f (fma, 1.0, 1.0, -1.0, minus_zero); + TEST_fff_f (fma, 1.0, -1.0, 1.0, minus_zero); + TEST_fff_f (fma, -1.0, 1.0, 1.0, minus_zero); + TEST_fff_f (fma, -1.0, -1.0, -1.0, minus_zero); + } + + fesetround (save_round_mode); + + END (fma_downward); +} + + +static void +fma_test_upward (void) +{ + int save_round_mode; + START (fma_upward); + + save_round_mode = fegetround (); + + if (!fesetround (FE_UPWARD)) + { + TEST_fff_f (fma, plus_zero, plus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, plus_zero, minus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, minus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, minus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, minus_zero, plus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, minus_zero, plus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, minus_zero, minus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, minus_zero, minus_zero, minus_zero, plus_zero); + TEST_fff_f (fma, 1.0, plus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, 1.0, plus_zero, minus_zero, plus_zero); + TEST_fff_f (fma, 1.0, minus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, 1.0, minus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, -1.0, plus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, -1.0, plus_zero, minus_zero, minus_zero); + TEST_fff_f (fma, -1.0, minus_zero, plus_zero, plus_zero); + TEST_fff_f (fma, -1.0, minus_zero, minus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, 1.0, plus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, 1.0, minus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, -1.0, plus_zero, plus_zero); + TEST_fff_f (fma, plus_zero, -1.0, minus_zero, minus_zero); + TEST_fff_f (fma, minus_zero, 1.0, plus_zero, plus_zero); + TEST_fff_f (fma, minus_zero, 1.0, minus_zero, minus_zero); + TEST_fff_f (fma, minus_zero, -1.0, plus_zero, plus_zero); + TEST_fff_f (fma, minus_zero, -1.0, minus_zero, plus_zero); + + TEST_fff_f (fma, 1.0, 1.0, -1.0, plus_zero); + TEST_fff_f (fma, 1.0, -1.0, 1.0, plus_zero); + TEST_fff_f (fma, -1.0, 1.0, 1.0, plus_zero); + TEST_fff_f (fma, -1.0, -1.0, -1.0, plus_zero); + } + + fesetround (save_round_mode); + + END (fma_upward); +} + + +static void fmax_test (void) { START (fmax); @@ -9539,6 +9710,9 @@ main (int argc, char **argv) /* Multiply and add: */ fma_test (); + fma_test_towardzero (); + fma_test_downward (); + fma_test_upward (); /* Complex functions: */ cabs_test (); |