375 lines · c
1// RUN: %clang_builtins %s %librt -lm -o %t && %run %t2// REQUIRES: librt_has_divxc33// REQUIRES: x86-target-arch4// UNSUPPORTED: target=powerpc64{{.*}}5// UNSUPPORTED: target=mips{{.*}}6// REQUIRES: c99-complex7 8#if !_ARCH_PPC9 10#include "int_lib.h"11#include <math.h>12#include <complex.h>13#include <stdio.h>14 15 16// Returns: the quotient of (a + ib) / (c + id)17 18COMPILER_RT_ABI long double _Complex19__divxc3(long double __a, long double __b, long double __c, long double __d);20 21enum {zero, non_zero, inf, NaN, non_zero_nan};22 23int24classify(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__divxc3(long double a, long double b, long double c, long double d)48{49 long double _Complex r = __divxc3(a, b, c, d);50// printf("test__divxc3(%Lf, %Lf, %Lf, %Lf) = %Lf + I%Lf\n",51// a, b, c, d, creall(r), cimagl(r));52 long double _Complex dividend;53 long double _Complex divisor;54 55 __real__ dividend = a;56 __imag__ dividend = b;57 __real__ divisor = c;58 __imag__ divisor = d;59 60 switch (classify(dividend))61 {62 case zero:63 switch (classify(divisor))64 {65 case zero:66 if (classify(r) != NaN)67 return 1;68 break;69 case non_zero:70 if (classify(r) != zero)71 return 1;72 break;73 case inf:74 if (classify(r) != zero)75 return 1;76 break;77 case NaN:78 if (classify(r) != NaN)79 return 1;80 break;81 case non_zero_nan:82 if (classify(r) != NaN)83 return 1;84 break;85 }86 break;87 case non_zero:88 switch (classify(divisor))89 {90 case zero:91 if (classify(r) != inf)92 return 1;93 break;94 case non_zero:95 if (classify(r) != non_zero)96 return 1;97 {98 long double _Complex z = (a * c + b * d) / (c * c + d * d)99 + (b * c - a * d) / (c * c + d * d) * _Complex_I;100 if (cabs((r - z)/r) > 1.e-6)101 return 1;102 }103 break;104 case inf:105 if (classify(r) != zero)106 return 1;107 break;108 case NaN:109 if (classify(r) != NaN)110 return 1;111 break;112 case non_zero_nan:113 if (classify(r) != NaN)114 return 1;115 break;116 }117 break;118 case inf:119 switch (classify(divisor))120 {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;141 }142 break;143 case NaN:144 switch (classify(divisor))145 {146 case zero:147 if (classify(r) != NaN)148 return 1;149 break;150 case non_zero:151 if (classify(r) != NaN)152 return 1;153 break;154 case inf:155 if (classify(r) != NaN)156 return 1;157 break;158 case NaN:159 if (classify(r) != NaN)160 return 1;161 break;162 case non_zero_nan:163 if (classify(r) != NaN)164 return 1;165 break;166 }167 break;168 case non_zero_nan:169 switch (classify(divisor))170 {171 case zero:172 if (classify(r) != inf)173 return 1;174 break;175 case non_zero:176 if (classify(r) != NaN)177 return 1;178 break;179 case inf:180 if (classify(r) != NaN)181 return 1;182 break;183 case NaN:184 if (classify(r) != NaN)185 return 1;186 break;187 case non_zero_nan:188 if (classify(r) != NaN)189 return 1;190 break;191 }192 break;193 }194 195 return 0;196}197 198long double x[][2] =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 { 1.e+6, 1.e+6},216 {-1.e+6, 1.e+6},217 {-1.e+6, -1.e+6},218 { 1.e+6, -1.e+6},219 220 {NAN, NAN},221 {-INFINITY, NAN},222 {-2, NAN},223 {-1, NAN},224 {-0.5, NAN},225 {-0., NAN},226 {+0., NAN},227 {0.5, NAN},228 {1, NAN},229 {2, NAN},230 {INFINITY, NAN},231 232 {NAN, -INFINITY},233 {-INFINITY, -INFINITY},234 {-2, -INFINITY},235 {-1, -INFINITY},236 {-0.5, -INFINITY},237 {-0., -INFINITY},238 {+0., -INFINITY},239 {0.5, -INFINITY},240 {1, -INFINITY},241 {2, -INFINITY},242 {INFINITY, -INFINITY},243 244 {NAN, -2},245 {-INFINITY, -2},246 {-2, -2},247 {-1, -2},248 {-0.5, -2},249 {-0., -2},250 {+0., -2},251 {0.5, -2},252 {1, -2},253 {2, -2},254 {INFINITY, -2},255 256 {NAN, -1},257 {-INFINITY, -1},258 {-2, -1},259 {-1, -1},260 {-0.5, -1},261 {-0., -1},262 {+0., -1},263 {0.5, -1},264 {1, -1},265 {2, -1},266 {INFINITY, -1},267 268 {NAN, -0.5},269 {-INFINITY, -0.5},270 {-2, -0.5},271 {-1, -0.5},272 {-0.5, -0.5},273 {-0., -0.5},274 {+0., -0.5},275 {0.5, -0.5},276 {1, -0.5},277 {2, -0.5},278 {INFINITY, -0.5},279 280 {NAN, -0.},281 {-INFINITY, -0.},282 {-2, -0.},283 {-1, -0.},284 {-0.5, -0.},285 {-0., -0.},286 {+0., -0.},287 {0.5, -0.},288 {1, -0.},289 {2, -0.},290 {INFINITY, -0.},291 292 {NAN, 0.},293 {-INFINITY, 0.},294 {-2, 0.},295 {-1, 0.},296 {-0.5, 0.},297 {-0., 0.},298 {+0., 0.},299 {0.5, 0.},300 {1, 0.},301 {2, 0.},302 {INFINITY, 0.},303 304 {NAN, 0.5},305 {-INFINITY, 0.5},306 {-2, 0.5},307 {-1, 0.5},308 {-0.5, 0.5},309 {-0., 0.5},310 {+0., 0.5},311 {0.5, 0.5},312 {1, 0.5},313 {2, 0.5},314 {INFINITY, 0.5},315 316 {NAN, 1},317 {-INFINITY, 1},318 {-2, 1},319 {-1, 1},320 {-0.5, 1},321 {-0., 1},322 {+0., 1},323 {0.5, 1},324 {1, 1},325 {2, 1},326 {INFINITY, 1},327 328 {NAN, 2},329 {-INFINITY, 2},330 {-2, 2},331 {-1, 2},332 {-0.5, 2},333 {-0., 2},334 {+0., 2},335 {0.5, 2},336 {1, 2},337 {2, 2},338 {INFINITY, 2},339 340 {NAN, INFINITY},341 {-INFINITY, INFINITY},342 {-2, INFINITY},343 {-1, INFINITY},344 {-0.5, INFINITY},345 {-0., INFINITY},346 {+0., INFINITY},347 {0.5, INFINITY},348 {1, INFINITY},349 {2, INFINITY},350 {INFINITY, INFINITY}351 352};353 354#endif355 356int main()357{358#if !_ARCH_PPC359 const unsigned N = sizeof(x) / sizeof(x[0]);360 unsigned i, j;361 for (i = 0; i < N; ++i)362 {363 for (j = 0; j < N; ++j)364 {365 if (test__divxc3(x[i][0], x[i][1], x[j][0], x[j][1]))366 return 1;367 }368 }369 370#else371 printf("skipped\n");372#endif373 return 0;374}375