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