1 /* Test of fused multiply-add.
2 Copyright (C) 2011 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17 /* Written by Bruno Haible <bruno@clisp.org>, 2011. */
19 /* Returns 2^e as a DOUBLE. */
23 /* One could define XE_RANGE and YE_RANGE to 5 or 60, but this would slow down
24 the test without the expectation of catching more bugs. */
28 /* Define to 1 if you want to allow the behaviour of the glibc 2.11 fma()
29 implementation. glibc bug #1..#16 refer to the test cases in
30 <http://sourceware.org/bugzilla/show_bug.cgi?id=13304>. */
31 #if __GLIBC__ >= 2 && 0
32 # define FORGIVE_GLIBC_BUG 1
34 # define FORGIVE_GLIBC_BUG 0
37 /* Define to 1 if you want to allow the behaviour of the 'double-double'
38 implementation of 'long double' (seen on IRIX 6.5 and Linux/PowerPC).
39 This floating-point type does not follow IEEE 754. */
40 #if MANT_BIT == LDBL_MANT_BIT && LDBL_MANT_BIT == 2 * DBL_MANT_BIT
41 # define FORGIVE_DOUBLEDOUBLE_BUG 1
43 # define FORGIVE_DOUBLEDOUBLE_BUG 0
46 /* Subnormal numbers appear to not work as expected on IRIX 6.5. */
48 # define MIN_SUBNORMAL_EXP (MIN_EXP - 1)
50 # define MIN_SUBNORMAL_EXP (MIN_EXP - MANT_BIT)
53 /* Check rounding behaviour. */
56 test_function (DOUBLE (*my_fma) (DOUBLE, DOUBLE, DOUBLE))
58 /* Array mapping n to (-1)^n. */
59 static const DOUBLE pow_m1[] =
61 L_(1.0), - L_(1.0), L_(1.0), - L_(1.0),
62 L_(1.0), - L_(1.0), L_(1.0), - L_(1.0)
67 volatile DOUBLE result;
68 volatile DOUBLE expected;
70 /* A product x * y that consists of two bits. */
79 for (xs = 0; xs < 2; xs++)
80 for (xe = -XE_RANGE; xe <= XE_RANGE; xe++)
82 x = pow_m1[xs] * POW2 (xe); /* (-1)^xs * 2^xe */
84 for (ys = 0; ys < 2; ys++)
85 for (ye = -YE_RANGE; ye <= YE_RANGE; ye++)
87 y = pow_m1[ys] * POW2 (ye); /* (-1)^ys * 2^ye */
89 sign = pow_m1[xs + ys];
91 /* Test addition (same signs). */
92 for (ze = MIN_EXP - MANT_BIT; ze <= MAX_EXP - 1;)
94 z = sign * POW2 (ze); /* (-1)^(xs+ys) * 2^ze */
95 result = my_fma (x, y, z);
96 if (xe + ye >= ze + MANT_BIT)
97 expected = sign * POW2 (xe + ye);
98 else if (xe + ye > ze - MANT_BIT)
99 expected = sign * (POW2 (xe + ye) + POW2 (ze));
102 ASSERT (result == expected);
105 /* Shortcut some values of ze, to speed up the test. */
106 if (ze == MIN_EXP + MANT_BIT)
107 ze = - 2 * MANT_BIT - 1;
108 else if (ze == 2 * MANT_BIT)
109 ze = MAX_EXP - MANT_BIT - 1;
112 /* Test subtraction (opposite signs). */
113 for (ze = MIN_EXP - MANT_BIT; ze <= MAX_EXP - 1;)
115 z = - sign * POW2 (ze); /* (-1)^(xs+ys+1) * 2^ze */
116 result = my_fma (x, y, z);
117 if (xe + ye > ze + MANT_BIT)
118 expected = sign * POW2 (xe + ye);
119 else if (xe + ye >= ze)
120 expected = sign * (POW2 (xe + ye) - POW2 (ze));
121 else if (xe + ye > ze - 1 - MANT_BIT)
122 expected = - sign * (POW2 (ze) - POW2 (xe + ye));
125 ASSERT (result == expected);
128 /* Shortcut some values of ze, to speed up the test. */
129 if (ze == MIN_EXP + MANT_BIT)
130 ze = - 2 * MANT_BIT - 1;
131 else if (ze == 2 * MANT_BIT)
132 ze = MAX_EXP - MANT_BIT - 1;
137 /* A product x * y that consists of three bits. */
147 for (i = 1; i <= MANT_BIT - 1; i++)
148 for (xs = 0; xs < 2; xs++)
149 for (xe = -XE_RANGE; xe <= XE_RANGE; xe++)
151 x = /* (-1)^xs * (2^xe + 2^(xe-i)) */
152 pow_m1[xs] * (POW2 (xe) + POW2 (xe - i));
154 for (ys = 0; ys < 2; ys++)
155 for (ye = -YE_RANGE; ye <= YE_RANGE; ye++)
157 y = /* (-1)^ys * (2^ye + 2^(ye-i)) */
158 pow_m1[ys] * (POW2 (ye) + POW2 (ye - i));
160 sign = pow_m1[xs + ys];
162 /* The exact value of x * y is
163 (-1)^(xs+ys) * (2^(xe+ye) + 2^(xe+ye-i+1) + 2^(xe+ye-2*i)) */
165 /* Test addition (same signs). */
166 for (ze = MIN_SUBNORMAL_EXP; ze <= MAX_EXP - 1;)
168 z = sign * POW2 (ze); /* (-1)^(xs+ys) * 2^ze */
169 result = my_fma (x, y, z);
170 if (FORGIVE_DOUBLEDOUBLE_BUG)
172 && xe + ye < ze + MANT_BIT
173 && i == DBL_MANT_BIT)
174 || (xe + ye == ze + DBL_MANT_BIT && i == DBL_MANT_BIT + 1)
175 || (xe + ye == ze + MANT_BIT - 1 && i == 1))
177 if (xe + ye > ze + MANT_BIT)
179 if (2 * i > MANT_BIT)
181 sign * (POW2 (xe + ye)
182 + POW2 (xe + ye - i + 1));
183 else if (2 * i == MANT_BIT)
185 if (FORGIVE_GLIBC_BUG) /* glibc bug #7 */
188 sign * (POW2 (xe + ye)
189 + POW2 (xe + ye - i + 1)
190 + POW2 (xe + ye - MANT_BIT + 1));
194 sign * (POW2 (xe + ye)
195 + POW2 (xe + ye - i + 1)
196 + POW2 (xe + ye - 2 * i));
198 else if (xe + ye == ze + MANT_BIT)
200 if (2 * i >= MANT_BIT)
202 if (FORGIVE_GLIBC_BUG) /* glibc bug #8 */
205 sign * (POW2 (xe + ye)
206 + POW2 (xe + ye - i + 1)
207 + POW2 (xe + ye - MANT_BIT + 1));
209 else if (2 * i == MANT_BIT - 1)
210 /* round-to-even rounds up */
212 sign * (POW2 (xe + ye)
213 + POW2 (xe + ye - i + 1)
214 + POW2 (xe + ye - 2 * i + 1));
217 sign * (POW2 (xe + ye)
218 + POW2 (xe + ye - i + 1)
219 + POW2 (xe + ye - 2 * i));
221 else if (xe + ye > ze - MANT_BIT + 2 * i)
223 if (2 * i == MANT_BIT)
224 if (FORGIVE_GLIBC_BUG) /* glibc bug #9 */
229 + POW2 (xe + ye - i + 1)
230 + POW2 (xe + ye - 2 * i));
232 else if (xe + ye >= ze - MANT_BIT + i)
236 + POW2 (xe + ye - i + 1));
237 else if (xe + ye == ze - MANT_BIT + i - 1)
239 if (2 * i >= MANT_BIT)
240 if (FORGIVE_GLIBC_BUG) /* glibc bug #3, #10 */
244 sign * (POW2 (ze) + POW2 (ze - MANT_BIT + 1));
249 + POW2 (ze - MANT_BIT + 1));
251 else if (xe + ye >= ze - MANT_BIT + 1)
252 expected = sign * (POW2 (ze) + POW2 (xe + ye));
253 else if (xe + ye == ze - MANT_BIT)
255 sign * (POW2 (ze) + POW2 (ze - MANT_BIT + 1));
256 else if (xe + ye == ze - MANT_BIT - 1)
260 if (FORGIVE_GLIBC_BUG) /* glibc bug #1 */
263 sign * (POW2 (ze) + POW2 (ze - MANT_BIT + 1));
270 ASSERT (result == expected);
274 /* Shortcut some values of ze, to speed up the test. */
275 if (ze == MIN_EXP + MANT_BIT)
276 ze = - 2 * MANT_BIT - 1;
277 else if (ze == 2 * MANT_BIT)
278 ze = MAX_EXP - MANT_BIT - 1;
281 /* Test subtraction (opposite signs). */
283 for (ze = MIN_SUBNORMAL_EXP; ze <= MAX_EXP - 1;)
285 z = - sign * POW2 (ze); /* (-1)^(xs+ys+1) * 2^ze */
286 result = my_fma (x, y, z);
287 if (FORGIVE_DOUBLEDOUBLE_BUG)
288 if ((xe + ye == ze && i == MANT_BIT - 1)
290 && xe + ye <= ze + DBL_MANT_BIT - 1
291 && i == DBL_MANT_BIT + 1)
292 || (xe + ye >= ze + DBL_MANT_BIT - 1
293 && xe + ye < ze + MANT_BIT
294 && xe + ye == ze + i - 1)
295 || (xe + ye > ze + DBL_MANT_BIT
296 && xe + ye < ze + MANT_BIT
297 && i == DBL_MANT_BIT))
301 /* maximal extinction */
302 if (2 * i >= MANT_BIT)
303 if (FORGIVE_GLIBC_BUG) /* glibc bug #12 */
306 sign * (POW2 (xe + ye - i + 1)
307 + POW2 (xe + ye - 2 * i));
309 else if (xe + ye == ze - 1)
311 /* significant extinction */
312 if (2 * i > MANT_BIT)
314 sign * (- POW2 (xe + ye)
315 + POW2 (xe + ye - i + 1));
318 if (2 * i == MANT_BIT)
319 if (FORGIVE_GLIBC_BUG) /* glibc bug #13 */
322 sign * (- POW2 (xe + ye)
323 + POW2 (xe + ye - i + 1)
324 + POW2 (xe + ye - 2 * i));
327 else if (xe + ye > ze + MANT_BIT)
329 if (2 * i >= MANT_BIT)
331 sign * (POW2 (xe + ye)
332 + POW2 (xe + ye - i + 1));
335 sign * (POW2 (xe + ye)
336 + POW2 (xe + ye - i + 1)
337 + POW2 (xe + ye - 2 * i));
339 else if (xe + ye == ze + MANT_BIT)
341 if (2 * i >= MANT_BIT)
343 sign * (POW2 (xe + ye)
344 + POW2 (xe + ye - i + 1));
345 else if (2 * i == MANT_BIT - 1)
346 /* round-to-even rounds down */
348 sign * (POW2 (xe + ye)
349 + POW2 (xe + ye - i + 1));
351 /* round-to-even rounds up */
353 sign * (POW2 (xe + ye)
354 + POW2 (xe + ye - i + 1)
355 + POW2 (xe + ye - 2 * i));
357 else if (xe + ye >= ze - MANT_BIT + 2 * i)
359 if (2 * i == MANT_BIT)
360 if (FORGIVE_GLIBC_BUG) /* glibc bug #11 */
365 + POW2 (xe + ye - i + 1)
366 + POW2 (xe + ye - 2 * i));
368 else if (xe + ye >= ze - MANT_BIT + i - 1)
372 + POW2 (xe + ye - i + 1));
373 else if (xe + ye == ze - MANT_BIT + i - 2)
375 if (2 * i >= MANT_BIT)
376 if (FORGIVE_GLIBC_BUG) /* glibc bug #4, #14 */
381 + POW2 (ze - MANT_BIT));
383 else if (xe + ye >= ze - MANT_BIT)
387 else if (xe + ye == ze - MANT_BIT - 1)
389 if (FORGIVE_GLIBC_BUG) /* glibc bug #2 */
393 + POW2 (ze - MANT_BIT));
397 ASSERT (result == expected);
401 /* Shortcut some values of ze, to speed up the test. */
402 if (ze == MIN_EXP + MANT_BIT)
403 ze = - 2 * MANT_BIT - 1;
404 else if (ze == 2 * MANT_BIT)
405 ze = MAX_EXP - MANT_BIT - 1;
410 /* TODO: Similar tests with
411 x = (-1)^xs * (2^xe - 2^(xe-i)), y = (-1)^ys * (2^ye - 2^(ye-i)) */
412 /* A product x * y that consists of one segment of bits (or, if you prefer,
413 two bits, one with positive weight and one with negative weight). */
423 for (i = 1; i <= MANT_BIT - 1; i++)
424 for (xs = 0; xs < 2; xs++)
425 for (xe = -XE_RANGE; xe <= XE_RANGE; xe++)
427 x = /* (-1)^xs * (2^xe + 2^(xe-i)) */
428 pow_m1[xs] * (POW2 (xe) + POW2 (xe - i));
430 for (ys = 0; ys < 2; ys++)
431 for (ye = -YE_RANGE; ye <= YE_RANGE; ye++)
433 y = /* (-1)^ys * (2^ye - 2^(ye-i)) */
434 pow_m1[ys] * (POW2 (ye) - POW2 (ye - i));
436 sign = pow_m1[xs + ys];
438 /* The exact value of x * y is
439 (-1)^(xs+ys) * (2^(xe+ye) - 2^(xe+ye-2*i)) */
441 /* Test addition (same signs). */
442 for (ze = MIN_EXP - MANT_BIT; ze <= MAX_EXP - 1;)
444 z = sign * POW2 (ze); /* (-1)^(xs+ys) * 2^ze */
445 result = my_fma (x, y, z);
446 if (FORGIVE_DOUBLEDOUBLE_BUG)
447 if ((xe + ye == ze + MANT_BIT && i > DBL_MANT_BIT)
448 || (xe + ye < ze + MANT_BIT
450 && i == DBL_MANT_BIT)
452 && xe + ye == ze - MANT_BIT + 2 * i))
454 if (xe + ye > ze + MANT_BIT + 1)
456 if (2 * i > MANT_BIT)
457 expected = sign * POW2 (xe + ye);
460 sign * (POW2 (xe + ye)
461 - POW2 (xe + ye - 2 * i));
463 else if (xe + ye == ze + MANT_BIT + 1)
465 if (2 * i >= MANT_BIT)
466 expected = sign * POW2 (xe + ye);
469 sign * (POW2 (xe + ye)
470 - POW2 (xe + ye - 2 * i));
472 else if (xe + ye >= ze - MANT_BIT + 2 * i)
474 if (2 * i > MANT_BIT)
476 sign * (POW2 (xe + ye) + POW2 (ze));
479 sign * (POW2 (xe + ye)
480 - POW2 (xe + ye - 2 * i)
483 else if (xe + ye >= ze - MANT_BIT + 1)
485 sign * (POW2 (ze) + POW2 (xe + ye));
488 ASSERT (result == expected);
492 /* Shortcut some values of ze, to speed up the test. */
493 if (ze == MIN_EXP + MANT_BIT)
494 ze = - 2 * MANT_BIT - 1;
495 else if (ze == 2 * MANT_BIT)
496 ze = MAX_EXP - MANT_BIT - 1;
499 /* Test subtraction (opposite signs). */
501 for (ze = MIN_SUBNORMAL_EXP; ze <= MAX_EXP - 1;)
503 z = - sign * POW2 (ze); /* (-1)^(xs+ys+1) * 2^ze */
504 result = my_fma (x, y, z);
505 if (FORGIVE_DOUBLEDOUBLE_BUG)
507 && xe + ye < ze + DBL_MANT_BIT
508 && xe + ye == ze + 2 * i - LDBL_MANT_BIT)
512 /* maximal extinction */
513 if (2 * i > MANT_BIT)
514 if (FORGIVE_GLIBC_BUG) /* glibc bug #16 */
516 expected = sign * - POW2 (xe + ye - 2 * i);
518 else if (xe + ye > ze + MANT_BIT + 1)
520 if (2 * i > MANT_BIT + 1)
521 expected = sign * POW2 (xe + ye);
522 else if (2 * i == MANT_BIT + 1)
524 if (FORGIVE_GLIBC_BUG) /* glibc bug #6 */
527 sign * (POW2 (xe + ye)
528 - POW2 (xe + ye - MANT_BIT));
532 sign * (POW2 (xe + ye)
533 - POW2 (xe + ye - 2 * i));
535 else if (xe + ye == ze + MANT_BIT + 1)
537 if (2 * i > MANT_BIT)
539 if (FORGIVE_GLIBC_BUG) /* glibc bug #15 */
542 sign * (POW2 (xe + ye)
543 - POW2 (xe + ye - MANT_BIT));
545 else if (2 * i == MANT_BIT)
547 sign * (POW2 (xe + ye)
548 - POW2 (xe + ye - MANT_BIT + 1));
551 sign * (POW2 (xe + ye)
552 - POW2 (xe + ye - 2 * i));
554 else if (xe + ye == ze + MANT_BIT)
556 if (2 * i > MANT_BIT + 1)
558 sign * (POW2 (xe + ye)
559 - POW2 (xe + ye - MANT_BIT));
560 else if (2 * i == MANT_BIT + 1)
562 sign * (POW2 (xe + ye)
563 - POW2 (xe + ye - MANT_BIT + 1));
566 sign * (POW2 (xe + ye)
568 - POW2 (xe + ye - 2 * i));
570 else if (xe + ye > ze - MANT_BIT + 2 * i)
572 if (2 * i > MANT_BIT)
574 sign * (POW2 (xe + ye) - POW2 (ze));
577 sign * (POW2 (xe + ye)
579 - POW2 (xe + ye - 2 * i));
581 else if (xe + ye == ze - MANT_BIT + 2 * i)
585 - POW2 (xe + ye - 2 * i));
586 else if (xe + ye > ze - MANT_BIT)
587 expected = sign * (- POW2 (ze) + POW2 (xe + ye));
588 else if (xe + ye == ze - MANT_BIT)
590 if (FORGIVE_GLIBC_BUG) /* glibc bug #5 */
592 expected = sign * (- POW2 (ze) + POW2 (xe + ye));
596 ASSERT (result == expected);
600 /* Shortcut some values of ze, to speed up the test. */
601 if (ze == MIN_EXP + MANT_BIT)
602 ze = - 2 * MANT_BIT - 1;
603 else if (ze == 2 * MANT_BIT)
604 ze = MAX_EXP - MANT_BIT - 1;
609 /* TODO: Tests with denormalized results. */
610 /* Tests with temporary overflow. */
612 volatile DOUBLE x = POW2 (MAX_EXP - 1);
613 volatile DOUBLE y = POW2 (MAX_EXP - 1);
614 volatile DOUBLE z = - INFINITY;
615 volatile DOUBLE result = my_fma (x, y, z);
616 ASSERT (result == - INFINITY);
619 volatile DOUBLE x = POW2 (MAX_EXP - 1); /* 2^(MAX_EXP-1) */
620 volatile DOUBLE y = L_(2.0); /* 2^1 */
621 volatile DOUBLE z = /* -(2^MAX_EXP - 2^(MAX_EXP-MANT_BIT)) */
622 - LDEXP (POW2 (MAX_EXP - 1) - POW2 (MAX_EXP - MANT_BIT - 1), 1);
623 volatile DOUBLE result = my_fma (x, y, z);
624 if (!FORGIVE_DOUBLEDOUBLE_BUG)
625 ASSERT (result == POW2 (MAX_EXP - MANT_BIT));
628 volatile DOUBLE x = POW2 (MAX_EXP - 1); /* 2^(MAX_EXP-1) */
629 volatile DOUBLE y = L_(3.0); /* 3 */
630 volatile DOUBLE z = - LDEXP (L_(5.0), MAX_EXP - 3); /* -5*2^(MAX_EXP-3) */
631 volatile DOUBLE result = my_fma (x, y, z);
632 ASSERT (result == LDEXP (L_(7.0), MAX_EXP - 3));