New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[libc][math] Implement nexttoward functions #72763
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,12 +10,14 @@ | |
#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_MANIPULATIONFUNCTIONS_H | ||
|
||
#include "FPBits.h" | ||
#include "FloatProperties.h" | ||
#include "NearestIntegerOperations.h" | ||
#include "NormalFloat.h" | ||
#include "PlatformDefs.h" | ||
|
||
#include "src/__support/CPP/bit.h" | ||
#include "src/__support/CPP/type_traits.h" | ||
#include "src/__support/FPUtil/FEnvImpl.h" | ||
#include "src/__support/macros/attributes.h" | ||
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY | ||
|
||
|
@@ -169,8 +171,50 @@ LIBC_INLINE T nextafter(T from, T to) { | |
int_val = (to_bits.uintval() & sign_mask) + UIntType(1); | ||
} | ||
|
||
UIntType exponent_bits = int_val & FloatProperties<T>::EXPONENT_MASK; | ||
if (exponent_bits == UIntType(0)) | ||
raise_except_if_required(FE_UNDERFLOW | FE_INEXACT); | ||
else if (exponent_bits == FloatProperties<T>::EXPONENT_MASK) | ||
raise_except_if_required(FE_OVERFLOW | FE_INEXACT); | ||
|
||
return cpp::bit_cast<T>(int_val); | ||
} | ||
|
||
template <typename T> | ||
LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, T> | ||
nexttoward(T from, long double to) { | ||
FPBits<T> from_bits(from); | ||
if (from_bits.is_nan()) | ||
return from; | ||
|
||
FPBits<long double> to_bits(to); | ||
if (to_bits.is_nan()) | ||
return to; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm observing the following warnings when building
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That issue should be fixed by #73698. Are you on an updated checkout? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ah, thanks, slightly behind! |
||
|
||
if ((long double)from == to) | ||
return to; | ||
|
||
using UIntType = typename FPBits<T>::UIntType; | ||
UIntType int_val = from_bits.uintval(); | ||
if (from != T(0.0)) { | ||
if ((from < to) == (from > T(0.0))) { | ||
++int_val; | ||
} else { | ||
--int_val; | ||
} | ||
} else { | ||
int_val = FPBits<T>::MIN_SUBNORMAL; | ||
if (to_bits.get_sign()) | ||
int_val |= FloatProperties<T>::SIGN_MASK; | ||
} | ||
|
||
UIntType exponent_bits = int_val & FloatProperties<T>::EXPONENT_MASK; | ||
if (exponent_bits == UIntType(0)) | ||
raise_except_if_required(FE_UNDERFLOW | FE_INEXACT); | ||
else if (exponent_bits == FloatProperties<T>::EXPONENT_MASK) | ||
raise_except_if_required(FE_OVERFLOW | FE_INEXACT); | ||
|
||
return cpp::bit_cast<T>(int_val); | ||
// TODO: Raise floating point exceptions as required by the standard. | ||
} | ||
|
||
} // namespace fputil | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
//===-- Implementation of nexttoward function -----------------------------===// | ||
// | ||
// 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 "src/math/nexttoward.h" | ||
#include "src/__support/FPUtil/ManipulationFunctions.h" | ||
#include "src/__support/common.h" | ||
|
||
namespace LIBC_NAMESPACE { | ||
|
||
LLVM_LIBC_FUNCTION(double, nexttoward, (double x, long double y)) { | ||
return fputil::nexttoward(x, y); | ||
} | ||
|
||
} // namespace LIBC_NAMESPACE |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
//===-- Implementation of nexttowardf function ----------------------------===// | ||
// | ||
// 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 "src/math/nexttowardf.h" | ||
#include "src/__support/FPUtil/ManipulationFunctions.h" | ||
#include "src/__support/common.h" | ||
|
||
namespace LIBC_NAMESPACE { | ||
|
||
LLVM_LIBC_FUNCTION(float, nexttowardf, (float x, long double y)) { | ||
return fputil::nexttoward(x, y); | ||
} | ||
|
||
} // namespace LIBC_NAMESPACE |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
//===-- Implementation of nexttowardl function ----------------------------===// | ||
// | ||
// 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 "src/math/nexttowardl.h" | ||
#include "src/__support/FPUtil/ManipulationFunctions.h" | ||
#include "src/__support/common.h" | ||
|
||
namespace LIBC_NAMESPACE { | ||
|
||
LLVM_LIBC_FUNCTION(long double, nexttowardl, (long double x, long double y)) { | ||
// We can reuse the nextafter implementation because nexttoward behaves | ||
// exactly same as nextafter in case of long doubles. Also, we have explcitly | ||
// handled the special 80-bit long doubles in nextafter implementation. | ||
return fputil::nextafter(x, y); | ||
nishantwrp marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
} // namespace LIBC_NAMESPACE |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
//===-- Implementation header for nexttoward --------------------*- 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_SRC_MATH_NEXTTOWARD_H | ||
#define LLVM_LIBC_SRC_MATH_NEXTTOWARD_H | ||
|
||
namespace LIBC_NAMESPACE { | ||
|
||
double nexttoward(double x, long double y); | ||
|
||
} // namespace LIBC_NAMESPACE | ||
|
||
#endif // LLVM_LIBC_SRC_MATH_NEXTTOWARD_H |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
//===-- Implementation header for nexttowardf -------------------*- 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_SRC_MATH_NEXTTOWARDF_H | ||
#define LLVM_LIBC_SRC_MATH_NEXTTOWARDF_H | ||
|
||
namespace LIBC_NAMESPACE { | ||
|
||
float nexttowardf(float x, long double y); | ||
|
||
} // namespace LIBC_NAMESPACE | ||
|
||
#endif // LLVM_LIBC_SRC_MATH_NEXTTOWARDF_H |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
//===-- Implementation header for nexttowardl -------------------*- 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_SRC_MATH_NEXTTOWARDL_H | ||
#define LLVM_LIBC_SRC_MATH_NEXTTOWARDL_H | ||
|
||
namespace LIBC_NAMESPACE { | ||
|
||
long double nexttowardl(long double x, long double y); | ||
|
||
} // namespace LIBC_NAMESPACE | ||
|
||
#endif // LLVM_LIBC_SRC_MATH_NEXTTOWARDL_H |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should probably test the exceptions in the tests for nextafter too. Will do that in a separate pr?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SGTM. Thanks for fixing this TODO item.