brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.2 KiB · 1e1cfae Raw
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