brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.8 KiB · 05b8f68 Raw
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