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