63 lines
2.6 KiB
C++
63 lines
2.6 KiB
C++
//===-- 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(); }
|