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