[libc] Add testing macros for errno and floating point exceptions.

Add testing macros for errno and floating point exceptions.

Reviewed By: sivachandra

Differential Revision: https://reviews.llvm.org/D121235
This commit is contained in:
Tue Ly 2022-03-08 13:36:39 -05:00
parent b389d68e52
commit ffb410d3f9
8 changed files with 105 additions and 103 deletions

View File

@ -9,17 +9,14 @@
#ifndef LLVM_LIBC_TEST_SRC_MATH_ROUNDTOINTEGERTEST_H
#define LLVM_LIBC_TEST_SRC_MATH_ROUNDTOINTEGERTEST_H
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
#include "utils/MPFRWrapper/MPFRUtils.h"
#include "utils/UnitTest/FPMatcher.h"
#include "utils/UnitTest/Test.h"
#include <math.h>
#if math_errhandling & MATH_ERRNO
#include <errno.h>
#endif
#if math_errhandling & MATH_ERREXCEPT
#include "src/__support/FPUtil/FEnvImpl.h"
#endif
#include <math.h>
namespace mpfr = __llvm_libc::testing::mpfr;
@ -45,29 +42,17 @@ private:
void test_one_input(RoundToIntegerFunc func, F input, I expected,
bool expectError) {
#if math_errhandling & MATH_ERRNO
errno = 0;
#endif
#if math_errhandling & MATH_ERREXCEPT
__llvm_libc::fputil::clear_except(FE_ALL_EXCEPT);
#endif
ASSERT_EQ(func(input), expected);
if (expectError) {
#if math_errhandling & MATH_ERREXCEPT
ASSERT_EQ(__llvm_libc::fputil::test_except(FE_ALL_EXCEPT), FE_INVALID);
#endif
#if math_errhandling & MATH_ERRNO
ASSERT_EQ(errno, EDOM);
#endif
ASSERT_FP_EXCEPTION(FE_INVALID);
ASSERT_MATH_ERRNO(EDOM);
} else {
#if math_errhandling & MATH_ERREXCEPT
ASSERT_EQ(__llvm_libc::fputil::test_except(FE_ALL_EXCEPT), 0);
#endif
#if math_errhandling & MATH_ERRNO
ASSERT_EQ(errno, 0);
#endif
ASSERT_FP_EXCEPTION(0);
ASSERT_MATH_ERRNO(0);
}
}

View File

@ -29,21 +29,19 @@ TEST(LlvmLibcCosfTest, SpecialNumbers) {
errno = 0;
EXPECT_FP_EQ(aNaN, __llvm_libc::cosf(aNaN));
EXPECT_EQ(errno, 0);
EXPECT_MATH_ERRNO(0);
EXPECT_FP_EQ(1.0f, __llvm_libc::cosf(0.0f));
EXPECT_EQ(errno, 0);
EXPECT_MATH_ERRNO(0);
EXPECT_FP_EQ(1.0f, __llvm_libc::cosf(-0.0f));
EXPECT_EQ(errno, 0);
EXPECT_MATH_ERRNO(0);
errno = 0;
EXPECT_FP_EQ(aNaN, __llvm_libc::cosf(inf));
EXPECT_EQ(errno, EDOM);
EXPECT_MATH_ERRNO(EDOM);
errno = 0;
EXPECT_FP_EQ(aNaN, __llvm_libc::cosf(neg_inf));
EXPECT_EQ(errno, EDOM);
EXPECT_MATH_ERRNO(EDOM);
}
TEST(LlvmLibcCosfTest, InFloatRange) {

View File

@ -24,33 +24,31 @@ TEST(LlvmLibcExp2fTest, SpecialNumbers) {
errno = 0;
EXPECT_FP_EQ(aNaN, __llvm_libc::exp2f(aNaN));
EXPECT_EQ(errno, 0);
EXPECT_MATH_ERRNO(0);
EXPECT_FP_EQ(inf, __llvm_libc::exp2f(inf));
EXPECT_EQ(errno, 0);
EXPECT_MATH_ERRNO(0);
EXPECT_FP_EQ(0.0f, __llvm_libc::exp2f(neg_inf));
EXPECT_EQ(errno, 0);
EXPECT_MATH_ERRNO(0);
EXPECT_FP_EQ(1.0f, __llvm_libc::exp2f(0.0f));
EXPECT_EQ(errno, 0);
EXPECT_MATH_ERRNO(0);
EXPECT_FP_EQ(1.0f, __llvm_libc::exp2f(-0.0f));
EXPECT_EQ(errno, 0);
EXPECT_MATH_ERRNO(0);
}
TEST(LlvmLibcExpfTest, Overflow) {
errno = 0;
EXPECT_FP_EQ(inf, __llvm_libc::exp2f(float(FPBits(0x7f7fffffU))));
EXPECT_EQ(errno, ERANGE);
EXPECT_MATH_ERRNO(ERANGE);
errno = 0;
EXPECT_FP_EQ(inf, __llvm_libc::exp2f(float(FPBits(0x43000000U))));
EXPECT_EQ(errno, ERANGE);
EXPECT_MATH_ERRNO(ERANGE);
errno = 0;
EXPECT_FP_EQ(inf, __llvm_libc::exp2f(float(FPBits(0x43000001U))));
EXPECT_EQ(errno, ERANGE);
EXPECT_MATH_ERRNO(ERANGE);
}
// Test with inputs which are the borders of underflow/overflow but still
@ -61,43 +59,41 @@ TEST(LlvmLibcExpfTest, Borderline) {
errno = 0;
x = float(FPBits(0x42fa0001U));
EXPECT_MPFR_MATCH(mpfr::Operation::Exp2, x, __llvm_libc::exp2f(x), 1.0);
EXPECT_EQ(errno, 0);
EXPECT_MATH_ERRNO(0);
x = float(FPBits(0x42ffffffU));
EXPECT_MPFR_MATCH(mpfr::Operation::Exp2, x, __llvm_libc::exp2f(x), 1.0);
EXPECT_EQ(errno, 0);
EXPECT_MATH_ERRNO(0);
x = float(FPBits(0xc2fa0001U));
EXPECT_MPFR_MATCH(mpfr::Operation::Exp2, x, __llvm_libc::exp2f(x), 1.0);
EXPECT_EQ(errno, 0);
EXPECT_MATH_ERRNO(0);
x = float(FPBits(0xc2fc0000U));
EXPECT_MPFR_MATCH(mpfr::Operation::Exp2, x, __llvm_libc::exp2f(x), 1.0);
EXPECT_EQ(errno, 0);
EXPECT_MATH_ERRNO(0);
x = float(FPBits(0xc2fc0001U));
EXPECT_MPFR_MATCH(mpfr::Operation::Exp2, x, __llvm_libc::exp2f(x), 1.0);
EXPECT_EQ(errno, 0);
EXPECT_MATH_ERRNO(0);
x = float(FPBits(0xc3150000U));
EXPECT_MPFR_MATCH(mpfr::Operation::Exp2, x, __llvm_libc::exp2f(x), 1.0);
EXPECT_EQ(errno, 0);
EXPECT_MATH_ERRNO(0);
}
TEST(LlvmLibcExpfTest, Underflow) {
errno = 0;
EXPECT_FP_EQ(0.0f, __llvm_libc::exp2f(float(FPBits(0xff7fffffU))));
EXPECT_EQ(errno, ERANGE);
EXPECT_MATH_ERRNO(ERANGE);
errno = 0;
float x = float(FPBits(0xc3158000U));
EXPECT_MPFR_MATCH(mpfr::Operation::Exp2, x, __llvm_libc::exp2f(x), 1.0);
EXPECT_EQ(errno, ERANGE);
EXPECT_MATH_ERRNO(ERANGE);
errno = 0;
x = float(FPBits(0xc3165432U));
EXPECT_MPFR_MATCH(mpfr::Operation::Exp2, x, __llvm_libc::exp2f(x), 1.0);
EXPECT_EQ(errno, ERANGE);
EXPECT_MATH_ERRNO(ERANGE);
}
TEST(LlvmLibcexp2fTest, InFloatRange) {

View File

@ -24,49 +24,45 @@ TEST(LlvmLibcExpfTest, SpecialNumbers) {
errno = 0;
EXPECT_FP_EQ(aNaN, __llvm_libc::expf(aNaN));
EXPECT_EQ(errno, 0);
EXPECT_MATH_ERRNO(0);
EXPECT_FP_EQ(inf, __llvm_libc::expf(inf));
EXPECT_EQ(errno, 0);
EXPECT_MATH_ERRNO(0);
EXPECT_FP_EQ(0.0f, __llvm_libc::expf(neg_inf));
EXPECT_EQ(errno, 0);
EXPECT_MATH_ERRNO(0);
EXPECT_FP_EQ(1.0f, __llvm_libc::expf(0.0f));
EXPECT_EQ(errno, 0);
EXPECT_MATH_ERRNO(0);
EXPECT_FP_EQ(1.0f, __llvm_libc::expf(-0.0f));
EXPECT_EQ(errno, 0);
EXPECT_MATH_ERRNO(0);
}
TEST(LlvmLibcExpfTest, Overflow) {
errno = 0;
EXPECT_FP_EQ(inf, __llvm_libc::expf(float(FPBits(0x7f7fffffU))));
EXPECT_EQ(errno, ERANGE);
EXPECT_MATH_ERRNO(ERANGE);
errno = 0;
EXPECT_FP_EQ(inf, __llvm_libc::expf(float(FPBits(0x42cffff8U))));
EXPECT_EQ(errno, ERANGE);
EXPECT_MATH_ERRNO(ERANGE);
errno = 0;
EXPECT_FP_EQ(inf, __llvm_libc::expf(float(FPBits(0x42d00008U))));
EXPECT_EQ(errno, ERANGE);
EXPECT_MATH_ERRNO(ERANGE);
}
TEST(LlvmLibcExpfTest, Underflow) {
errno = 0;
EXPECT_FP_EQ(0.0f, __llvm_libc::expf(float(FPBits(0xff7fffffU))));
EXPECT_EQ(errno, ERANGE);
EXPECT_MATH_ERRNO(ERANGE);
errno = 0;
float x = float(FPBits(0xc2cffff8U));
EXPECT_MPFR_MATCH(mpfr::Operation::Exp, x, __llvm_libc::expf(x), 1.0);
EXPECT_EQ(errno, ERANGE);
EXPECT_MATH_ERRNO(ERANGE);
errno = 0;
x = float(FPBits(0xc2d00008U));
EXPECT_MPFR_MATCH(mpfr::Operation::Exp, x, __llvm_libc::expf(x), 1.0);
EXPECT_EQ(errno, ERANGE);
EXPECT_MATH_ERRNO(ERANGE);
}
// Test with inputs which are the borders of underflow/overflow but still
@ -77,19 +73,19 @@ TEST(LlvmLibcExpfTest, Borderline) {
errno = 0;
x = float(FPBits(0x42affff8U));
ASSERT_MPFR_MATCH(mpfr::Operation::Exp, x, __llvm_libc::expf(x), 1.0);
EXPECT_EQ(errno, 0);
EXPECT_MATH_ERRNO(0);
x = float(FPBits(0x42b00008U));
ASSERT_MPFR_MATCH(mpfr::Operation::Exp, x, __llvm_libc::expf(x), 1.0);
EXPECT_EQ(errno, 0);
EXPECT_MATH_ERRNO(0);
x = float(FPBits(0xc2affff8U));
ASSERT_MPFR_MATCH(mpfr::Operation::Exp, x, __llvm_libc::expf(x), 1.0);
EXPECT_EQ(errno, 0);
EXPECT_MATH_ERRNO(0);
x = float(FPBits(0xc2b00008U));
ASSERT_MPFR_MATCH(mpfr::Operation::Exp, x, __llvm_libc::expf(x), 1.0);
EXPECT_EQ(errno, 0);
EXPECT_MATH_ERRNO(0);
}
TEST(LlvmLibcExpfTest, InFloatRange) {

View File

@ -24,49 +24,45 @@ TEST(LlvmLibcExpm1fTest, SpecialNumbers) {
errno = 0;
EXPECT_FP_EQ(aNaN, __llvm_libc::expm1f(aNaN));
EXPECT_EQ(errno, 0);
EXPECT_MATH_ERRNO(0);
EXPECT_FP_EQ(inf, __llvm_libc::expm1f(inf));
EXPECT_EQ(errno, 0);
EXPECT_MATH_ERRNO(0);
EXPECT_FP_EQ(-1.0f, __llvm_libc::expm1f(neg_inf));
EXPECT_EQ(errno, 0);
EXPECT_MATH_ERRNO(0);
EXPECT_FP_EQ(0.0f, __llvm_libc::expm1f(0.0f));
EXPECT_EQ(errno, 0);
EXPECT_MATH_ERRNO(0);
EXPECT_FP_EQ(-0.0f, __llvm_libc::expm1f(-0.0f));
EXPECT_EQ(errno, 0);
EXPECT_MATH_ERRNO(0);
}
TEST(LlvmLibcExpm1fTest, Overflow) {
errno = 0;
EXPECT_FP_EQ(inf, __llvm_libc::expm1f(float(FPBits(0x7f7fffffU))));
EXPECT_EQ(errno, ERANGE);
EXPECT_MATH_ERRNO(ERANGE);
errno = 0;
EXPECT_FP_EQ(inf, __llvm_libc::expm1f(float(FPBits(0x42cffff8U))));
EXPECT_EQ(errno, ERANGE);
EXPECT_MATH_ERRNO(ERANGE);
errno = 0;
EXPECT_FP_EQ(inf, __llvm_libc::expm1f(float(FPBits(0x42d00008U))));
EXPECT_EQ(errno, ERANGE);
EXPECT_MATH_ERRNO(ERANGE);
}
TEST(LlvmLibcExpm1fTest, Underflow) {
errno = 0;
EXPECT_FP_EQ(-1.0f, __llvm_libc::expm1f(float(FPBits(0xff7fffffU))));
EXPECT_EQ(errno, ERANGE);
EXPECT_MATH_ERRNO(ERANGE);
errno = 0;
float x = float(FPBits(0xc2cffff8U));
EXPECT_FP_EQ(-1.0f, __llvm_libc::expm1f(x));
EXPECT_EQ(errno, ERANGE);
EXPECT_MATH_ERRNO(ERANGE);
errno = 0;
x = float(FPBits(0xc2d00008U));
EXPECT_FP_EQ(-1.0f, __llvm_libc::expm1f(x));
EXPECT_EQ(errno, ERANGE);
EXPECT_MATH_ERRNO(ERANGE);
}
// Test with inputs which are the borders of underflow/overflow but still
@ -77,19 +73,19 @@ TEST(LlvmLibcExpm1fTest, Borderline) {
errno = 0;
x = float(FPBits(0x42affff8U));
ASSERT_MPFR_MATCH(mpfr::Operation::Expm1, x, __llvm_libc::expm1f(x), 1.0);
EXPECT_EQ(errno, 0);
EXPECT_MATH_ERRNO(0);
x = float(FPBits(0x42b00008U));
ASSERT_MPFR_MATCH(mpfr::Operation::Expm1, x, __llvm_libc::expm1f(x), 1.0);
EXPECT_EQ(errno, 0);
EXPECT_MATH_ERRNO(0);
x = float(FPBits(0xc2affff8U));
ASSERT_MPFR_MATCH(mpfr::Operation::Expm1, x, __llvm_libc::expm1f(x), 1.0);
EXPECT_EQ(errno, 0);
EXPECT_MATH_ERRNO(0);
x = float(FPBits(0xc2b00008U));
ASSERT_MPFR_MATCH(mpfr::Operation::Expm1, x, __llvm_libc::expm1f(x), 1.0);
EXPECT_EQ(errno, 0);
EXPECT_MATH_ERRNO(0);
}
TEST(LlvmLibcExpm1fTest, InFloatRange) {

View File

@ -32,29 +32,27 @@ TEST(LlvmLibcSinCosfTest, SpecialNumbers) {
__llvm_libc::sincosf(aNaN, &sin, &cos);
EXPECT_FP_EQ(aNaN, cos);
EXPECT_FP_EQ(aNaN, sin);
EXPECT_EQ(errno, 0);
EXPECT_MATH_ERRNO(0);
__llvm_libc::sincosf(0.0f, &sin, &cos);
EXPECT_FP_EQ(1.0f, cos);
EXPECT_FP_EQ(0.0f, sin);
EXPECT_EQ(errno, 0);
EXPECT_MATH_ERRNO(0);
__llvm_libc::sincosf(-0.0f, &sin, &cos);
EXPECT_FP_EQ(1.0f, cos);
EXPECT_FP_EQ(-0.0f, sin);
EXPECT_EQ(errno, 0);
EXPECT_MATH_ERRNO(0);
errno = 0;
__llvm_libc::sincosf(inf, &sin, &cos);
EXPECT_FP_EQ(aNaN, cos);
EXPECT_FP_EQ(aNaN, sin);
EXPECT_EQ(errno, EDOM);
EXPECT_MATH_ERRNO(EDOM);
errno = 0;
__llvm_libc::sincosf(neg_inf, &sin, &cos);
EXPECT_FP_EQ(aNaN, cos);
EXPECT_FP_EQ(aNaN, sin);
EXPECT_EQ(errno, EDOM);
EXPECT_MATH_ERRNO(EDOM);
}
TEST(LlvmLibcSinCosfTest, InFloatRange) {

View File

@ -29,21 +29,19 @@ TEST(LlvmLibcSinfTest, SpecialNumbers) {
errno = 0;
EXPECT_FP_EQ(aNaN, __llvm_libc::sinf(aNaN));
EXPECT_EQ(errno, 0);
EXPECT_MATH_ERRNO(0);
EXPECT_FP_EQ(0.0f, __llvm_libc::sinf(0.0f));
EXPECT_EQ(errno, 0);
EXPECT_MATH_ERRNO(0);
EXPECT_FP_EQ(-0.0f, __llvm_libc::sinf(-0.0f));
EXPECT_EQ(errno, 0);
EXPECT_MATH_ERRNO(0);
errno = 0;
EXPECT_FP_EQ(aNaN, __llvm_libc::sinf(inf));
EXPECT_EQ(errno, EDOM);
EXPECT_MATH_ERRNO(EDOM);
errno = 0;
EXPECT_FP_EQ(aNaN, __llvm_libc::sinf(neg_inf));
EXPECT_EQ(errno, EDOM);
EXPECT_MATH_ERRNO(EDOM);
}
TEST(LlvmLibcSinfTest, InFloatRange) {

View File

@ -9,10 +9,13 @@
#ifndef LLVM_LIBC_UTILS_UNITTEST_FPMATCHER_H
#define LLVM_LIBC_UTILS_UNITTEST_FPMATCHER_H
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
#include "utils/UnitTest/Test.h"
#include <errno.h>
#include <math.h>
namespace __llvm_libc {
namespace fputil {
namespace testing {
@ -97,4 +100,36 @@ FPMatcher<T, C> getMatcher(T expectedValue) {
__llvm_libc::fputil::testing::getMatcher<__llvm_libc::testing::Cond_NE>( \
expected))
#define EXPECT_MATH_ERRNO(expected) \
do { \
if (math_errhandling & MATH_ERRNO) { \
int actual = errno; \
errno = 0; \
EXPECT_EQ(actual, expected); \
} \
} while (0)
#define ASSERT_MATH_ERRNO(expected) \
do { \
if (math_errhandling & MATH_ERRNO) { \
int actual = errno; \
errno = 0; \
ASSERT_EQ(actual, expected); \
} \
} while (0)
#define EXPECT_FP_EXCEPTION(expected) \
do { \
if (math_errhandling & MATH_ERREXCEPT) { \
EXPECT_EQ(__llvm_libc::fputil::test_except(FE_ALL_EXCEPT), expected); \
} \
} while (0)
#define ASSERT_FP_EXCEPTION(expected) \
do { \
if (math_errhandling & MATH_ERREXCEPT) { \
ASSERT_EQ(__llvm_libc::fputil::test_except(FE_ALL_EXCEPT), expected); \
} \
} while (0)
#endif // LLVM_LIBC_UTILS_UNITTEST_FPMATCHER_H