1 | //===-- Utility class to test flavors of totalordermag ----------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #ifndef LIBC_TEST_SRC_MATH_SMOKE_TOTALORDERMAGTEST_H |
10 | #define LIBC_TEST_SRC_MATH_SMOKE_TOTALORDERMAGTEST_H |
11 | |
12 | #include "test/UnitTest/FEnvSafeTest.h" |
13 | #include "test/UnitTest/FPMatcher.h" |
14 | #include "test/UnitTest/Test.h" |
15 | |
16 | using LIBC_NAMESPACE::Sign; |
17 | |
18 | template <typename T> |
19 | class TotalOrderMagTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest { |
20 | |
21 | DECLARE_SPECIAL_CONSTANTS(T) |
22 | |
23 | public: |
24 | typedef int (*TotalOrderMagFunc)(const T *, const T *); |
25 | |
26 | bool funcWrapper(TotalOrderMagFunc func, T x, T y) { |
27 | return func(&x, &y) != 0; |
28 | } |
29 | |
30 | void testXLesserThanY(TotalOrderMagFunc func) { |
31 | EXPECT_TRUE(funcWrapper(func, neg_inf, inf)); |
32 | |
33 | EXPECT_TRUE(funcWrapper(func, T(0.0), T(0.1))); |
34 | EXPECT_TRUE(funcWrapper(func, T(0.0), T(123.38))); |
35 | |
36 | EXPECT_FALSE(funcWrapper(func, T(-0.1), T(0.0))); |
37 | EXPECT_FALSE(funcWrapper(func, T(-123.38), T(0.0))); |
38 | |
39 | EXPECT_TRUE(funcWrapper(func, T(-0.1), T(0.1))); |
40 | EXPECT_TRUE(funcWrapper(func, T(-123.38), T(123.38))); |
41 | } |
42 | |
43 | void testXGreaterThanY(TotalOrderMagFunc func) { |
44 | EXPECT_TRUE(funcWrapper(func, inf, neg_inf)); |
45 | |
46 | EXPECT_TRUE(funcWrapper(func, T(0.0), T(-0.1))); |
47 | EXPECT_TRUE(funcWrapper(func, T(0.0), T(-123.38))); |
48 | |
49 | EXPECT_FALSE(funcWrapper(func, T(0.1), T(0.0))); |
50 | EXPECT_FALSE(funcWrapper(func, T(123.38), T(0.0))); |
51 | |
52 | EXPECT_TRUE(funcWrapper(func, T(0.1), T(-0.1))); |
53 | EXPECT_TRUE(funcWrapper(func, T(123.38), T(-123.38))); |
54 | } |
55 | |
56 | void testXEqualToY(TotalOrderMagFunc func) { |
57 | EXPECT_TRUE(funcWrapper(func, inf, inf)); |
58 | EXPECT_TRUE(funcWrapper(func, neg_inf, neg_inf)); |
59 | |
60 | EXPECT_TRUE(funcWrapper(func, T(-0.0), T(0.0))); |
61 | EXPECT_TRUE(funcWrapper(func, T(0.0), T(-0.0))); |
62 | |
63 | EXPECT_TRUE(funcWrapper(func, T(0.0), T(0.0))); |
64 | EXPECT_TRUE(funcWrapper(func, T(-0.0), T(-0.0))); |
65 | EXPECT_TRUE(funcWrapper(func, T(0.1), T(0.1))); |
66 | EXPECT_TRUE(funcWrapper(func, T(-0.1), T(-0.1))); |
67 | EXPECT_TRUE(funcWrapper(func, T(123.38), T(123.38))); |
68 | EXPECT_TRUE(funcWrapper(func, T(-123.38), T(-123.38))); |
69 | } |
70 | |
71 | void testSingleNaN(TotalOrderMagFunc func) { |
72 | EXPECT_FALSE(funcWrapper(func, neg_aNaN, T(0.0))); |
73 | EXPECT_FALSE(funcWrapper(func, neg_aNaN, T(0.1))); |
74 | EXPECT_FALSE(funcWrapper(func, neg_aNaN, T(123.38))); |
75 | |
76 | EXPECT_TRUE(funcWrapper(func, T(0.0), neg_aNaN)); |
77 | EXPECT_TRUE(funcWrapper(func, T(0.1), neg_aNaN)); |
78 | EXPECT_TRUE(funcWrapper(func, T(123.38), neg_aNaN)); |
79 | |
80 | EXPECT_TRUE(funcWrapper(func, T(0.0), aNaN)); |
81 | EXPECT_TRUE(funcWrapper(func, T(0.1), aNaN)); |
82 | EXPECT_TRUE(funcWrapper(func, T(123.38), aNaN)); |
83 | |
84 | EXPECT_FALSE(funcWrapper(func, aNaN, T(0.0))); |
85 | EXPECT_FALSE(funcWrapper(func, aNaN, T(0.1))); |
86 | EXPECT_FALSE(funcWrapper(func, aNaN, T(123.38))); |
87 | } |
88 | |
89 | void testNaNSigns(TotalOrderMagFunc func) { |
90 | EXPECT_TRUE(funcWrapper(func, neg_aNaN, aNaN)); |
91 | EXPECT_FALSE(funcWrapper(func, neg_aNaN, sNaN)); |
92 | EXPECT_TRUE(funcWrapper(func, neg_sNaN, aNaN)); |
93 | EXPECT_TRUE(funcWrapper(func, neg_sNaN, sNaN)); |
94 | |
95 | EXPECT_TRUE(funcWrapper(func, aNaN, neg_aNaN)); |
96 | EXPECT_FALSE(funcWrapper(func, aNaN, neg_sNaN)); |
97 | EXPECT_TRUE(funcWrapper(func, sNaN, neg_aNaN)); |
98 | EXPECT_TRUE(funcWrapper(func, sNaN, neg_sNaN)); |
99 | } |
100 | |
101 | void testQuietVsSignalingNaN(TotalOrderMagFunc func) { |
102 | EXPECT_FALSE(funcWrapper(func, neg_aNaN, neg_sNaN)); |
103 | EXPECT_TRUE(funcWrapper(func, neg_sNaN, neg_aNaN)); |
104 | EXPECT_TRUE(funcWrapper(func, sNaN, aNaN)); |
105 | EXPECT_FALSE(funcWrapper(func, aNaN, sNaN)); |
106 | } |
107 | |
108 | void testNaNPayloads(TotalOrderMagFunc func) { |
109 | T qnan_0x42 = FPBits::quiet_nan(Sign::POS, 0x42).get_val(); |
110 | T neg_qnan_0x42 = FPBits::quiet_nan(Sign::NEG, 0x42).get_val(); |
111 | T snan_0x42 = FPBits::signaling_nan(Sign::POS, 0x42).get_val(); |
112 | T neg_snan_0x42 = FPBits::signaling_nan(Sign::NEG, 0x42).get_val(); |
113 | |
114 | EXPECT_TRUE(funcWrapper(func, aNaN, aNaN)); |
115 | EXPECT_TRUE(funcWrapper(func, sNaN, sNaN)); |
116 | EXPECT_TRUE(funcWrapper(func, aNaN, qnan_0x42)); |
117 | EXPECT_FALSE(funcWrapper(func, sNaN, snan_0x42)); |
118 | EXPECT_FALSE(funcWrapper(func, qnan_0x42, aNaN)); |
119 | EXPECT_TRUE(funcWrapper(func, snan_0x42, sNaN)); |
120 | |
121 | EXPECT_TRUE(funcWrapper(func, neg_aNaN, neg_aNaN)); |
122 | EXPECT_TRUE(funcWrapper(func, neg_sNaN, neg_sNaN)); |
123 | EXPECT_TRUE(funcWrapper(func, neg_aNaN, neg_qnan_0x42)); |
124 | EXPECT_FALSE(funcWrapper(func, neg_sNaN, neg_snan_0x42)); |
125 | EXPECT_FALSE(funcWrapper(func, neg_qnan_0x42, neg_aNaN)); |
126 | EXPECT_TRUE(funcWrapper(func, neg_snan_0x42, neg_sNaN)); |
127 | } |
128 | }; |
129 | |
130 | #define LIST_TOTALORDERMAG_TESTS(T, func) \ |
131 | using LlvmLibcTotalOrderMagTest = TotalOrderMagTestTemplate<T>; \ |
132 | TEST_F(LlvmLibcTotalOrderMagTest, XLesserThanY) { testXLesserThanY(&func); } \ |
133 | TEST_F(LlvmLibcTotalOrderMagTest, XGreaterThanY) { \ |
134 | testXGreaterThanY(&func); \ |
135 | } \ |
136 | TEST_F(LlvmLibcTotalOrderMagTest, XEqualToY) { testXEqualToY(&func); } \ |
137 | TEST_F(LlvmLibcTotalOrderMagTest, SingleNaN) { testSingleNaN(&func); } \ |
138 | TEST_F(LlvmLibcTotalOrderMagTest, NaNSigns) { testNaNSigns(&func); } \ |
139 | TEST_F(LlvmLibcTotalOrderMagTest, QuietVsSignalingNaN) { \ |
140 | testQuietVsSignalingNaN(&func); \ |
141 | } \ |
142 | TEST_F(LlvmLibcTotalOrderMagTest, NaNPayloads) { testNaNPayloads(&func); } |
143 | |
144 | #endif // LIBC_TEST_SRC_MATH_SMOKE_TOTALORDERMAGTEST_H |
145 | |