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