aboutsummaryrefslogtreecommitdiff
path: root/libc/test
diff options
context:
space:
mode:
authorSiva Chandra Reddy <sivachandra@google.com>2020-11-18 21:30:47 -0800
committerSiva Chandra Reddy <sivachandra@google.com>2020-12-02 11:48:49 -0800
commit19c3894f9436ef68f33f80ee1fd589166267b5a1 (patch)
tree47a95ea27e4b17d38eda57a7c75dfe777e7bcf0d /libc/test
parentbc044a88ee3c16e4164740732a7adc91a29b24f5 (diff)
downloadllvm-project-19c3894f9436ef68f33f80ee1fd589166267b5a1.tar.gz
[libc] Fix couple of corner cases in remquo.
These two cases are fixed: 1. If numerator is not zero and denominator is infinity, then the numerator is returned as the remainder. 2. If numerator and denominator are equal in magnitude, then quotient with the right sign is returned. The differet tests of remquo, remquof and remquol have been unified into a single file to avoid duplication. Reviewed By: lntue Differential Revision: https://reviews.llvm.org/D92353
Diffstat (limited to 'libc/test')
-rw-r--r--libc/test/src/math/CMakeLists.txt6
-rw-r--r--libc/test/src/math/RemQuoTest.h144
-rw-r--r--libc/test/src/math/remquo_test.cpp80
-rw-r--r--libc/test/src/math/remquof_test.cpp80
-rw-r--r--libc/test/src/math/remquol_test.cpp86
5 files changed, 159 insertions, 237 deletions
diff --git a/libc/test/src/math/CMakeLists.txt b/libc/test/src/math/CMakeLists.txt
index 2220cef00791..cdffe737d8df 100644
--- a/libc/test/src/math/CMakeLists.txt
+++ b/libc/test/src/math/CMakeLists.txt
@@ -686,6 +686,8 @@ add_fp_unittest(
libc_math_unittests
SRCS
remquof_test.cpp
+ HDRS
+ RemQuoTest.h
DEPENDS
libc.include.math
libc.src.math.remquof
@@ -699,6 +701,8 @@ add_fp_unittest(
libc_math_unittests
SRCS
remquo_test.cpp
+ HDRS
+ RemQuoTest.h
DEPENDS
libc.include.math
libc.src.math.remquo
@@ -712,6 +716,8 @@ add_fp_unittest(
libc_math_unittests
SRCS
remquol_test.cpp
+ HDRS
+ RemQuoTest.h
DEPENDS
libc.include.math
libc.src.math.remquol
diff --git a/libc/test/src/math/RemQuoTest.h b/libc/test/src/math/RemQuoTest.h
new file mode 100644
index 000000000000..29fcdb83b6a2
--- /dev/null
+++ b/libc/test/src/math/RemQuoTest.h
@@ -0,0 +1,144 @@
+//===-- Utility class to test different flavors of remquo -------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_TEST_SRC_MATH_REMQUOTEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_REMQUOTEST_H
+
+#include "utils/FPUtil/BasicOperations.h"
+#include "utils/FPUtil/FPBits.h"
+#include "utils/FPUtil/TestHelpers.h"
+#include "utils/MPFRWrapper/MPFRUtils.h"
+#include "utils/UnitTest/Test.h"
+#include <math.h>
+
+namespace mpfr = __llvm_libc::testing::mpfr;
+
+template <typename T>
+class RemQuoTestTemplate : public __llvm_libc::testing::Test {
+ using FPBits = __llvm_libc::fputil::FPBits<T>;
+ using UIntType = typename FPBits::UIntType;
+
+ const T zero = __llvm_libc::fputil::FPBits<T>::zero();
+ const T negZero = __llvm_libc::fputil::FPBits<T>::negZero();
+ const T inf = __llvm_libc::fputil::FPBits<T>::inf();
+ const T negInf = __llvm_libc::fputil::FPBits<T>::negInf();
+ const T nan = __llvm_libc::fputil::FPBits<T>::buildNaN(1);
+
+public:
+ typedef T (*RemQuoFunc)(T, T, int *);
+
+ void testSpecialNumbers(RemQuoFunc func) {
+ int quotient;
+ T x, y;
+
+ y = T(1.0);
+ x = inf;
+ EXPECT_NE(isnan(func(x, y, &quotient)), 0);
+ x = negInf;
+ EXPECT_NE(isnan(func(x, y, &quotient)), 0);
+
+ x = T(1.0);
+ y = zero;
+ EXPECT_NE(isnan(func(x, y, &quotient)), 0);
+ y = negZero;
+ EXPECT_NE(isnan(func(x, y, &quotient)), 0);
+
+ y = nan;
+ x = T(1.0);
+ EXPECT_NE(isnan(func(x, y, &quotient)), 0);
+
+ y = T(1.0);
+ x = nan;
+ EXPECT_NE(isnan(func(x, y, &quotient)), 0);
+
+ x = nan;
+ y = nan;
+ EXPECT_NE(isnan(func(x, y, &quotient)), 0);
+
+ x = zero;
+ y = T(1.0);
+ EXPECT_FP_EQ(func(x, y, &quotient), zero);
+
+ x = negZero;
+ y = T(1.0);
+ EXPECT_FP_EQ(func(x, y, &quotient), negZero);
+
+ x = T(1.125);
+ y = inf;
+ EXPECT_FP_EQ(func(x, y, &quotient), x);
+ EXPECT_EQ(quotient, 0);
+ }
+
+ void testEqualNumeratorAndDenominator(RemQuoFunc func) {
+ T x = T(1.125), y = T(1.125);
+ int q;
+
+ // When the remainder is zero, the standard requires it to
+ // have the same sign as x.
+
+ EXPECT_FP_EQ(func(x, y, &q), zero);
+ EXPECT_EQ(q, 1);
+
+ EXPECT_FP_EQ(func(x, -y, &q), zero);
+ EXPECT_EQ(q, -1);
+
+ EXPECT_FP_EQ(func(-x, y, &q), negZero);
+ EXPECT_EQ(q, -1);
+
+ EXPECT_FP_EQ(func(-x, -y, &q), negZero);
+ EXPECT_EQ(q, 1);
+ }
+
+ void testSubnormalRange(RemQuoFunc func) {
+ constexpr UIntType count = 1000001;
+ constexpr UIntType step =
+ (FPBits::maxSubnormal - FPBits::minSubnormal) / count;
+ for (UIntType v = FPBits::minSubnormal, w = FPBits::maxSubnormal;
+ v <= FPBits::maxSubnormal && w >= FPBits::minSubnormal;
+ v += step, w -= step) {
+ T x = FPBits(v), y = FPBits(w);
+ mpfr::BinaryOutput<T> result;
+ mpfr::BinaryInput<T> input{x, y};
+ result.f = func(x, y, &result.i);
+ ASSERT_MPFR_MATCH(mpfr::Operation::RemQuo, input, result, 0.0);
+ }
+ }
+
+ void testNormalRange(RemQuoFunc func) {
+ constexpr UIntType count = 1000001;
+ constexpr UIntType step = (FPBits::maxNormal - FPBits::minNormal) / count;
+ for (UIntType v = FPBits::minNormal, w = FPBits::maxNormal;
+ v <= FPBits::maxNormal && w >= FPBits::minNormal;
+ v += step, w -= step) {
+ T x = FPBits(v), y = FPBits(w);
+ mpfr::BinaryOutput<T> result;
+ mpfr::BinaryInput<T> input{x, y};
+ result.f = func(x, y, &result.i);
+
+ // In normal range on x86 platforms, the long double implicit 1 bit can be
+ // zero making the numbers NaN. Hence we test for them separately.
+ if (isnan(x) || isnan(y)) {
+ ASSERT_NE(isnan(result.f), 0);
+ continue;
+ }
+
+ ASSERT_MPFR_MATCH(mpfr::Operation::RemQuo, input, result, 0.0);
+ }
+ }
+};
+
+#define LIST_REMQUO_TESTS(T, func) \
+ using RemQuoTest = RemQuoTestTemplate<T>; \
+ TEST_F(RemQuoTest, SpecialNumbers) { testSpecialNumbers(&func); } \
+ TEST_F(RemQuoTest, EqualNumeratorAndDenominator) { \
+ testEqualNumeratorAndDenominator(&func); \
+ } \
+ TEST_F(RemQuoTest, SubnormalRange) { testSubnormalRange(&func); } \
+ TEST_F(RemQuoTest, NormalRange) { testNormalRange(&func); }
+
+#endif // LLVM_LIBC_TEST_SRC_MATH_REMQUOTEST_H
diff --git a/libc/test/src/math/remquo_test.cpp b/libc/test/src/math/remquo_test.cpp
index 197d97069001..8efec397f39d 100644
--- a/libc/test/src/math/remquo_test.cpp
+++ b/libc/test/src/math/remquo_test.cpp
@@ -6,82 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#include "src/math/remquo.h"
-#include "utils/FPUtil/BasicOperations.h"
-#include "utils/FPUtil/FPBits.h"
-#include "utils/FPUtil/TestHelpers.h"
-#include "utils/MPFRWrapper/MPFRUtils.h"
-#include "utils/UnitTest/Test.h"
-#include <math.h>
-
-using FPBits = __llvm_libc::fputil::FPBits<double>;
-using UIntType = FPBits::UIntType;
-
-namespace mpfr = __llvm_libc::testing::mpfr;
-
-DECLARE_SPECIAL_CONSTANTS(double)
-
-TEST(RemquoTest, SpecialNumbers) {
- int exponent;
- double x, y;
-
- y = 1.0;
- x = inf;
- EXPECT_NE(isnan(__llvm_libc::remquo(x, y, &exponent)), 0);
- x = negInf;
- EXPECT_NE(isnan(__llvm_libc::remquo(x, y, &exponent)), 0);
-
- x = 1.0;
- y = zero;
- EXPECT_NE(isnan(__llvm_libc::remquo(x, y, &exponent)), 0);
- y = negZero;
- EXPECT_NE(isnan(__llvm_libc::remquo(x, y, &exponent)), 0);
+#include "RemQuoTest.h"
- y = nan;
- x = 1.0;
- EXPECT_NE(isnan(__llvm_libc::remquo(x, y, &exponent)), 0);
-
- y = 1.0;
- x = nan;
- EXPECT_NE(isnan(__llvm_libc::remquo(x, y, &exponent)), 0);
-
- x = nan;
- y = nan;
- EXPECT_NE(isnan(__llvm_libc::remquo(x, y, &exponent)), 0);
-
- x = zero;
- y = 1.0;
- EXPECT_FP_EQ(__llvm_libc::remquo(x, y, &exponent), zero);
-
- x = negZero;
- y = 1.0;
- EXPECT_FP_EQ(__llvm_libc::remquo(x, y, &exponent), negZero);
-}
-
-TEST(RemquoTest, SubnormalRange) {
- constexpr UIntType count = 1000001;
- constexpr UIntType step =
- (FPBits::maxSubnormal - FPBits::minSubnormal) / count;
- for (UIntType v = FPBits::minSubnormal, w = FPBits::maxSubnormal;
- v <= FPBits::maxSubnormal && w >= FPBits::minSubnormal;
- v += step, w -= step) {
- double x = FPBits(v), y = FPBits(w);
- mpfr::BinaryOutput<double> result;
- mpfr::BinaryInput<double> input{x, y};
- result.f = __llvm_libc::remquo(x, y, &result.i);
- ASSERT_MPFR_MATCH(mpfr::Operation::RemQuo, input, result, 0.0);
- }
-}
+#include "src/math/remquo.h"
-TEST(RemquoTest, NormalRange) {
- constexpr UIntType count = 1000001;
- constexpr UIntType step = (FPBits::maxNormal - FPBits::minNormal) / count;
- for (UIntType v = FPBits::minNormal, w = FPBits::maxNormal;
- v <= FPBits::maxNormal && w >= FPBits::minNormal; v += step, w -= step) {
- double x = FPBits(v), y = FPBits(w);
- mpfr::BinaryOutput<double> result;
- mpfr::BinaryInput<double> input{x, y};
- result.f = __llvm_libc::remquo(x, y, &result.i);
- ASSERT_MPFR_MATCH(mpfr::Operation::RemQuo, input, result, 0.0);
- }
-}
+LIST_REMQUO_TESTS(double, __llvm_libc::remquo)
diff --git a/libc/test/src/math/remquof_test.cpp b/libc/test/src/math/remquof_test.cpp
index 4ede7fb3feec..1af4ba4e0153 100644
--- a/libc/test/src/math/remquof_test.cpp
+++ b/libc/test/src/math/remquof_test.cpp
@@ -6,82 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#include "src/math/remquof.h"
-#include "utils/FPUtil/BasicOperations.h"
-#include "utils/FPUtil/FPBits.h"
-#include "utils/FPUtil/TestHelpers.h"
-#include "utils/MPFRWrapper/MPFRUtils.h"
-#include "utils/UnitTest/Test.h"
-#include <math.h>
-
-using FPBits = __llvm_libc::fputil::FPBits<float>;
-using UIntType = FPBits::UIntType;
-
-namespace mpfr = __llvm_libc::testing::mpfr;
-
-DECLARE_SPECIAL_CONSTANTS(float)
-
-TEST(RemquofTest, SpecialNumbers) {
- int exponent;
- float x, y;
-
- y = 1.0f;
- x = inf;
- EXPECT_NE(isnan(__llvm_libc::remquof(x, y, &exponent)), 0);
- x = negInf;
- EXPECT_NE(isnan(__llvm_libc::remquof(x, y, &exponent)), 0);
-
- x = 1.0f;
- y = zero;
- EXPECT_NE(isnan(__llvm_libc::remquof(x, y, &exponent)), 0);
- y = negZero;
- EXPECT_NE(isnan(__llvm_libc::remquof(x, y, &exponent)), 0);
+#include "RemQuoTest.h"
- y = nan;
- x = 1.0f;
- EXPECT_NE(isnan(__llvm_libc::remquof(x, y, &exponent)), 0);
-
- y = 1.0f;
- x = nan;
- EXPECT_NE(isnan(__llvm_libc::remquof(x, y, &exponent)), 0);
-
- x = nan;
- y = nan;
- EXPECT_NE(isnan(__llvm_libc::remquof(x, y, &exponent)), 0);
-
- x = zero;
- y = 1.0f;
- EXPECT_FP_EQ(__llvm_libc::remquof(x, y, &exponent), zero);
-
- x = negZero;
- y = 1.0f;
- EXPECT_FP_EQ(__llvm_libc::remquof(x, y, &exponent), negZero);
-}
-
-TEST(RemquofTest, SubnormalRange) {
- constexpr UIntType count = 1000001;
- constexpr UIntType step =
- (FPBits::maxSubnormal - FPBits::minSubnormal) / count;
- for (UIntType v = FPBits::minSubnormal, w = FPBits::maxSubnormal;
- v <= FPBits::maxSubnormal && w >= FPBits::minSubnormal;
- v += step, w -= step) {
- float x = FPBits(v), y = FPBits(w);
- mpfr::BinaryOutput<float> result;
- mpfr::BinaryInput<float> input{x, y};
- result.f = __llvm_libc::remquof(x, y, &result.i);
- ASSERT_MPFR_MATCH(mpfr::Operation::RemQuo, input, result, 0.0);
- }
-}
+#include "src/math/remquof.h"
-TEST(RemquofTest, NormalRange) {
- constexpr UIntType count = 1000001;
- constexpr UIntType step = (FPBits::maxNormal - FPBits::minNormal) / count;
- for (UIntType v = FPBits::minNormal, w = FPBits::maxNormal;
- v <= FPBits::maxNormal && w >= FPBits::minNormal; v += step, w -= step) {
- float x = FPBits(v), y = FPBits(w);
- mpfr::BinaryOutput<float> result;
- mpfr::BinaryInput<float> input{x, y};
- result.f = __llvm_libc::remquof(x, y, &result.i);
- ASSERT_MPFR_MATCH(mpfr::Operation::RemQuo, input, result, 0.0);
- }
-}
+LIST_REMQUO_TESTS(float, __llvm_libc::remquof)
diff --git a/libc/test/src/math/remquol_test.cpp b/libc/test/src/math/remquol_test.cpp
index 1539aabead95..e4438e83fe18 100644
--- a/libc/test/src/math/remquol_test.cpp
+++ b/libc/test/src/math/remquol_test.cpp
@@ -6,88 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#include "src/math/remquol.h"
-#include "utils/FPUtil/BasicOperations.h"
-#include "utils/FPUtil/FPBits.h"
-#include "utils/FPUtil/TestHelpers.h"
-#include "utils/MPFRWrapper/MPFRUtils.h"
-#include "utils/UnitTest/Test.h"
-#include <math.h>
-
-using FPBits = __llvm_libc::fputil::FPBits<long double>;
-using UIntType = FPBits::UIntType;
-
-namespace mpfr = __llvm_libc::testing::mpfr;
-
-DECLARE_SPECIAL_CONSTANTS(long double)
-
-TEST(RemquolTest, SpecialNumbers) {
- int exponent;
- long double x, y;
-
- y = 1.0l;
- x = inf;
- EXPECT_NE(isnan(__llvm_libc::remquol(x, y, &exponent)), 0);
- x = negInf;
- EXPECT_NE(isnan(__llvm_libc::remquol(x, y, &exponent)), 0);
-
- x = 1.0l;
- y = zero;
- EXPECT_NE(isnan(__llvm_libc::remquol(x, y, &exponent)), 0);
- y = negZero;
- EXPECT_NE(isnan(__llvm_libc::remquol(x, y, &exponent)), 0);
+#include "RemQuoTest.h"
- y = nan;
- x = 1.0l;
- EXPECT_NE(isnan(__llvm_libc::remquol(x, y, &exponent)), 0);
-
- y = 1.0l;
- x = nan;
- EXPECT_NE(isnan(__llvm_libc::remquol(x, y, &exponent)), 0);
-
- x = nan;
- y = nan;
- EXPECT_NE(isnan(__llvm_libc::remquol(x, y, &exponent)), 0);
-
- x = zero;
- y = 1.0l;
- EXPECT_FP_EQ(__llvm_libc::remquol(x, y, &exponent), zero);
-
- x = negZero;
- y = 1.0l;
- EXPECT_FP_EQ(__llvm_libc::remquol(x, y, &exponent), negZero);
-}
-
-TEST(RemquolTest, SubnormalRange) {
- constexpr UIntType count = 1000001;
- constexpr UIntType step =
- (FPBits::maxSubnormal - FPBits::minSubnormal) / count;
- for (UIntType v = FPBits::minSubnormal, w = FPBits::maxSubnormal;
- v <= FPBits::maxSubnormal && w >= FPBits::minSubnormal;
- v += step, w -= step) {
- long double x = FPBits(v), y = FPBits(w);
- mpfr::BinaryOutput<long double> result;
- mpfr::BinaryInput<long double> input{x, y};
- result.f = __llvm_libc::remquol(x, y, &result.i);
- ASSERT_MPFR_MATCH(mpfr::Operation::RemQuo, input, result, 0.0);
- }
-}
+#include "src/math/remquol.h"
-TEST(RemquolTest, NormalRange) {
- constexpr UIntType count = 1000001;
- constexpr UIntType step = (FPBits::maxNormal - FPBits::minNormal) / count;
- for (UIntType v = FPBits::minNormal, w = FPBits::maxNormal;
- v <= FPBits::maxNormal && w >= FPBits::minNormal; v += step, w -= step) {
- long double x = FPBits(v), y = FPBits(w);
- mpfr::BinaryOutput<long double> result;
- result.f = __llvm_libc::remquol(x, y, &result.i);
- // In normal range on x86 platforms, the implicit 1 bit can be zero making
- // the numbers NaN. Hence we test for them separately.
- if (isnan(x) || isnan(y)) {
- ASSERT_NE(isnan(result.f), 0);
- } else {
- mpfr::BinaryInput<long double> input{x, y};
- ASSERT_MPFR_MATCH(mpfr::Operation::RemQuo, input, result, 0.0);
- }
- }
-}
+LIST_REMQUO_TESTS(long double, __llvm_libc::remquol)