xref: /llvm-project/compiler-rt/test/builtins/Unit/compiler_rt_scalbnl_test.c (revision d2ce3e9621411f3391def327f89e3a650918989f)
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 
test__compiler_rt_scalbnl(const char * mode,fp_t x,int y)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, y);
20   // Consider +/-0 unequal, but disregard the sign/payload of NaN.
21   if (toRep(crt_value) != toRep(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(crt_value);
27     libm_value_t.all = toRep(libm_value);
28     printf(
29         "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 
iterate_cases(const char * mode)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("%d, %d\n", i, j);
79       if (test__compiler_rt_scalbnl(mode, cases[i], j))
80         return 1;
81     }
82     if (test__compiler_rt_scalbnl(mode, cases[i], -100000))
83       return 1;
84     if (test__compiler_rt_scalbnl(mode, cases[i], 100000))
85       return 1;
86     if (test__compiler_rt_scalbnl(mode, cases[i], INT_MIN))
87       return 1;
88     if (test__compiler_rt_scalbnl(mode, cases[i], INT_MAX))
89       return 1;
90   }
91   return 0;
92 }
93 
main()94 int main() {
95   if (iterate_cases("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
main()105 int main() {
106   printf("skipped\n");
107   return 0;
108 }
109 #endif
110