Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / compiler-rt / test / builtins / Unit / divtc3_test.c
blob9ba4880f4a110270623fdd0057e1a37ca019f327
1 // RUN: %clang_builtins %s %librt -lm -o %t && %run %t
2 // REQUIRES: librt_has_divtc3
3 // REQUIRES: c99-complex
5 //
6 // Bug 42493
7 // XFAIL: sparc-target-arch
8 //
9 #include <stdio.h>
11 #include "int_lib.h"
12 #include "int_math.h"
13 #include <complex.h>
14 #include <math.h>
16 // Returns: the quotient of (a + ib) / (c + id)
18 COMPILER_RT_ABI Qcomplex __divtc3(tf_float __a, tf_float __b, tf_float __c,
19 tf_float __d);
21 enum {zero, non_zero, inf, NaN, non_zero_nan};
23 static int classify(Qcomplex x) {
24 tf_float real = COMPLEXTF_REAL(x);
25 tf_float imag = COMPLEXTF_IMAGINARY(x);
26 if (real == 0.0 && imag == 0.0)
27 return zero;
28 if (crt_isinf(real) || crt_isinf(imag))
29 return inf;
30 if (crt_isnan(real) && crt_isnan(imag))
31 return NaN;
32 if (crt_isnan(real)) {
33 if (imag == 0.0)
34 return NaN;
35 return non_zero_nan;
37 if (crt_isnan(imag)) {
38 if (real == 0.0)
39 return NaN;
40 return non_zero_nan;
42 return non_zero;
45 static int test__divtc3(tf_float a, tf_float b, tf_float c, tf_float d) {
46 Qcomplex r = __divtc3(a, b, c, d);
47 Qcomplex dividend;
48 Qcomplex divisor;
50 COMPLEXTF_REAL(dividend) = a;
51 COMPLEXTF_IMAGINARY(dividend) = b;
52 COMPLEXTF_REAL(divisor) = c;
53 COMPLEXTF_IMAGINARY(divisor) = d;
55 switch (classify(dividend)) {
56 case zero:
57 switch (classify(divisor)) {
58 case zero:
59 if (classify(r) != NaN)
60 return 1;
61 break;
62 case non_zero:
63 if (classify(r) != zero)
64 return 1;
65 break;
66 case inf:
67 if (classify(r) != zero)
68 return 1;
69 break;
70 case NaN:
71 if (classify(r) != NaN)
72 return 1;
73 break;
74 case non_zero_nan:
75 if (classify(r) != NaN)
76 return 1;
77 break;
79 break;
80 case non_zero:
81 switch (classify(divisor)) {
82 case zero:
83 if (classify(r) != inf)
84 return 1;
85 break;
86 case non_zero:
87 if (classify(r) != non_zero)
88 return 1;
90 tf_float zReal = (a * c + b * d) / (c * c + d * d);
91 tf_float zImag = (b * c - a * d) / (c * c + d * d);
92 Qcomplex diff =
93 __divtc3(COMPLEXTF_REAL(r) - zReal, COMPLEXTF_IMAGINARY(r) - zImag,
94 COMPLEXTF_REAL(r), COMPLEXTF_IMAGINARY(r));
95 // cabsl(z) == hypotl(creall(z), cimagl(z))
96 #ifdef CRT_LDBL_128BIT
97 if (hypotl(COMPLEXTF_REAL(diff), COMPLEXTF_IMAGINARY(diff)) > 1.e-6)
98 #else
99 // Avoid dependency on __trunctfxf2 for ld80 platforms and use double instead.
100 if (hypot(COMPLEXTF_REAL(diff), COMPLEXTF_IMAGINARY(diff)) > 1.e-6)
101 #endif
102 return 1;
104 break;
105 case inf:
106 if (classify(r) != zero)
107 return 1;
108 break;
109 case NaN:
110 if (classify(r) != NaN)
111 return 1;
112 break;
113 case non_zero_nan:
114 if (classify(r) != NaN)
115 return 1;
116 break;
118 break;
119 case inf:
120 switch (classify(divisor)) {
121 case zero:
122 if (classify(r) != inf)
123 return 1;
124 break;
125 case non_zero:
126 if (classify(r) != inf)
127 return 1;
128 break;
129 case inf:
130 if (classify(r) != NaN)
131 return 1;
132 break;
133 case NaN:
134 if (classify(r) != NaN)
135 return 1;
136 break;
137 case non_zero_nan:
138 if (classify(r) != NaN)
139 return 1;
140 break;
142 break;
143 case NaN:
144 switch (classify(divisor)) {
145 case zero:
146 if (classify(r) != NaN)
147 return 1;
148 break;
149 case non_zero:
150 if (classify(r) != NaN)
151 return 1;
152 break;
153 case inf:
154 if (classify(r) != NaN)
155 return 1;
156 break;
157 case NaN:
158 if (classify(r) != NaN)
159 return 1;
160 break;
161 case non_zero_nan:
162 if (classify(r) != NaN)
163 return 1;
164 break;
166 break;
167 case non_zero_nan:
168 switch (classify(divisor)) {
169 case zero:
170 if (classify(r) != inf)
171 return 1;
172 break;
173 case non_zero:
174 if (classify(r) != NaN)
175 return 1;
176 break;
177 case inf:
178 if (classify(r) != NaN)
179 return 1;
180 break;
181 case NaN:
182 if (classify(r) != NaN)
183 return 1;
184 break;
185 case non_zero_nan:
186 if (classify(r) != NaN)
187 return 1;
188 break;
190 break;
193 return 0;
196 tf_float x[][2] = {{1.e-6, 1.e-6},
197 {-1.e-6, 1.e-6},
198 {-1.e-6, -1.e-6},
199 {1.e-6, -1.e-6},
201 {1.e+6, 1.e-6},
202 {-1.e+6, 1.e-6},
203 {-1.e+6, -1.e-6},
204 {1.e+6, -1.e-6},
206 {1.e-6, 1.e+6},
207 {-1.e-6, 1.e+6},
208 {-1.e-6, -1.e+6},
209 {1.e-6, -1.e+6},
211 {1.e+6, 1.e+6},
212 {-1.e+6, 1.e+6},
213 {-1.e+6, -1.e+6},
214 {1.e+6, -1.e+6},
216 {NAN, NAN},
217 {-INFINITY, NAN},
218 {-2, NAN},
219 {-1, NAN},
220 {-0.5, NAN},
221 {-0., NAN},
222 {+0., NAN},
223 {0.5, NAN},
224 {1, NAN},
225 {2, NAN},
226 {INFINITY, NAN},
228 {NAN, -INFINITY},
229 {-INFINITY, -INFINITY},
230 {-2, -INFINITY},
231 {-1, -INFINITY},
232 {-0.5, -INFINITY},
233 {-0., -INFINITY},
234 {+0., -INFINITY},
235 {0.5, -INFINITY},
236 {1, -INFINITY},
237 {2, -INFINITY},
238 {INFINITY, -INFINITY},
240 {NAN, -2},
241 {-INFINITY, -2},
242 {-2, -2},
243 {-1, -2},
244 {-0.5, -2},
245 {-0., -2},
246 {+0., -2},
247 {0.5, -2},
248 {1, -2},
249 {2, -2},
250 {INFINITY, -2},
252 {NAN, -1},
253 {-INFINITY, -1},
254 {-2, -1},
255 {-1, -1},
256 {-0.5, -1},
257 {-0., -1},
258 {+0., -1},
259 {0.5, -1},
260 {1, -1},
261 {2, -1},
262 {INFINITY, -1},
264 {NAN, -0.5},
265 {-INFINITY, -0.5},
266 {-2, -0.5},
267 {-1, -0.5},
268 {-0.5, -0.5},
269 {-0., -0.5},
270 {+0., -0.5},
271 {0.5, -0.5},
272 {1, -0.5},
273 {2, -0.5},
274 {INFINITY, -0.5},
276 {NAN, -0.},
277 {-INFINITY, -0.},
278 {-2, -0.},
279 {-1, -0.},
280 {-0.5, -0.},
281 {-0., -0.},
282 {+0., -0.},
283 {0.5, -0.},
284 {1, -0.},
285 {2, -0.},
286 {INFINITY, -0.},
288 {NAN, 0.},
289 {-INFINITY, 0.},
290 {-2, 0.},
291 {-1, 0.},
292 {-0.5, 0.},
293 {-0., 0.},
294 {+0., 0.},
295 {0.5, 0.},
296 {1, 0.},
297 {2, 0.},
298 {INFINITY, 0.},
300 {NAN, 0.5},
301 {-INFINITY, 0.5},
302 {-2, 0.5},
303 {-1, 0.5},
304 {-0.5, 0.5},
305 {-0., 0.5},
306 {+0., 0.5},
307 {0.5, 0.5},
308 {1, 0.5},
309 {2, 0.5},
310 {INFINITY, 0.5},
312 {NAN, 1},
313 {-INFINITY, 1},
314 {-2, 1},
315 {-1, 1},
316 {-0.5, 1},
317 {-0., 1},
318 {+0., 1},
319 {0.5, 1},
320 {1, 1},
321 {2, 1},
322 {INFINITY, 1},
324 {NAN, 2},
325 {-INFINITY, 2},
326 {-2, 2},
327 {-1, 2},
328 {-0.5, 2},
329 {-0., 2},
330 {+0., 2},
331 {0.5, 2},
332 {1, 2},
333 {2, 2},
334 {INFINITY, 2},
336 {NAN, INFINITY},
337 {-INFINITY, INFINITY},
338 {-2, INFINITY},
339 {-1, INFINITY},
340 {-0.5, INFINITY},
341 {-0., INFINITY},
342 {+0., INFINITY},
343 {0.5, INFINITY},
344 {1, INFINITY},
345 {2, INFINITY},
346 {INFINITY, INFINITY}
350 int main() {
351 const unsigned N = sizeof(x) / sizeof(x[0]);
352 unsigned i, j;
353 for (i = 0; i < N; ++i) {
354 for (j = 0; j < N; ++j) {
355 if (test__divtc3(x[i][0], x[i][1], x[j][0], x[j][1])) {
356 fprintf(stderr, "Failed for %g, %g, %g, %g\n", (double)x[i][0],
357 (double)x[i][1], (double)x[j][0], (double)x[j][1]);
358 return 1;
363 fprintf(stderr, "No errors found.\n");
364 return 0;