376 lines · c
1// RUN: %clang_builtins %s %librt -lm -o %t && %run %t2// REQUIRES: librt_has_divtc33// REQUIRES: c99-complex4 5//6// This test should be XFAILed on 32-bit sparc (sparc-target-arch, Issue7// #41838), but that is currently hidden, which caused an XPASS (Issue #72398).8//9#include <stdio.h>10 11#include "int_lib.h"12#include "int_math.h"13#include <complex.h>14#include <math.h>15 16// Returns: the quotient of (a + ib) / (c + id)17#if defined(CRT_HAS_TF_MODE)18 19COMPILER_RT_ABI Qcomplex __divtc3(tf_float __a, tf_float __b, tf_float __c,20 tf_float __d);21 22enum {zero, non_zero, inf, NaN, non_zero_nan};23 24static int classify(Qcomplex x) {25 tf_float real = COMPLEXTF_REAL(x);26 tf_float imag = COMPLEXTF_IMAGINARY(x);27 if (real == 0.0 && imag == 0.0)28 return zero;29 if (crt_isinf(real) || crt_isinf(imag))30 return inf;31 if (crt_isnan(real) && crt_isnan(imag))32 return NaN;33 if (crt_isnan(real)) {34 if (imag == 0.0)35 return NaN;36 return non_zero_nan;37 }38 if (crt_isnan(imag)) {39 if (real == 0.0)40 return NaN;41 return non_zero_nan;42 }43 return non_zero;44}45 46static int test__divtc3(tf_float a, tf_float b, tf_float c, tf_float d) {47 Qcomplex r = __divtc3(a, b, c, d);48 Qcomplex dividend;49 Qcomplex divisor;50 51 COMPLEXTF_REAL(dividend) = a;52 COMPLEXTF_IMAGINARY(dividend) = b;53 COMPLEXTF_REAL(divisor) = c;54 COMPLEXTF_IMAGINARY(divisor) = d;55 56 switch (classify(dividend)) {57 case zero:58 switch (classify(divisor)) {59 case zero:60 if (classify(r) != NaN)61 return 1;62 break;63 case non_zero:64 if (classify(r) != zero)65 return 1;66 break;67 case inf:68 if (classify(r) != zero)69 return 1;70 break;71 case NaN:72 if (classify(r) != NaN)73 return 1;74 break;75 case non_zero_nan:76 if (classify(r) != NaN)77 return 1;78 break;79 }80 break;81 case non_zero:82 switch (classify(divisor)) {83 case zero:84 if (classify(r) != inf)85 return 1;86 break;87 case non_zero:88 if (classify(r) != non_zero)89 return 1;90 {91 tf_float zReal = (a * c + b * d) / (c * c + d * d);92 tf_float zImag = (b * c - a * d) / (c * c + d * d);93 Qcomplex diff =94 __divtc3(COMPLEXTF_REAL(r) - zReal, COMPLEXTF_IMAGINARY(r) - zImag,95 COMPLEXTF_REAL(r), COMPLEXTF_IMAGINARY(r));96 // cabsl(z) == hypotl(creall(z), cimagl(z))97#ifdef CRT_LDBL_128BIT98 if (hypotl(COMPLEXTF_REAL(diff), COMPLEXTF_IMAGINARY(diff)) > 1.e-6)99#else100 // Avoid dependency on __trunctfxf2 for ld80 platforms and use double instead.101 if (hypot(COMPLEXTF_REAL(diff), COMPLEXTF_IMAGINARY(diff)) > 1.e-6)102#endif103 return 1;104 }105 break;106 case inf:107 if (classify(r) != zero)108 return 1;109 break;110 case NaN:111 if (classify(r) != NaN)112 return 1;113 break;114 case non_zero_nan:115 if (classify(r) != NaN)116 return 1;117 break;118 }119 break;120 case inf:121 switch (classify(divisor)) {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 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 case zero:171 if (classify(r) != inf)172 return 1;173 break;174 case non_zero:175 if (classify(r) != NaN)176 return 1;177 break;178 case inf:179 if (classify(r) != NaN)180 return 1;181 break;182 case NaN:183 if (classify(r) != NaN)184 return 1;185 break;186 case non_zero_nan:187 if (classify(r) != NaN)188 return 1;189 break;190 }191 break;192 }193 194 return 0;195}196 197tf_float x[][2] = {{1.e-6, 1.e-6},198 {-1.e-6, 1.e-6},199 {-1.e-6, -1.e-6},200 {1.e-6, -1.e-6},201 202 {1.e+6, 1.e-6},203 {-1.e+6, 1.e-6},204 {-1.e+6, -1.e-6},205 {1.e+6, -1.e-6},206 207 {1.e-6, 1.e+6},208 {-1.e-6, 1.e+6},209 {-1.e-6, -1.e+6},210 {1.e-6, -1.e+6},211 212 {1.e+6, 1.e+6},213 {-1.e+6, 1.e+6},214 {-1.e+6, -1.e+6},215 {1.e+6, -1.e+6},216 217 {NAN, NAN},218 {-INFINITY, NAN},219 {-2, NAN},220 {-1, NAN},221 {-0.5, NAN},222 {-0., NAN},223 {+0., NAN},224 {0.5, NAN},225 {1, NAN},226 {2, NAN},227 {INFINITY, NAN},228 229 {NAN, -INFINITY},230 {-INFINITY, -INFINITY},231 {-2, -INFINITY},232 {-1, -INFINITY},233 {-0.5, -INFINITY},234 {-0., -INFINITY},235 {+0., -INFINITY},236 {0.5, -INFINITY},237 {1, -INFINITY},238 {2, -INFINITY},239 {INFINITY, -INFINITY},240 241 {NAN, -2},242 {-INFINITY, -2},243 {-2, -2},244 {-1, -2},245 {-0.5, -2},246 {-0., -2},247 {+0., -2},248 {0.5, -2},249 {1, -2},250 {2, -2},251 {INFINITY, -2},252 253 {NAN, -1},254 {-INFINITY, -1},255 {-2, -1},256 {-1, -1},257 {-0.5, -1},258 {-0., -1},259 {+0., -1},260 {0.5, -1},261 {1, -1},262 {2, -1},263 {INFINITY, -1},264 265 {NAN, -0.5},266 {-INFINITY, -0.5},267 {-2, -0.5},268 {-1, -0.5},269 {-0.5, -0.5},270 {-0., -0.5},271 {+0., -0.5},272 {0.5, -0.5},273 {1, -0.5},274 {2, -0.5},275 {INFINITY, -0.5},276 277 {NAN, -0.},278 {-INFINITY, -0.},279 {-2, -0.},280 {-1, -0.},281 {-0.5, -0.},282 {-0., -0.},283 {+0., -0.},284 {0.5, -0.},285 {1, -0.},286 {2, -0.},287 {INFINITY, -0.},288 289 {NAN, 0.},290 {-INFINITY, 0.},291 {-2, 0.},292 {-1, 0.},293 {-0.5, 0.},294 {-0., 0.},295 {+0., 0.},296 {0.5, 0.},297 {1, 0.},298 {2, 0.},299 {INFINITY, 0.},300 301 {NAN, 0.5},302 {-INFINITY, 0.5},303 {-2, 0.5},304 {-1, 0.5},305 {-0.5, 0.5},306 {-0., 0.5},307 {+0., 0.5},308 {0.5, 0.5},309 {1, 0.5},310 {2, 0.5},311 {INFINITY, 0.5},312 313 {NAN, 1},314 {-INFINITY, 1},315 {-2, 1},316 {-1, 1},317 {-0.5, 1},318 {-0., 1},319 {+0., 1},320 {0.5, 1},321 {1, 1},322 {2, 1},323 {INFINITY, 1},324 325 {NAN, 2},326 {-INFINITY, 2},327 {-2, 2},328 {-1, 2},329 {-0.5, 2},330 {-0., 2},331 {+0., 2},332 {0.5, 2},333 {1, 2},334 {2, 2},335 {INFINITY, 2},336 337 {NAN, INFINITY},338 {-INFINITY, INFINITY},339 {-2, INFINITY},340 {-1, INFINITY},341 {-0.5, INFINITY},342 {-0., INFINITY},343 {+0., INFINITY},344 {0.5, INFINITY},345 {1, INFINITY},346 {2, INFINITY},347 {INFINITY, INFINITY}348 349};350 351int main() {352 const unsigned N = sizeof(x) / sizeof(x[0]);353 unsigned i, j;354 for (i = 0; i < N; ++i) {355 for (j = 0; j < N; ++j) {356 if (test__divtc3(x[i][0], x[i][1], x[j][0], x[j][1])) {357 fprintf(stderr, "Failed for %g, %g, %g, %g\n", (double)x[i][0],358 (double)x[i][1], (double)x[j][0], (double)x[j][1]);359 return 1;360 }361 }362 }363 364 fprintf(stderr, "No errors found.\n");365 return 0;366}367 368#else369 370int main() {371 printf("skipped\n");372 return 0;373}374 375#endif // CRT_HAS_TF_MODE376