blob: 0fd1ab087f7f5d858c6127b26d78d9e6064ae3c4 [file] [edit]
//===-- Unittests for shared math check exception functions ---------------===//
//
// 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 "shared/math_check_exceptions.h"
#include "src/__support/CPP/array.h"
#include "src/__support/math/check/exp_exceptions.h"
#include "test/UnitTest/FPMatcher.h"
#include "test/UnitTest/Test.h"
template <typename T>
class CheckExpTest : public LIBC_NAMESPACE::testing::Test {
DECLARE_SPECIAL_CONSTANTS(T)
public:
void run_test() {
using LIBC_NAMESPACE::shared::check::exp_exceptions;
using IntArray = LIBC_NAMESPACE::cpp::array<int, 4>;
using Bounds = LIBC_NAMESPACE::math::check::exp_internal::Bounds<T>;
constexpr IntArray ROUNDING_MODES = {FE_TONEAREST, FE_UPWARD, FE_DOWNWARD,
FE_TOWARDZERO};
for (auto rm : ROUNDING_MODES) {
EXPECT_EQ(FE_INVALID, exp_exceptions(sNaN, rm));
EXPECT_EQ(FE_INVALID, exp_exceptions(neg_sNaN, rm));
EXPECT_EQ(0, exp_exceptions(aNaN, rm));
EXPECT_EQ(0, exp_exceptions(neg_aNaN, rm));
EXPECT_EQ(0, exp_exceptions(inf, rm));
EXPECT_EQ(0, exp_exceptions(neg_inf, rm));
EXPECT_EQ(0, exp_exceptions(zero, rm));
EXPECT_EQ(0, exp_exceptions(neg_zero, rm));
EXPECT_EQ(FE_UNDERFLOW,
exp_exceptions(neg_max_normal, rm) & FE_UNDERFLOW);
EXPECT_EQ(FE_UNDERFLOW, exp_exceptions(Bounds::LOWER, rm) & FE_UNDERFLOW);
EXPECT_EQ(0, exp_exceptions(T(1), rm) & (~FE_INEXACT));
}
EXPECT_EQ(FE_OVERFLOW,
exp_exceptions(max_normal, FE_TONEAREST) & FE_OVERFLOW);
EXPECT_EQ(FE_OVERFLOW, exp_exceptions(max_normal, FE_UPWARD) & FE_OVERFLOW);
EXPECT_EQ(0, exp_exceptions(max_normal, FE_DOWNWARD) & FE_OVERFLOW);
EXPECT_EQ(0, exp_exceptions(max_normal, FE_TOWARDZERO) & FE_OVERFLOW);
EXPECT_EQ(FE_OVERFLOW,
exp_exceptions(Bounds::UPPER, FE_TONEAREST) & FE_OVERFLOW);
EXPECT_EQ(FE_OVERFLOW,
exp_exceptions(Bounds::UPPER, FE_UPWARD) & FE_OVERFLOW);
EXPECT_EQ(0, exp_exceptions(Bounds::UPPER, FE_DOWNWARD) & FE_OVERFLOW);
EXPECT_EQ(0, exp_exceptions(Bounds::UPPER, FE_TOWARDZERO) & FE_OVERFLOW);
}
};
using LlvmLibcCheckExpTestFloat = CheckExpTest<float>;
using LlvmLibcCheckExpTestDouble = CheckExpTest<double>;
TEST_F(LlvmLibcCheckExpTestFloat, CheckExpfExceptions) { run_test(); }
TEST_F(LlvmLibcCheckExpTestDouble, CheckExpExceptions) { run_test(); }