338 lines · cpp
1//===-- Unittests for comparison operations on floating-point numbers -----===//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "src/__support/FPUtil/bfloat16.h"10#include "src/__support/FPUtil/comparison_operations.h"11#include "src/__support/macros/properties/types.h"12#include "test/UnitTest/FEnvSafeTest.h"13#include "test/UnitTest/FPMatcher.h"14#include "test/UnitTest/Test.h"15 16using LIBC_NAMESPACE::fputil::equals;17using LIBC_NAMESPACE::fputil::greater_than;18using LIBC_NAMESPACE::fputil::greater_than_or_equals;19using LIBC_NAMESPACE::fputil::less_than;20using LIBC_NAMESPACE::fputil::less_than_or_equals;21 22using BFloat16 = LIBC_NAMESPACE::fputil::BFloat16;23 24template <typename T>25class ComparisonOperationsTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {26 DECLARE_SPECIAL_CONSTANTS(T)27 28 static constexpr T normal1 = T(3.14);29 static constexpr T neg_normal1 = T(-3.14);30 static constexpr T normal2 = T(2.71);31 static constexpr T small = T(0.1);32 static constexpr T neg_small = T(-0.1);33 static constexpr T large = T(10000.0);34 static constexpr T neg_large = T(-10000.0);35 36public:37 void test_equals() {38 EXPECT_TRUE(equals(neg_zero, neg_zero));39 EXPECT_TRUE(equals(zero, neg_zero));40 EXPECT_TRUE(equals(neg_zero, zero));41 42 EXPECT_TRUE(equals(inf, inf));43 EXPECT_TRUE(equals(neg_inf, neg_inf));44 EXPECT_FALSE(equals(inf, neg_inf));45 EXPECT_FALSE(equals(neg_inf, inf));46 47 EXPECT_TRUE(equals(normal1, normal1));48 EXPECT_TRUE(equals(normal2, normal2));49 EXPECT_FALSE(equals(normal1, normal2));50 EXPECT_FALSE(equals(normal1, neg_normal1));51 52 auto test_qnan = [&](T x, T y) {53 LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);54 EXPECT_FALSE(equals(x, y));55 EXPECT_FP_EXCEPTION(0);56 };57 58 test_qnan(aNaN, aNaN);59 test_qnan(aNaN, neg_aNaN);60 test_qnan(aNaN, zero);61 test_qnan(aNaN, inf);62 test_qnan(aNaN, normal1);63 64 test_qnan(neg_aNaN, neg_aNaN);65 test_qnan(neg_aNaN, aNaN);66 test_qnan(neg_aNaN, zero);67 test_qnan(neg_aNaN, inf);68 test_qnan(neg_aNaN, normal1);69 70 auto test_snan = [&](T x, T y) {71 LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);72 EXPECT_FALSE(equals(x, y));73 EXPECT_FP_EXCEPTION(FE_INVALID);74 };75 76 test_snan(sNaN, sNaN);77 test_snan(sNaN, neg_sNaN);78 test_snan(sNaN, aNaN);79 test_snan(sNaN, neg_aNaN);80 test_snan(sNaN, zero);81 test_snan(sNaN, neg_zero);82 test_snan(sNaN, inf);83 test_snan(sNaN, neg_inf);84 test_snan(sNaN, normal1);85 86 test_snan(neg_sNaN, neg_sNaN);87 test_snan(neg_sNaN, sNaN);88 test_snan(neg_sNaN, aNaN);89 test_snan(neg_sNaN, neg_aNaN);90 test_snan(neg_sNaN, zero);91 test_snan(neg_sNaN, neg_zero);92 test_snan(neg_sNaN, inf);93 test_snan(neg_sNaN, neg_inf);94 test_snan(neg_sNaN, normal1);95 }96 97 void test_less_than() {98 EXPECT_TRUE(less_than(neg_small, small));99 EXPECT_TRUE(less_than(small, large));100 101 EXPECT_TRUE(less_than(neg_large, neg_small));102 EXPECT_FALSE(less_than(large, small));103 EXPECT_FALSE(less_than(small, neg_small));104 105 EXPECT_FALSE(less_than(zero, neg_zero));106 EXPECT_FALSE(less_than(neg_zero, zero));107 EXPECT_FALSE(less_than(zero, zero));108 109 EXPECT_TRUE(less_than(neg_small, zero));110 EXPECT_TRUE(less_than(neg_zero, small));111 EXPECT_FALSE(less_than(small, zero));112 113 EXPECT_TRUE(less_than(neg_inf, inf));114 EXPECT_TRUE(less_than(neg_inf, neg_small));115 EXPECT_TRUE(less_than(small, inf));116 EXPECT_FALSE(less_than(inf, small));117 118 EXPECT_FALSE(less_than(small, small));119 EXPECT_FALSE(less_than(neg_inf, neg_inf));120 121 auto test_qnan = [&](T x, T y) {122 LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);123 EXPECT_FALSE(less_than(x, y));124 EXPECT_FP_EXCEPTION(FE_INVALID);125 };126 127 test_qnan(aNaN, small);128 test_qnan(small, aNaN);129 test_qnan(aNaN, aNaN);130 test_qnan(neg_aNaN, neg_small);131 test_qnan(neg_small, neg_aNaN);132 test_qnan(neg_aNaN, neg_aNaN);133 134 auto test_snan = [&](T x, T y) {135 LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);136 EXPECT_FALSE(less_than(x, y));137 EXPECT_FP_EXCEPTION(FE_INVALID);138 };139 140 test_snan(sNaN, small);141 test_snan(sNaN, neg_small);142 test_snan(sNaN, zero);143 test_snan(sNaN, inf);144 test_snan(sNaN, aNaN);145 test_snan(sNaN, sNaN);146 147 test_snan(neg_sNaN, small);148 test_snan(neg_sNaN, neg_small);149 test_snan(neg_sNaN, zero);150 test_snan(neg_sNaN, inf);151 test_snan(neg_sNaN, aNaN);152 test_snan(neg_sNaN, neg_sNaN);153 }154 155 void test_greater_than() {156 EXPECT_TRUE(greater_than(large, neg_small));157 EXPECT_TRUE(greater_than(neg_small, neg_large));158 159 EXPECT_FALSE(greater_than(large, large));160 EXPECT_FALSE(greater_than(neg_small, large));161 162 EXPECT_FALSE(greater_than(zero, neg_zero));163 EXPECT_FALSE(greater_than(neg_zero, zero));164 165 EXPECT_TRUE(greater_than(inf, neg_inf));166 EXPECT_TRUE(greater_than(inf, large));167 EXPECT_TRUE(greater_than(large, neg_inf));168 EXPECT_FALSE(greater_than(neg_inf, inf));169 170 EXPECT_FALSE(greater_than(large, large));171 EXPECT_FALSE(greater_than(inf, inf));172 173 auto test_qnan = [&](T x, T y) {174 LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);175 EXPECT_FALSE(greater_than(x, y));176 EXPECT_FP_EXCEPTION(FE_INVALID);177 };178 179 test_qnan(aNaN, large);180 test_qnan(large, aNaN);181 test_qnan(aNaN, aNaN);182 test_qnan(neg_aNaN, neg_small);183 test_qnan(neg_small, neg_aNaN);184 test_qnan(neg_aNaN, neg_aNaN);185 186 auto test_snan = [&](T x, T y) {187 LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);188 EXPECT_FALSE(greater_than(x, y));189 EXPECT_FP_EXCEPTION(FE_INVALID);190 };191 192 test_snan(sNaN, large);193 test_snan(sNaN, neg_small);194 test_snan(sNaN, zero);195 test_snan(sNaN, inf);196 test_snan(sNaN, aNaN);197 test_snan(sNaN, sNaN);198 199 test_snan(neg_sNaN, large);200 test_snan(neg_sNaN, neg_small);201 test_snan(neg_sNaN, zero);202 test_snan(neg_sNaN, inf);203 test_snan(neg_sNaN, aNaN);204 test_snan(neg_sNaN, neg_sNaN);205 }206 207 void test_less_than_or_equals() {208 EXPECT_TRUE(less_than_or_equals(neg_small, small));209 EXPECT_TRUE(less_than_or_equals(small, large));210 EXPECT_TRUE(less_than_or_equals(neg_inf, small));211 212 EXPECT_TRUE(less_than_or_equals(small, small));213 EXPECT_TRUE(less_than_or_equals(zero, neg_zero));214 EXPECT_TRUE(less_than_or_equals(inf, inf));215 216 EXPECT_FALSE(less_than_or_equals(small, neg_small));217 EXPECT_FALSE(less_than_or_equals(large, small));218 EXPECT_FALSE(less_than_or_equals(inf, small));219 220 EXPECT_TRUE(less_than_or_equals(neg_large, small));221 EXPECT_FALSE(less_than_or_equals(large, neg_small));222 223 auto test_qnan = [&](T x, T y) {224 LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);225 EXPECT_FALSE(less_than_or_equals(x, y));226 EXPECT_FP_EXCEPTION(FE_INVALID);227 };228 229 test_qnan(aNaN, small);230 test_qnan(small, aNaN);231 test_qnan(aNaN, aNaN);232 test_qnan(neg_aNaN, neg_small);233 test_qnan(neg_small, neg_aNaN);234 test_qnan(neg_aNaN, neg_aNaN);235 236 auto test_snan = [&](T x, T y) {237 LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);238 EXPECT_FALSE(less_than_or_equals(x, y));239 EXPECT_FP_EXCEPTION(FE_INVALID);240 };241 242 test_snan(sNaN, small);243 test_snan(sNaN, neg_small);244 test_snan(sNaN, zero);245 test_snan(sNaN, inf);246 test_snan(sNaN, aNaN);247 test_snan(sNaN, sNaN);248 249 test_snan(neg_sNaN, small);250 test_snan(neg_sNaN, neg_small);251 test_snan(neg_sNaN, zero);252 test_snan(neg_sNaN, inf);253 test_snan(neg_sNaN, aNaN);254 test_snan(neg_sNaN, neg_sNaN);255 }256 257 void test_greater_than_or_equals() {258 EXPECT_TRUE(greater_than_or_equals(small, neg_small));259 EXPECT_TRUE(greater_than_or_equals(large, small));260 EXPECT_TRUE(greater_than_or_equals(inf, small));261 262 EXPECT_TRUE(greater_than_or_equals(small, small));263 EXPECT_TRUE(greater_than_or_equals(zero, neg_zero));264 EXPECT_TRUE(greater_than_or_equals(neg_inf, neg_inf));265 266 EXPECT_FALSE(greater_than_or_equals(neg_small, small));267 EXPECT_FALSE(greater_than_or_equals(small, large));268 EXPECT_FALSE(greater_than_or_equals(neg_inf, small));269 270 EXPECT_TRUE(greater_than_or_equals(large, neg_small));271 EXPECT_FALSE(greater_than_or_equals(neg_large, small));272 273 auto test_qnan = [&](T x, T y) {274 LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);275 EXPECT_FALSE(greater_than_or_equals(x, y));276 EXPECT_FP_EXCEPTION(FE_INVALID);277 };278 279 test_qnan(aNaN, small);280 test_qnan(small, aNaN);281 test_qnan(aNaN, aNaN);282 test_qnan(neg_aNaN, neg_small);283 test_qnan(neg_small, neg_aNaN);284 test_qnan(neg_aNaN, neg_aNaN);285 286 auto test_snan = [&](T x, T y) {287 LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);288 EXPECT_FALSE(greater_than_or_equals(x, y));289 EXPECT_FP_EXCEPTION(FE_INVALID);290 };291 292 test_snan(sNaN, small);293 test_snan(sNaN, neg_small);294 test_snan(sNaN, zero);295 test_snan(sNaN, inf);296 test_snan(sNaN, aNaN);297 test_snan(sNaN, sNaN);298 299 test_snan(neg_sNaN, small);300 test_snan(neg_sNaN, neg_small);301 test_snan(neg_sNaN, zero);302 test_snan(neg_sNaN, inf);303 test_snan(neg_sNaN, aNaN);304 test_snan(neg_sNaN, neg_sNaN);305 }306};307 308#define TEST_COMPARISON_OPS(Name, Type) \309 using LlvmLibc##Name##ComparisonOperationsTest = \310 ComparisonOperationsTest<Type>; \311 TEST_F(LlvmLibc##Name##ComparisonOperationsTest, Equals) { test_equals(); } \312 TEST_F(LlvmLibc##Name##ComparisonOperationsTest, LessThan) { \313 test_less_than(); \314 } \315 TEST_F(LlvmLibc##Name##ComparisonOperationsTest, GreaterThan) { \316 test_greater_than(); \317 } \318 TEST_F(LlvmLibc##Name##ComparisonOperationsTest, LessThanOrEquals) { \319 test_less_than_or_equals(); \320 } \321 TEST_F(LlvmLibc##Name##ComparisonOperationsTest, GreaterThanOrEquals) { \322 test_greater_than_or_equals(); \323 }324 325TEST_COMPARISON_OPS(Float, float)326TEST_COMPARISON_OPS(Double, double)327TEST_COMPARISON_OPS(LongDouble, long double)328 329#ifdef LIBC_TYPES_HAS_FLOAT16330TEST_COMPARISON_OPS(Float16, float16)331#endif // LIBC_TYPES_HAS_FLOAT16332 333#ifdef LIBC_TYPES_HAS_FLOAT128334TEST_COMPARISON_OPS(Float128, float128)335#endif // LIBC_TYPES_HAS_FLOAT128336 337TEST_COMPARISON_OPS(BFloat16, BFloat16)338