xref: /llvm-project/compiler-rt/test/builtins/Unit/trunctfxf2_test.c (revision d2ce3e9621411f3391def327f89e3a650918989f)
1 // RUN: %clang_builtins %s %librt -o %t && %run %t
2 // REQUIRES: librt_has_trunctfxf2
3 
4 #include "int_lib.h"
5 #include <stdio.h>
6 
7 #if __LDBL_MANT_DIG__ == 64 && defined(__x86_64__) &&                          \
8     (defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__))
9 
10 #include "fp_test.h"
11 
12 COMPILER_RT_ABI long double __trunctfxf2(tf_float a);
13 
test__trunctfxf2(tf_float a,uint64_t expectedHi,uint64_t expectedLo)14 int test__trunctfxf2(tf_float a, uint64_t expectedHi, uint64_t expectedLo) {
15   long double x = __trunctfxf2(a);
16   int ret = compareResultF80(x, expectedHi, expectedLo);
17   ;
18   if (ret) {
19     printf("error in __trunctfxf2(%.20Lf) = %.20Lf, "
20            "expected %.20Lf\n",
21            a, x, fromRep128(expectedHi, expectedLo));
22   }
23   return ret;
24 }
25 
26 char assumption_1[sizeof(long double) * CHAR_BIT == 128] = {0};
27 
28 #endif
29 
main()30 int main() {
31 #if __LDBL_MANT_DIG__ == 64 && defined(__x86_64__) &&                          \
32     (defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__))
33   // qNaN
34   if (test__trunctfxf2(makeQNaN128(), UINT64_C(0x7FFF),
35                        UINT64_C(0xC000000000000000)))
36     return 1;
37   // NaN
38   if (test__trunctfxf2(makeNaN128(UINT64_C(0x810000000000)), UINT64_C(0x7FFF),
39                        UINT64_C(0xC080000000000000)))
40     return 1;
41   // inf
42   if (test__trunctfxf2(makeInf128(), UINT64_C(0x7FFF),
43                        UINT64_C(0x8000000000000000)))
44     return 1;
45   // zero
46   if (test__trunctfxf2(0.0Q, UINT64_C(0x0), UINT64_C(0x0)))
47     return 1;
48   if (test__trunctfxf2(0x1.af23456789bbaaab347645365cdep+5L, UINT64_C(0x4004),
49                        UINT64_C(0xd791a2b3c4ddd556)))
50     return 1;
51   if (test__trunctfxf2(0x1.dedafcff354b6ae9758763545432p-9L, UINT64_C(0x3ff6),
52                        UINT64_C(0xef6d7e7f9aa5b575)))
53     return 1;
54   if (test__trunctfxf2(0x1.2f34dd5f437e849b4baab754cdefp+4534L,
55                        UINT64_C(0x51b5), UINT64_C(0x979a6eafa1bf424e)))
56     return 1;
57   if (test__trunctfxf2(0x1.edcbff8ad76ab5bf46463233214fp-435L, UINT64_C(0x3e4c),
58                        UINT64_C(0xf6e5ffc56bb55ae0)))
59     return 1;
60 
61   // Test rounding near halfway.
62   tf_float halfwayPlus =
63       fromRep128(UINT64_C(0x7ffa000000000000),
64                  ((UINT64_C(1) << (112 - 63 - 1)) + UINT64_C(1)));
65   if (test__trunctfxf2(halfwayPlus, UINT64_C(0x7ffa),
66                        UINT64_C(0x8000000000000001)))
67     return 1;
68   tf_float halfwayExactOdd = fromRep128(
69       UINT64_C(0x7ffa000000000000),
70       ((UINT64_C(1) << (112 - 63)) + (UINT64_C(1) << (112 - 63 - 1))));
71   if (test__trunctfxf2(halfwayExactOdd, UINT64_C(0x7ffa),
72                        UINT64_C(0x8000000000000002)))
73     return 1;
74   tf_float halfwayExactEven =
75       fromRep128(UINT64_C(0x7ffa000000000000), (UINT64_C(1) << (112 - 63 - 1)));
76   if (test__trunctfxf2(halfwayExactEven, UINT64_C(0x7ffa),
77                        UINT64_C(0x8000000000000000)))
78     return 1;
79   tf_float halfwayRoundingWillChangeExponent =
80       fromRep128(UINT64_C(0x7ffaffffffffffff), UINT64_C(0xffff000000000001));
81   if (test__trunctfxf2(halfwayRoundingWillChangeExponent, UINT64_C(0x7ffb),
82                        UINT64_C(0x8000000000000000)))
83     return 1;
84 
85   // denormal number
86   if (test__trunctfxf2(1e-4932Q, UINT64_C(0), UINT64_C(0x261247c8f29357f0)))
87     return 1;
88   // denormal number
89   if (test__trunctfxf2(2e-4932Q, UINT64_C(0), UINT64_C(0x4c248f91e526afe0)))
90     return 1;
91 
92 #else
93   printf("skipped\n");
94 
95 #endif
96   return 0;
97 }
98