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