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 funcWrapper(TotalOrderMagFunc func,T x,T y)26 bool funcWrapper(TotalOrderMagFunc func, T x, T y) { 27 return func(&x, &y) != 0; 28 } 29 testXLesserThanY(TotalOrderMagFunc func)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 testXGreaterThanY(TotalOrderMagFunc func)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 testXEqualToY(TotalOrderMagFunc func)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 testSingleNaN(TotalOrderMagFunc func)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 testNaNSigns(TotalOrderMagFunc func)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 testQuietVsSignalingNaN(TotalOrderMagFunc func)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 testNaNPayloads(TotalOrderMagFunc func)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