[libc-commits] [PATCH] D114726: [libc] Fix bugs with negative and mixed normal/denormal inputs in hypot implementation.
Tue Ly via Phabricator via libc-commits
libc-commits at lists.llvm.org
Fri Dec 3 07:14:30 PST 2021
lntue updated this revision to Diff 391634.
lntue added a comment.
[libc] Fix bugs with negative and mixed normal/denormal inputs in hypot implementation.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D114726/new/
https://reviews.llvm.org/D114726
Files:
libc/src/__support/FPUtil/Hypot.h
libc/test/src/math/HypotTest.h
Index: libc/test/src/math/HypotTest.h
===================================================================
--- libc/test/src/math/HypotTest.h
+++ libc/test/src/math/HypotTest.h
@@ -47,28 +47,47 @@
void testSubnormalRange(Func 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 = T(FPBits(v)), y = T(FPBits(w));
- T result = func(x, y);
- mpfr::BinaryInput<T> input{x, y};
- ASSERT_MPFR_MATCH(mpfr::Operation::Hypot, input, result, 0.5);
+ for (unsigned scale = 0; scale < 4; ++scale) {
+ UIntType maxValue = FPBits::maxSubnormal << scale;
+ UIntType step = (maxValue - FPBits::minSubnormal) / count;
+ for (int signs = 0; signs < 4; ++signs) {
+ for (UIntType v = FPBits::minSubnormal, w = maxValue;
+ v <= maxValue && w >= FPBits::minSubnormal; v += step, w -= step) {
+ T x = T(FPBits(v)), y = T(FPBits(w));
+ if (signs % 2 == 1) {
+ x = -x;
+ }
+ if (signs >= 2) {
+ y = -y;
+ }
+
+ T result = func(x, y);
+ mpfr::BinaryInput<T> input{x, y};
+ ASSERT_MPFR_MATCH(mpfr::Operation::Hypot, input, result, 0.5);
+ }
+ }
}
}
void testNormalRange(Func 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 = T(FPBits(v)), y = T(FPBits(w));
- T result = func(x, y);
- mpfr::BinaryInput<T> input{x, y};
- ASSERT_MPFR_MATCH(mpfr::Operation::Hypot, input, result, 0.5);
+ for (int signs = 0; signs < 4; ++signs) {
+ for (UIntType v = FPBits::minNormal, w = FPBits::maxNormal;
+ v <= FPBits::maxNormal && w >= FPBits::minNormal;
+ v += step, w -= step) {
+ T x = T(FPBits(v)), y = T(FPBits(w));
+ if (signs % 2 == 1) {
+ x = -x;
+ }
+ if (signs >= 2) {
+ y = -y;
+ }
+
+ T result = func(x, y);
+ mpfr::BinaryInput<T> input{x, y};
+ ASSERT_MPFR_MATCH(mpfr::Operation::Hypot, input, result, 0.5);
+ }
}
}
};
Index: libc/src/__support/FPUtil/Hypot.h
===================================================================
--- libc/src/__support/FPUtil/Hypot.h
+++ libc/src/__support/FPUtil/Hypot.h
@@ -150,7 +150,7 @@
return abs(y);
}
- if (x >= y) {
+ if (abs(x) >= abs(y)) {
a_exp = x_bits.getUnbiasedExponent();
a_mant = x_bits.getMantissa();
b_exp = y_bits.getUnbiasedExponent();
@@ -178,10 +178,13 @@
y_mant_width = MantissaWidth<T>::value + 1;
} else {
leading_one = internal::findLeadingOne(a_mant, y_mant_width);
+ a_exp = 1;
}
if (b_exp != 0) {
b_mant |= one;
+ } else {
+ b_exp = 1;
}
a_mant_sq = static_cast<DUIntType>(a_mant) * a_mant;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D114726.391634.patch
Type: text/x-patch
Size: 3226 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libc-commits/attachments/20211203/026eff5d/attachment.bin>
More information about the libc-commits
mailing list