1// RUN: %clang_builtins %s %librt -lm -o %t && %run %t
2//
3// 32-bit: Bug 42493, 64-bit: Bug 42496
4// XFAIL: sparc
5//
6//===-- divtc3_test.c - Test __divtc3 -------------------------------------===//
7//
8// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
9// See https://llvm.org/LICENSE.txt for license information.
10// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
11//
12//===----------------------------------------------------------------------===//
13//
14// This file tests __divtc3 for the compiler_rt library.
15//
16//===----------------------------------------------------------------------===//
17
18#include <stdio.h>
19
20#include "int_lib.h"
21#include <math.h>
22#include <complex.h>
23
24// REQUIRES: c99-complex
25
26// Returns: the quotient of (a + ib) / (c + id)
27
28COMPILER_RT_ABI long double _Complex
29__divtc3(long double __a, long double __b, long double __c, long double __d);
30
31enum {zero, non_zero, inf, NaN, non_zero_nan};
32
33int
34classify(long double _Complex x)
35{
36    if (x == 0)
37        return zero;
38    if (isinf(creall(x)) || isinf(cimagl(x)))
39        return inf;
40    if (isnan(creall(x)) && isnan(cimagl(x)))
41        return NaN;
42    if (isnan(creall(x)))
43    {
44        if (cimagl(x) == 0)
45            return NaN;
46        return non_zero_nan;
47    }
48    if (isnan(cimagl(x)))
49    {
50        if (creall(x) == 0)
51            return NaN;
52        return non_zero_nan;
53    }
54    return non_zero;
55}
56
57int test__divtc3(long double a, long double b, long double c, long double d)
58{
59    long double _Complex r = __divtc3(a, b, c, d);
60//      printf("test__divtc3(%Lf, %Lf, %Lf, %Lf) = %Lf + I%Lf\n",
61//              a, b, c, d, creall(r), cimagl(r));
62
63	long double _Complex dividend;
64	long double _Complex divisor;
65
66	__real__ dividend = a;
67	__imag__ dividend = b;
68	__real__ divisor = c;
69	__imag__ divisor = d;
70
71    switch (classify(dividend))
72    {
73    case zero:
74        switch (classify(divisor))
75        {
76        case zero:
77            if (classify(r) != NaN)
78                return 1;
79            break;
80        case non_zero:
81            if (classify(r) != zero)
82                return 1;
83            break;
84        case inf:
85            if (classify(r) != zero)
86                return 1;
87            break;
88        case NaN:
89            if (classify(r) != NaN)
90                return 1;
91            break;
92        case non_zero_nan:
93            if (classify(r) != NaN)
94                return 1;
95            break;
96        }
97        break;
98    case non_zero:
99        switch (classify(divisor))
100        {
101        case zero:
102            if (classify(r) != inf)
103                return 1;
104            break;
105        case non_zero:
106            if (classify(r) != non_zero)
107                return 1;
108            {
109            long double _Complex z = (a * c + b * d) / (c * c + d * d)
110                                   + (b * c - a * d) / (c * c + d * d) * _Complex_I;
111            if (cabsl((r - z)/r) > 1.e-6)
112                return 1;
113            }
114            break;
115        case inf:
116            if (classify(r) != zero)
117                return 1;
118            break;
119        case NaN:
120            if (classify(r) != NaN)
121                return 1;
122            break;
123        case non_zero_nan:
124            if (classify(r) != NaN)
125                return 1;
126            break;
127        }
128        break;
129    case inf:
130        switch (classify(divisor))
131        {
132        case zero:
133            if (classify(r) != inf)
134                return 1;
135            break;
136        case non_zero:
137            if (classify(r) != inf)
138                return 1;
139            break;
140        case inf:
141            if (classify(r) != NaN)
142                return 1;
143            break;
144        case NaN:
145            if (classify(r) != NaN)
146                return 1;
147            break;
148        case non_zero_nan:
149            if (classify(r) != NaN)
150                return 1;
151            break;
152        }
153        break;
154    case NaN:
155        switch (classify(divisor))
156        {
157        case zero:
158            if (classify(r) != NaN)
159                return 1;
160            break;
161        case non_zero:
162            if (classify(r) != NaN)
163                return 1;
164            break;
165        case inf:
166            if (classify(r) != NaN)
167                return 1;
168            break;
169        case NaN:
170            if (classify(r) != NaN)
171                return 1;
172            break;
173        case non_zero_nan:
174            if (classify(r) != NaN)
175                return 1;
176            break;
177        }
178        break;
179    case non_zero_nan:
180        switch (classify(divisor))
181        {
182        case zero:
183            if (classify(r) != inf)
184                return 1;
185            break;
186        case non_zero:
187            if (classify(r) != NaN)
188                return 1;
189            break;
190        case inf:
191            if (classify(r) != NaN)
192                return 1;
193            break;
194        case NaN:
195            if (classify(r) != NaN)
196                return 1;
197            break;
198        case non_zero_nan:
199            if (classify(r) != NaN)
200                return 1;
201            break;
202        }
203        break;
204    }
205
206    return 0;
207}
208
209long double x[][2] =
210{
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},
215
216    { 1.e+6,  1.e-6},
217    {-1.e+6,  1.e-6},
218    {-1.e+6, -1.e-6},
219    { 1.e+6, -1.e-6},
220
221    { 1.e-6,  1.e+6},
222    {-1.e-6,  1.e+6},
223    {-1.e-6, -1.e+6},
224    { 1.e-6, -1.e+6},
225
226    { 1.e+6,  1.e+6},
227    {-1.e+6,  1.e+6},
228    {-1.e+6, -1.e+6},
229    { 1.e+6, -1.e+6},
230
231    {NAN, NAN},
232    {-INFINITY, NAN},
233    {-2, NAN},
234    {-1, NAN},
235    {-0.5, NAN},
236    {-0., NAN},
237    {+0., NAN},
238    {0.5, NAN},
239    {1, NAN},
240    {2, NAN},
241    {INFINITY, NAN},
242
243    {NAN, -INFINITY},
244    {-INFINITY, -INFINITY},
245    {-2, -INFINITY},
246    {-1, -INFINITY},
247    {-0.5, -INFINITY},
248    {-0., -INFINITY},
249    {+0., -INFINITY},
250    {0.5, -INFINITY},
251    {1, -INFINITY},
252    {2, -INFINITY},
253    {INFINITY, -INFINITY},
254
255    {NAN, -2},
256    {-INFINITY, -2},
257    {-2, -2},
258    {-1, -2},
259    {-0.5, -2},
260    {-0., -2},
261    {+0., -2},
262    {0.5, -2},
263    {1, -2},
264    {2, -2},
265    {INFINITY, -2},
266
267    {NAN, -1},
268    {-INFINITY, -1},
269    {-2, -1},
270    {-1, -1},
271    {-0.5, -1},
272    {-0., -1},
273    {+0., -1},
274    {0.5, -1},
275    {1, -1},
276    {2, -1},
277    {INFINITY, -1},
278
279    {NAN, -0.5},
280    {-INFINITY, -0.5},
281    {-2, -0.5},
282    {-1, -0.5},
283    {-0.5, -0.5},
284    {-0., -0.5},
285    {+0., -0.5},
286    {0.5, -0.5},
287    {1, -0.5},
288    {2, -0.5},
289    {INFINITY, -0.5},
290
291    {NAN, -0.},
292    {-INFINITY, -0.},
293    {-2, -0.},
294    {-1, -0.},
295    {-0.5, -0.},
296    {-0., -0.},
297    {+0., -0.},
298    {0.5, -0.},
299    {1, -0.},
300    {2, -0.},
301    {INFINITY, -0.},
302
303    {NAN, 0.},
304    {-INFINITY, 0.},
305    {-2, 0.},
306    {-1, 0.},
307    {-0.5, 0.},
308    {-0., 0.},
309    {+0., 0.},
310    {0.5, 0.},
311    {1, 0.},
312    {2, 0.},
313    {INFINITY, 0.},
314
315    {NAN, 0.5},
316    {-INFINITY, 0.5},
317    {-2, 0.5},
318    {-1, 0.5},
319    {-0.5, 0.5},
320    {-0., 0.5},
321    {+0., 0.5},
322    {0.5, 0.5},
323    {1, 0.5},
324    {2, 0.5},
325    {INFINITY, 0.5},
326
327    {NAN, 1},
328    {-INFINITY, 1},
329    {-2, 1},
330    {-1, 1},
331    {-0.5, 1},
332    {-0., 1},
333    {+0., 1},
334    {0.5, 1},
335    {1, 1},
336    {2, 1},
337    {INFINITY, 1},
338
339    {NAN, 2},
340    {-INFINITY, 2},
341    {-2, 2},
342    {-1, 2},
343    {-0.5, 2},
344    {-0., 2},
345    {+0., 2},
346    {0.5, 2},
347    {1, 2},
348    {2, 2},
349    {INFINITY, 2},
350
351    {NAN, INFINITY},
352    {-INFINITY, INFINITY},
353    {-2, INFINITY},
354    {-1, INFINITY},
355    {-0.5, INFINITY},
356    {-0., INFINITY},
357    {+0., INFINITY},
358    {0.5, INFINITY},
359    {1, INFINITY},
360    {2, INFINITY},
361    {INFINITY, INFINITY}
362
363};
364
365int main()
366{
367    const unsigned N = sizeof(x) / sizeof(x[0]);
368    unsigned i, j;
369    for (i = 0; i < N; ++i)
370    {
371        for (j = 0; j < N; ++j)
372        {
373            if (test__divtc3(x[i][0], x[i][1], x[j][0], x[j][1]))
374                return 1;
375        }
376    }
377
378//	printf("No errors found.\n");
379    return 0;
380}
381