xref: /aosp_15_r20/external/llvm-libc/test/src/math/smoke/TotalOrderTest.h (revision 71db0c75aadcf003ffe3238005f61d7618a3fead)
1 //===-- Utility class to test different flavors of totalorder ---*- 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_TOTALORDERTEST_H
10 #define LIBC_TEST_SRC_MATH_SMOKE_TOTALORDERTEST_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 TotalOrderTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest {
20 
21   DECLARE_SPECIAL_CONSTANTS(T)
22 
23 public:
24   typedef int (*TotalOrderFunc)(const T *, const T *);
25 
funcWrapper(TotalOrderFunc func,T x,T y)26   bool funcWrapper(TotalOrderFunc func, T x, T y) { return func(&x, &y) != 0; }
27 
testXLesserThanY(TotalOrderFunc func)28   void testXLesserThanY(TotalOrderFunc func) {
29     EXPECT_TRUE(funcWrapper(func, neg_inf, inf));
30 
31     EXPECT_TRUE(funcWrapper(func, T(0.0), T(0.1)));
32     EXPECT_TRUE(funcWrapper(func, T(0.0), T(123.38)));
33 
34     EXPECT_TRUE(funcWrapper(func, T(-0.1), T(0.0)));
35     EXPECT_TRUE(funcWrapper(func, T(-123.38), T(0.0)));
36 
37     EXPECT_TRUE(funcWrapper(func, T(-0.1), T(0.1)));
38     EXPECT_TRUE(funcWrapper(func, T(-123.38), T(123.38)));
39   }
40 
testXGreaterThanY(TotalOrderFunc func)41   void testXGreaterThanY(TotalOrderFunc func) {
42     EXPECT_FALSE(funcWrapper(func, inf, neg_inf));
43 
44     EXPECT_FALSE(funcWrapper(func, T(0.0), T(-0.1)));
45     EXPECT_FALSE(funcWrapper(func, T(0.0), T(-123.38)));
46 
47     EXPECT_FALSE(funcWrapper(func, T(0.1), T(0.0)));
48     EXPECT_FALSE(funcWrapper(func, T(123.38), T(0.0)));
49 
50     EXPECT_FALSE(funcWrapper(func, T(0.1), T(-0.1)));
51     EXPECT_FALSE(funcWrapper(func, T(123.38), T(-123.38)));
52   }
53 
testXEqualToY(TotalOrderFunc func)54   void testXEqualToY(TotalOrderFunc func) {
55     EXPECT_TRUE(funcWrapper(func, inf, inf));
56     EXPECT_TRUE(funcWrapper(func, neg_inf, neg_inf));
57 
58     EXPECT_TRUE(funcWrapper(func, T(-0.0), T(0.0)));
59     EXPECT_FALSE(funcWrapper(func, T(0.0), T(-0.0)));
60 
61     EXPECT_TRUE(funcWrapper(func, T(0.0), T(0.0)));
62     EXPECT_TRUE(funcWrapper(func, T(-0.0), T(-0.0)));
63     EXPECT_TRUE(funcWrapper(func, T(0.1), T(0.1)));
64     EXPECT_TRUE(funcWrapper(func, T(-0.1), T(-0.1)));
65     EXPECT_TRUE(funcWrapper(func, T(123.38), T(123.38)));
66     EXPECT_TRUE(funcWrapper(func, T(-123.38), T(-123.38)));
67   }
68 
testSingleNaN(TotalOrderFunc func)69   void testSingleNaN(TotalOrderFunc func) {
70     EXPECT_TRUE(funcWrapper(func, neg_aNaN, T(0.0)));
71     EXPECT_TRUE(funcWrapper(func, neg_aNaN, T(0.1)));
72     EXPECT_TRUE(funcWrapper(func, neg_aNaN, T(123.38)));
73 
74     EXPECT_FALSE(funcWrapper(func, T(0.0), neg_aNaN));
75     EXPECT_FALSE(funcWrapper(func, T(0.1), neg_aNaN));
76     EXPECT_FALSE(funcWrapper(func, T(123.38), neg_aNaN));
77 
78     EXPECT_TRUE(funcWrapper(func, T(0.0), aNaN));
79     EXPECT_TRUE(funcWrapper(func, T(0.1), aNaN));
80     EXPECT_TRUE(funcWrapper(func, T(123.38), aNaN));
81 
82     EXPECT_FALSE(funcWrapper(func, aNaN, T(0.0)));
83     EXPECT_FALSE(funcWrapper(func, aNaN, T(0.1)));
84     EXPECT_FALSE(funcWrapper(func, aNaN, T(123.38)));
85   }
86 
testNaNSigns(TotalOrderFunc func)87   void testNaNSigns(TotalOrderFunc func) {
88     EXPECT_TRUE(funcWrapper(func, neg_aNaN, aNaN));
89     EXPECT_TRUE(funcWrapper(func, neg_aNaN, sNaN));
90     EXPECT_TRUE(funcWrapper(func, neg_sNaN, aNaN));
91     EXPECT_TRUE(funcWrapper(func, neg_sNaN, sNaN));
92 
93     EXPECT_FALSE(funcWrapper(func, aNaN, neg_aNaN));
94     EXPECT_FALSE(funcWrapper(func, aNaN, neg_sNaN));
95     EXPECT_FALSE(funcWrapper(func, sNaN, neg_aNaN));
96     EXPECT_FALSE(funcWrapper(func, sNaN, neg_sNaN));
97   }
98 
testQuietVsSignalingNaN(TotalOrderFunc func)99   void testQuietVsSignalingNaN(TotalOrderFunc func) {
100     EXPECT_TRUE(funcWrapper(func, neg_aNaN, neg_sNaN));
101     EXPECT_FALSE(funcWrapper(func, neg_sNaN, neg_aNaN));
102     EXPECT_TRUE(funcWrapper(func, sNaN, aNaN));
103     EXPECT_FALSE(funcWrapper(func, aNaN, sNaN));
104   }
105 
testNaNPayloads(TotalOrderFunc func)106   void testNaNPayloads(TotalOrderFunc func) {
107     T qnan_0x42 = FPBits::quiet_nan(Sign::POS, 0x42).get_val();
108     T neg_qnan_0x42 = FPBits::quiet_nan(Sign::NEG, 0x42).get_val();
109     T snan_0x42 = FPBits::signaling_nan(Sign::POS, 0x42).get_val();
110     T neg_snan_0x42 = FPBits::signaling_nan(Sign::NEG, 0x42).get_val();
111 
112     EXPECT_TRUE(funcWrapper(func, aNaN, aNaN));
113     EXPECT_TRUE(funcWrapper(func, sNaN, sNaN));
114     EXPECT_TRUE(funcWrapper(func, aNaN, qnan_0x42));
115     EXPECT_FALSE(funcWrapper(func, sNaN, snan_0x42));
116     EXPECT_FALSE(funcWrapper(func, qnan_0x42, aNaN));
117     EXPECT_TRUE(funcWrapper(func, snan_0x42, sNaN));
118 
119     EXPECT_TRUE(funcWrapper(func, neg_aNaN, neg_aNaN));
120     EXPECT_TRUE(funcWrapper(func, neg_sNaN, neg_sNaN));
121     EXPECT_FALSE(funcWrapper(func, neg_aNaN, neg_qnan_0x42));
122     EXPECT_TRUE(funcWrapper(func, neg_sNaN, neg_snan_0x42));
123     EXPECT_TRUE(funcWrapper(func, neg_qnan_0x42, neg_aNaN));
124     EXPECT_FALSE(funcWrapper(func, neg_snan_0x42, neg_sNaN));
125   }
126 };
127 
128 #define LIST_TOTALORDER_TESTS(T, func)                                         \
129   using LlvmLibcTotalOrderTest = TotalOrderTestTemplate<T>;                    \
130   TEST_F(LlvmLibcTotalOrderTest, XLesserThanY) { testXLesserThanY(&func); }    \
131   TEST_F(LlvmLibcTotalOrderTest, XGreaterThanY) { testXGreaterThanY(&func); }  \
132   TEST_F(LlvmLibcTotalOrderTest, XEqualToY) { testXEqualToY(&func); }          \
133   TEST_F(LlvmLibcTotalOrderTest, SingleNaN) { testSingleNaN(&func); }          \
134   TEST_F(LlvmLibcTotalOrderTest, NaNSigns) { testNaNSigns(&func); }            \
135   TEST_F(LlvmLibcTotalOrderTest, QuietVsSignalingNaN) {                        \
136     testQuietVsSignalingNaN(&func);                                            \
137   }                                                                            \
138   TEST_F(LlvmLibcTotalOrderTest, NaNPayloads) { testNaNPayloads(&func); }
139 
140 #endif // LIBC_TEST_SRC_MATH_SMOKE_TOTALORDERTEST_H
141