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
18COMPILER_RT_ABI long double _Complex
19__divtc3(long double __a, long double __b, long double __c, long double __d);
20
21enum {zero, non_zero, inf, NaN, non_zero_nan};
22
23int
24classify(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
47int 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
199long 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
355int 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