1 | // RUN: %clang_builtins %s %librt -o %t && %run %t |
2 | |
3 | #define QUAD_PRECISION |
4 | #include "fp_lib.h" |
5 | #include <fenv.h> |
6 | #include <float.h> |
7 | #include <limits.h> |
8 | #include <math.h> |
9 | #include <stdio.h> |
10 | |
11 | #if defined(CRT_HAS_TF_MODE) |
12 | |
13 | int test__compiler_rt_scalbnl(const char *mode, fp_t x, int y) { |
14 | #if defined(__ve__) |
15 | if (fpclassify(x) == FP_SUBNORMAL) |
16 | return 0; |
17 | # endif |
18 | fp_t crt_value = __compiler_rt_scalbnl(x, y); |
19 | fp_t libm_value = scalbnl(x: x, n: y); |
20 | // Consider +/-0 unequal, but disregard the sign/payload of NaN. |
21 | if (toRep(x: crt_value) != toRep(x: libm_value) && |
22 | !(crt_isnan(crt_value) && crt_isnan(libm_value))) { |
23 | // Split expected values into two for printf |
24 | twords x_t, crt_value_t, libm_value_t; |
25 | x_t.all = toRep(x); |
26 | crt_value_t.all = toRep(x: crt_value); |
27 | libm_value_t.all = toRep(x: libm_value); |
28 | printf( |
29 | format: "error: [%s] in __compiler_rt_scalbnl([%llX %llX], %d) = " |
30 | "[%llX %llX] != [%llX %llX]\n" , |
31 | mode, (unsigned long long)x_t.s.high, (unsigned long long)x_t.s.low, y, |
32 | (unsigned long long)crt_value_t.s.high, |
33 | (unsigned long long)crt_value_t.s.low, |
34 | (unsigned long long)libm_value_t.s.high, |
35 | (unsigned long long)libm_value_t.s.low); |
36 | return 1; |
37 | } |
38 | return 0; |
39 | } |
40 | |
41 | fp_t cases[] = { |
42 | -NAN, |
43 | NAN, |
44 | -INFINITY, |
45 | INFINITY, |
46 | -0.0, |
47 | 0.0, |
48 | -1, |
49 | 1, |
50 | -2, |
51 | 2, |
52 | // Since we are comparing the compiler-rt IEEE implementation against libc's |
53 | // long double implementation, this test can only succeed if long double |
54 | // is an IEEE 128-bit floating point number. |
55 | # if defined(CRT_LDBL_IEEE_F128) |
56 | LDBL_TRUE_MIN, |
57 | # endif |
58 | LDBL_MIN, |
59 | LDBL_MAX, |
60 | -1.001, |
61 | 1.001, |
62 | -1.002, |
63 | 1.002, |
64 | 1.e-6, |
65 | -1.e-6, |
66 | TF_C(0x1.0p-16381), |
67 | TF_C(0x1.0p-16382), |
68 | TF_C(0x1.0p-16383), // subnormal |
69 | TF_C(0x1.0p-16384), // subnormal |
70 | }; |
71 | |
72 | int iterate_cases(const char *mode) { |
73 | const unsigned N = sizeof(cases) / sizeof(cases[0]); |
74 | unsigned i; |
75 | for (i = 0; i < N; ++i) { |
76 | int j; |
77 | for (j = -5; j <= 5; ++j) { |
78 | printf(format: "%d, %d\n" , i, j); |
79 | if (test__compiler_rt_scalbnl(mode, x: cases[i], y: j)) |
80 | return 1; |
81 | } |
82 | if (test__compiler_rt_scalbnl(mode, x: cases[i], y: -100000)) |
83 | return 1; |
84 | if (test__compiler_rt_scalbnl(mode, x: cases[i], y: 100000)) |
85 | return 1; |
86 | if (test__compiler_rt_scalbnl(mode, x: cases[i], INT_MIN)) |
87 | return 1; |
88 | if (test__compiler_rt_scalbnl(mode, x: cases[i], INT_MAX)) |
89 | return 1; |
90 | } |
91 | return 0; |
92 | } |
93 | |
94 | int main() { |
95 | if (iterate_cases(mode: "default" )) |
96 | return 1; |
97 | |
98 | // Skip rounding mode tests (fesetround) because compiler-rt's quad-precision |
99 | // multiply also ignores the current rounding mode. |
100 | |
101 | return 0; |
102 | } |
103 | |
104 | #else |
105 | int main() { |
106 | printf("skipped\n" ); |
107 | return 0; |
108 | } |
109 | #endif |
110 | |