1 /* Test of fused multiply-add.
2 Copyright (C) 2011-2021 Free Software Foundation, Inc.
3
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.
8
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.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
16
17 /* Written by Bruno Haible <bruno@clisp.org>, 2011. */
18
19 static void
test_function(DOUBLE (* my_fma)(DOUBLE,DOUBLE,DOUBLE))20 test_function (DOUBLE (*my_fma) (DOUBLE, DOUBLE, DOUBLE))
21 {
22 volatile DOUBLE x;
23 volatile DOUBLE y;
24 volatile DOUBLE z;
25 volatile DOUBLE result;
26 volatile DOUBLE expected;
27
28 /* Combinations with NaN. */
29 /* "If x or y are NaN, a NaN shall be returned." */
30 {
31 x = NAN;
32 y = NAN;
33 z = NAN;
34 result = my_fma (x, y, z);
35 ASSERT (ISNAN (result));
36 }
37 {
38 x = NAN;
39 y = NAN;
40 z = L_(1.0);
41 result = my_fma (x, y, z);
42 ASSERT (ISNAN (result));
43 }
44 {
45 x = NAN;
46 y = L_(0.0);
47 z = NAN;
48 result = my_fma (x, y, z);
49 ASSERT (ISNAN (result));
50 }
51 {
52 x = NAN;
53 y = L_(0.0);
54 z = L_(1.0);
55 result = my_fma (x, y, z);
56 ASSERT (ISNAN (result));
57 }
58 {
59 x = L_(0.0);
60 y = NAN;
61 z = NAN;
62 result = my_fma (x, y, z);
63 ASSERT (ISNAN (result));
64 }
65 {
66 x = L_(0.0);
67 y = NAN;
68 z = L_(1.0);
69 result = my_fma (x, y, z);
70 ASSERT (ISNAN (result));
71 }
72 /* "If x*y is not 0*Inf nor Inf*0 and z is a NaN, a NaN shall be returned." */
73 {
74 x = L_(3.0);
75 y = - L_(2.0);
76 z = NAN;
77 result = my_fma (x, y, z);
78 ASSERT (ISNAN (result));
79 }
80 /* "If one of x and y is infinite, the other is zero, and z is a NaN, a NaN
81 shall be returned and a domain error may occur." */
82 {
83 x = INFINITY;
84 y = L_(0.0);
85 z = NAN;
86 result = my_fma (x, y, z);
87 ASSERT (ISNAN (result));
88 }
89 {
90 x = L_(0.0);
91 y = INFINITY;
92 z = NAN;
93 result = my_fma (x, y, z);
94 ASSERT (ISNAN (result));
95 }
96
97 /* Combinations with Infinity. */
98 /* "If x multiplied by y is an exact infinity and z is also an infinity but
99 with the opposite sign, a domain error shall occur, and either a NaN
100 (if supported), or an implementation-defined value shall be returned." */
101 {
102 x = INFINITY;
103 y = L_(3.0);
104 z = - INFINITY;
105 result = my_fma (x, y, z);
106 ASSERT (ISNAN (result));
107 }
108 {
109 x = INFINITY;
110 y = - L_(3.0);
111 z = INFINITY;
112 result = my_fma (x, y, z);
113 ASSERT (ISNAN (result));
114 }
115 {
116 x = L_(3.0);
117 y = INFINITY;
118 z = - INFINITY;
119 result = my_fma (x, y, z);
120 ASSERT (ISNAN (result));
121 }
122 {
123 x = - L_(3.0);
124 y = INFINITY;
125 z = INFINITY;
126 result = my_fma (x, y, z);
127 ASSERT (ISNAN (result));
128 }
129 /* "If one of x and y is infinite, the other is zero, and z is not a NaN, a
130 domain error shall occur, and either a NaN (if supported), or an
131 implementation-defined value shall be returned." */
132 {
133 x = INFINITY;
134 y = L_(0.0);
135 z = L_(5.0);
136 result = my_fma (x, y, z);
137 ASSERT (ISNAN (result));
138 }
139 {
140 x = L_(0.0);
141 y = INFINITY;
142 z = L_(5.0);
143 result = my_fma (x, y, z);
144 ASSERT (ISNAN (result));
145 }
146 /* Infinite results. */
147 {
148 x = - L_(2.0);
149 y = L_(3.0);
150 z = INFINITY;
151 result = my_fma (x, y, z);
152 expected = INFINITY;
153 ASSERT (result == expected);
154 }
155 {
156 x = INFINITY;
157 y = L_(3.0);
158 z = INFINITY;
159 result = my_fma (x, y, z);
160 expected = INFINITY;
161 ASSERT (result == expected);
162 }
163 {
164 x = INFINITY;
165 y = - L_(3.0);
166 z = - INFINITY;
167 result = my_fma (x, y, z);
168 expected = - INFINITY;
169 ASSERT (result == expected);
170 }
171 {
172 x = L_(3.0);
173 y = INFINITY;
174 z = INFINITY;
175 result = my_fma (x, y, z);
176 expected = INFINITY;
177 ASSERT (result == expected);
178 }
179 {
180 x = - L_(3.0);
181 y = INFINITY;
182 z = - INFINITY;
183 result = my_fma (x, y, z);
184 expected = - INFINITY;
185 ASSERT (result == expected);
186 }
187
188 /* Combinations with zero. */
189 {
190 x = L_(0.0);
191 y = L_(3.0);
192 z = L_(11.0);
193 result = my_fma (x, y, z);
194 expected = L_(11.0);
195 ASSERT (result == expected);
196 }
197 {
198 x = L_(3.0);
199 y = L_(0.0);
200 z = L_(11.0);
201 result = my_fma (x, y, z);
202 expected = L_(11.0);
203 ASSERT (result == expected);
204 }
205 {
206 x = L_(3.0);
207 y = L_(4.0);
208 z = L_(0.0);
209 result = my_fma (x, y, z);
210 expected = L_(12.0);
211 ASSERT (result == expected);
212 }
213 }
214