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