Skip to content

[libc][math][c23] Add nextupl and nextdownl functions #85484

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

Merged
merged 2 commits into from
Mar 16, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions libc/config/linux/x86_64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -431,8 +431,10 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.nexttowardl
libc.src.math.nextdown
libc.src.math.nextdownf
libc.src.math.nextdownl
libc.src.math.nextup
libc.src.math.nextupf
libc.src.math.nextupl
libc.src.math.powf
libc.src.math.remainderf
libc.src.math.remainder
Expand Down
16 changes: 16 additions & 0 deletions libc/docs/math/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -275,12 +275,28 @@ Basic Operations
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| nextafterf128| |check| | |check| | | |check| | | | | | | | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| nextdown | |check| | | | | | | | | | | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| nextdownf | |check| | | | | | | | | | | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| nextdownl | |check| | | | | | | | | | | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| nextdownf128 | |check| | | | | | | | | | | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| nexttoward | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| nexttowardf | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| nexttowardl | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| nextup | |check| | | | | | | | | | | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| nextupf | |check| | | | | | | | | | | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| nextupl | |check| | | | | | | | | | | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| nextupf128 | |check| | | | | | | | | | | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
Comment on lines +278 to +299
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hadn't documented nextup{,f,f128} and nextdown{,f,f128} in #85431.

By the way, how exactly do you decide which targets to add entrypoints for? I only added entrypoints for Linux on x86-64 because that's what I develop on, but the current nextup* and nextdown* implementations should work on other targets too.

Copy link
Contributor

@lntue lntue Mar 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So in general, there are several things you can try:

  • For most of the generic functions for single, double, and long double, they should work everywhere. You can simply add them in your patch, and if you cannot test other architectures directly, you can watch our bots https://lab.llvm.org/buildbot/#/builders?tags=libc and get ready to fix-forward or back out the change if they failed.
  • For float128, so far we only tested that they work on x86-64, aarch64, and riscv-64, so normally you can just enable them for all 3, and watch the bots.
  • Some targets such as baremetal, windows, or macos we actually don't have working bots right now, so it's ok to skip them.
  • If you want to be on the safe side, you can simply only enable entrypoints for the targets that you can directly test in the initial PR, and then enable the other targets on a following PR, so that if it breaks other bots, you only need to rollback your second PR.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. I will enable other targets in a following PR.

| remainder | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| remainderf | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | |
Expand Down
2 changes: 2 additions & 0 deletions libc/spec/stdc.td
Original file line number Diff line number Diff line change
Expand Up @@ -538,10 +538,12 @@ def StdC : StandardSpec<"stdc"> {

FunctionSpec<"nextdown", RetValSpec<DoubleType>, [ArgSpec<DoubleType>]>,
FunctionSpec<"nextdownf", RetValSpec<FloatType>, [ArgSpec<FloatType>]>,
FunctionSpec<"nextdownl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>]>,
GuardedFunctionSpec<"nextdownf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT128">,

FunctionSpec<"nextup", RetValSpec<DoubleType>, [ArgSpec<DoubleType>]>,
FunctionSpec<"nextupf", RetValSpec<FloatType>, [ArgSpec<FloatType>]>,
FunctionSpec<"nextupl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>]>,
GuardedFunctionSpec<"nextupf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT128">,

FunctionSpec<"powf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<FloatType>]>,
Expand Down
1 change: 1 addition & 0 deletions libc/src/__support/FPUtil/ManipulationFunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ LIBC_INLINE constexpr T nextupdown(T x) {

#ifdef LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
#include "x86_64/NextAfterLongDouble.h"
#include "x86_64/NextUpDownLongDouble.h"
#endif // LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80

#endif // LLVM_LIBC_SRC___SUPPORT_FPUTIL_MANIPULATIONFUNCTIONS_H
56 changes: 56 additions & 0 deletions libc/src/__support/FPUtil/x86_64/NextUpDownLongDouble.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//===-- nextupdown implementation for x86 long double numbers ---*- 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___SUPPORT_FPUTIL_X86_64_NEXTUPDOWNLONGDOUBLE_H
#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_X86_64_NEXTUPDOWNLONGDOUBLE_H

#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/macros/attributes.h"
#include "src/__support/macros/properties/architectures.h"

#if !defined(LIBC_TARGET_ARCH_IS_X86)
#error "Invalid include"
#endif

namespace LIBC_NAMESPACE::fputil {

template <bool IsDown>
LIBC_INLINE constexpr long double nextupdown(long double x) {
constexpr Sign sign = IsDown ? Sign::NEG : Sign::POS;

using FPBits_t = FPBits<long double>;
FPBits_t xbits(x);
if (xbits.is_nan() || xbits == FPBits_t::max_normal(sign) ||
xbits == FPBits_t::inf(sign))
return x;

using StorageType = typename FPBits_t::StorageType;
if (x == 0.0l) {
xbits = FPBits_t::min_subnormal(sign);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably using early return can reduce the nested if-else a bit:

if (x == 0.0l)
  return FPBits_t::min_subnormal(sign).get_val();

if (xbits.sign() == sign) ...

} else if (xbits.sign() == sign) {
if (xbits.get_mantissa() == FPBits_t::FRACTION_MASK) {
xbits.set_mantissa(0);
xbits.set_biased_exponent(xbits.get_biased_exponent() + 1);
} else {
xbits = FPBits_t(StorageType(xbits.uintval() + 1));
}
} else {
if (xbits.get_mantissa() == 0) {
xbits.set_mantissa(FPBits_t::FRACTION_MASK);
xbits.set_biased_exponent(xbits.get_biased_exponent() - 1);
} else {
xbits = FPBits_t(StorageType(xbits.uintval() - 1));
}
}

return xbits.get_val();
}

} // namespace LIBC_NAMESPACE::fputil

#endif // LLVM_LIBC_SRC___SUPPORT_FPUTIL_X86_64_NEXTUPDOWNLONGDOUBLE_H
2 changes: 2 additions & 0 deletions libc/src/math/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -207,10 +207,12 @@ add_math_entrypoint_object(nexttowardl)

add_math_entrypoint_object(nextdown)
add_math_entrypoint_object(nextdownf)
add_math_entrypoint_object(nextdownl)
add_math_entrypoint_object(nextdownf128)

add_math_entrypoint_object(nextup)
add_math_entrypoint_object(nextupf)
add_math_entrypoint_object(nextupl)
add_math_entrypoint_object(nextupf128)

add_math_entrypoint_object(pow)
Expand Down
24 changes: 24 additions & 0 deletions libc/src/math/generic/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1890,6 +1890,18 @@ add_entrypoint_object(
-O3
)

add_entrypoint_object(
nextdownl
SRCS
nextdownl.cpp
HDRS
../nextdownl.h
DEPENDS
libc.src.__support.FPUtil.manipulation_functions
COMPILE_OPTIONS
-O3
)

add_entrypoint_object(
nextdownf
SRCS
Expand Down Expand Up @@ -1927,6 +1939,18 @@ add_entrypoint_object(
-O3
)

add_entrypoint_object(
nextupl
SRCS
nextupl.cpp
HDRS
../nextupl.h
DEPENDS
libc.src.__support.FPUtil.manipulation_functions
COMPILE_OPTIONS
-O3
)

add_entrypoint_object(
nextupf
SRCS
Expand Down
19 changes: 19 additions & 0 deletions libc/src/math/generic/nextdownl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//===-- Implementation of nextdownl 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/nextdownl.h"
#include "src/__support/FPUtil/ManipulationFunctions.h"
#include "src/__support/common.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(long double, nextdownl, (long double x)) {
return fputil::nextupdown</*IsDown=*/true>(x);
}

} // namespace LIBC_NAMESPACE
19 changes: 19 additions & 0 deletions libc/src/math/generic/nextupl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//===-- Implementation of nextupl 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/nextupl.h"
#include "src/__support/FPUtil/ManipulationFunctions.h"
#include "src/__support/common.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(long double, nextupl, (long double x)) {
return fputil::nextupdown</*IsDown=*/false>(x);
}

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/math/nextdownl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation header for nextdownl ---------------------*- 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_NEXTDOWNL_H
#define LLVM_LIBC_SRC_MATH_NEXTDOWNL_H

namespace LIBC_NAMESPACE {

long double nextdownl(long double x);

} // namespace LIBC_NAMESPACE

#endif // LLVM_LIBC_SRC_MATH_NEXTDOWNL_H
18 changes: 18 additions & 0 deletions libc/src/math/nextupl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation header for nextupl -----------------------*- 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_NEXTUPL_H
#define LLVM_LIBC_SRC_MATH_NEXTUPL_H

namespace LIBC_NAMESPACE {

long double nextupl(long double x);

} // namespace LIBC_NAMESPACE

#endif // LLVM_LIBC_SRC_MATH_NEXTUPL_H
28 changes: 28 additions & 0 deletions libc/test/src/math/smoke/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1658,6 +1658,20 @@ add_fp_unittest(
libc.src.__support.FPUtil.manipulation_functions
)

add_fp_unittest(
nextdownl_test
SUITE
libc-math-smoke-tests
SRCS
nextdownl_test.cpp
HDRS
NextDownTest.h
DEPENDS
libc.include.math
libc.src.math.nextdownl
libc.src.__support.FPUtil.manipulation_functions
)

add_fp_unittest(
nextdownf128_test
SUITE
Expand Down Expand Up @@ -1700,6 +1714,20 @@ add_fp_unittest(
libc.src.__support.FPUtil.manipulation_functions
)

add_fp_unittest(
nextupl_test
SUITE
libc-math-smoke-tests
SRCS
nextupl_test.cpp
HDRS
NextUpTest.h
DEPENDS
libc.include.math
libc.src.math.nextupl
libc.src.__support.FPUtil.manipulation_functions
)

add_fp_unittest(
nextupf128_test
SUITE
Expand Down
13 changes: 13 additions & 0 deletions libc/test/src/math/smoke/nextdownl_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//===-- Unittests for nextdownl -------------------------------------------===//
//
// 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 "NextDownTest.h"

#include "src/math/nextdownl.h"

LIST_NEXTDOWN_TESTS(long double, LIBC_NAMESPACE::nextdownl)
13 changes: 13 additions & 0 deletions libc/test/src/math/smoke/nextupl_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//===-- Unittests for nextupl ---------------------------------------------===//
//
// 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 "NextUpTest.h"

#include "src/math/nextupl.h"

LIST_NEXTUP_TESTS(long double, LIBC_NAMESPACE::nextupl)