xref: /llvm-project/compiler-rt/test/builtins/Unit/compiler_rt_logbl_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 "int_lib.h"
6 #include <math.h>
7 #include <stdio.h>
8 
9 #if defined(CRT_HAS_TF_MODE)
10 
test__compiler_rt_logbl(fp_t x)11 int test__compiler_rt_logbl(fp_t x) {
12 #  if defined(__ve__)
13   if (fpclassify(x) == FP_SUBNORMAL)
14     return 0;
15 #  endif
16   fp_t crt_value = __compiler_rt_logbl(x);
17   fp_t libm_value = logbl(x);
18   // Compare the values, considering all NaNs equivalent, as the spec doesn't
19   // specify the NaN signedness/payload.
20   if (crt_value != libm_value &&
21       !(crt_isnan(crt_value) && crt_isnan(libm_value))) {
22     // Split expected values into two for printf
23     twords x_t, crt_value_t, libm_value_t;
24     x_t.all = toRep(x);
25     crt_value_t.all = toRep(crt_value);
26     libm_value_t.all = toRep(libm_value);
27     printf("error: in __compiler_rt_logbl([%llX %llX]) = [%llX %llX] !=  "
28            "[%llX %llX]\n",
29            x_t.s.high, x_t.s.low, crt_value_t.s.high, crt_value_t.s.low,
30            libm_value_t.s.high, libm_value_t.s.low);
31     return 1;
32   }
33   return 0;
34 }
35 
36 fp_t cases[] = {
37     1.e-6, -1.e-6, NAN, -NAN, INFINITY, -INFINITY, -1,
38     -0.0,  0.0,    1,   -2,   2,        -0.5,      0.5,
39 };
40 
main()41 int main() {
42   const unsigned N = sizeof(cases) / sizeof(cases[0]);
43   for (unsigned i = 0; i < N; ++i) {
44     if (test__compiler_rt_logbl(cases[i]))
45       return 1;
46   }
47 
48   // Test a moving 1 bit, especially to handle denormal values.
49   // Test the negation as well.
50   // Since we are comparing the compiler-rt IEEE implementation against libc's
51   // long double implementation, this test can only succeed if long double
52   // is an IEEE 128-bit floating point number (otherwise we will see mismatches
53   // once we reach numbers that cannot be precisely represented in long double
54   // format).
55 #  if defined(CRT_LDBL_IEEE_F128)
56   rep_t x = signBit;
57   int i = 0;
58   while (x) {
59     if (test__compiler_rt_logbl(fromRep(x)))
60       return 1;
61     if (test__compiler_rt_logbl(fromRep(signBit ^ x)))
62       return 1;
63     x >>= 1;
64     printf("l1: %d\n", i++);
65   }
66   // Also try a couple moving ones
67   x = signBit | (signBit >> 1) | (signBit >> 2);
68   while (x) {
69     if (test__compiler_rt_logbl(fromRep(x)))
70       return 1;
71     if (test__compiler_rt_logbl(fromRep(signBit ^ x)))
72       return 1;
73     x >>= 1;
74     printf("l1: %d\n", i++);
75   }
76 #endif
77 
78   return 0;
79 }
80 #else
main()81 int main() {
82   printf("skipped\n");
83   return 0;
84 }
85 #endif
86