| //===-- Utility class to test different flavors of fdim ---------*- C++ -*-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===---------------------------------------------------------------------===// |
| |
| #include "src/__support/FPUtil/BasicOperations.h" |
| #include "src/__support/FPUtil/FPBits.h" |
| #include "utils/UnitTest/FPMatcher.h" |
| #include "utils/UnitTest/Test.h" |
| #include <math.h> |
| |
| template <typename T> |
| class FDimTestTemplate : public __llvm_libc::testing::Test { |
| public: |
| using FuncPtr = T (*)(T, T); |
| using FPBits = __llvm_libc::fputil::FPBits<T>; |
| using UIntType = typename FPBits::UIntType; |
| |
| void test_na_n_arg(FuncPtr func) { |
| EXPECT_FP_EQ(nan, func(nan, inf)); |
| EXPECT_FP_EQ(nan, func(neg_inf, nan)); |
| EXPECT_FP_EQ(nan, func(nan, zero)); |
| EXPECT_FP_EQ(nan, func(neg_zero, nan)); |
| EXPECT_FP_EQ(nan, func(nan, T(-1.2345))); |
| EXPECT_FP_EQ(nan, func(T(1.2345), nan)); |
| EXPECT_FP_EQ(func(nan, nan), nan); |
| } |
| |
| void test_inf_arg(FuncPtr func) { |
| EXPECT_FP_EQ(zero, func(neg_inf, inf)); |
| EXPECT_FP_EQ(inf, func(inf, zero)); |
| EXPECT_FP_EQ(zero, func(neg_zero, inf)); |
| EXPECT_FP_EQ(inf, func(inf, T(1.2345))); |
| EXPECT_FP_EQ(zero, func(T(-1.2345), inf)); |
| } |
| |
| void test_neg_inf_arg(FuncPtr func) { |
| EXPECT_FP_EQ(inf, func(inf, neg_inf)); |
| EXPECT_FP_EQ(zero, func(neg_inf, zero)); |
| EXPECT_FP_EQ(inf, func(neg_zero, neg_inf)); |
| EXPECT_FP_EQ(zero, func(neg_inf, T(-1.2345))); |
| EXPECT_FP_EQ(inf, func(T(1.2345), neg_inf)); |
| } |
| |
| void test_both_zero(FuncPtr func) { |
| EXPECT_FP_EQ(zero, func(zero, zero)); |
| EXPECT_FP_EQ(zero, func(zero, neg_zero)); |
| EXPECT_FP_EQ(zero, func(neg_zero, zero)); |
| EXPECT_FP_EQ(zero, func(neg_zero, neg_zero)); |
| } |
| |
| void test_in_range(FuncPtr func) { |
| constexpr UIntType COUNT = 10000001; |
| constexpr UIntType STEP = UIntType(-1) / COUNT; |
| for (UIntType i = 0, v = 0, w = UIntType(-1); i <= COUNT; |
| ++i, v += STEP, w -= STEP) { |
| T x = T(FPBits(v)), y = T(FPBits(w)); |
| if (isnan(x) || isinf(x)) |
| continue; |
| if (isnan(y) || isinf(y)) |
| continue; |
| |
| if (x > y) { |
| EXPECT_FP_EQ(x - y, func(x, y)); |
| } else { |
| EXPECT_FP_EQ(zero, func(x, y)); |
| } |
| } |
| } |
| |
| private: |
| // constexpr does not work on FPBits yet, so we cannot have these constants as |
| // static. |
| const T nan = T(__llvm_libc::fputil::FPBits<T>::build_nan(1)); |
| const T inf = T(__llvm_libc::fputil::FPBits<T>::inf()); |
| const T neg_inf = T(__llvm_libc::fputil::FPBits<T>::neg_inf()); |
| const T zero = T(__llvm_libc::fputil::FPBits<T>::zero()); |
| const T neg_zero = T(__llvm_libc::fputil::FPBits<T>::neg_zero()); |
| }; |