-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[libc][math][c23] Add {,u}fromfp{,x}{,f,l,f128} functions #86003
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][c23] Add {,u}fromfp{,x}{,f,l,f128} functions #86003
Conversation
@llvm/pr-subscribers-libc Author: OverMighty (overmighty) ChangesFixes #85279. cc @lntue Patch is 143.85 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/86003.diff 63 Files Affected:
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index e8cf11266624a7..d17240ab8de521 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -383,6 +383,12 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.frexp
libc.src.math.frexpf
libc.src.math.frexpl
+ libc.src.math.fromfp
+ libc.src.math.fromfpf
+ libc.src.math.fromfpl
+ libc.src.math.fromfpx
+ libc.src.math.fromfpxf
+ libc.src.math.fromfpxl
libc.src.math.hypot
libc.src.math.hypotf
libc.src.math.ilogb
@@ -467,6 +473,12 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.trunc
libc.src.math.truncf
libc.src.math.truncl
+ libc.src.math.ufromfp
+ libc.src.math.ufromfpf
+ libc.src.math.ufromfpl
+ libc.src.math.ufromfpx
+ libc.src.math.ufromfpxf
+ libc.src.math.ufromfpxl
)
if(LIBC_TYPES_HAS_FLOAT128)
@@ -481,6 +493,8 @@ if(LIBC_TYPES_HAS_FLOAT128)
libc.src.math.fminf128
libc.src.math.fmodf128
libc.src.math.frexpf128
+ libc.src.math.fromfpf128
+ libc.src.math.fromfpxf128
libc.src.math.ilogbf128
libc.src.math.ldexpf128
libc.src.math.llogbf128
@@ -498,6 +512,8 @@ if(LIBC_TYPES_HAS_FLOAT128)
libc.src.math.roundf128
libc.src.math.sqrtf128
libc.src.math.truncf128
+ libc.src.math.ufromfpf128
+ libc.src.math.ufromfpxf128
)
endif()
diff --git a/libc/docs/math/index.rst b/libc/docs/math/index.rst
index d337d060fb5dd9..fa604faaec2ff0 100644
--- a/libc/docs/math/index.rst
+++ b/libc/docs/math/index.rst
@@ -181,6 +181,22 @@ Basic Operations
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| frexpf128 | |check| | |check| | | |check| | | | | | | | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
+| fromfp | |check| | | | | | | | | | | | |
++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
+| fromfpf | |check| | | | | | | | | | | | |
++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
+| fromfpl | |check| | | | | | | | | | | | |
++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
+| fromfpf128 | |check| | | | | | | | | | | | |
++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
+| fromfpx | |check| | | | | | | | | | | | |
++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
+| fromfpxf | |check| | | | | | | | | | | | |
++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
+| fromfpxl | |check| | | | | | | | | | | | |
++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
+| fromfpxf128 | |check| | | | | | | | | | | | |
++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| ilogb | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| ilogbf | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | |
@@ -339,6 +355,22 @@ Basic Operations
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
| truncf128 | |check| | |check| | | |check| | | | | | | | | |
+--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
+| ufromfp | |check| | | | | | | | | | | | |
++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
+| ufromfpf | |check| | | | | | | | | | | | |
++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
+| ufromfpl | |check| | | | | | | | | | | | |
++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
+| ufromfpf128 | |check| | | | | | | | | | | | |
++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
+| ufromfpx | |check| | | | | | | | | | | | |
++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
+| ufromfpxf | |check| | | | | | | | | | | | |
++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
+| ufromfpxl | |check| | | | | | | | | | | | |
++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
+| ufromfpxf128 | |check| | | | | | | | | | | | |
++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
Higher Math Functions
diff --git a/libc/include/llvm-libc-macros/math-macros.h b/libc/include/llvm-libc-macros/math-macros.h
index db8a4ea65bd69a..0d89f020ebb8e6 100644
--- a/libc/include/llvm-libc-macros/math-macros.h
+++ b/libc/include/llvm-libc-macros/math-macros.h
@@ -17,6 +17,12 @@
#define FP_SUBNORMAL 3
#define FP_NORMAL 4
+#define FP_INT_UPWARD 0
+#define FP_INT_DOWNWARD 1
+#define FP_INT_TOWARDZERO 2
+#define FP_INT_TONEARESTFROMZERO 3
+#define FP_INT_TONEAREST 4
+
#define MATH_ERRNO 1
#define MATH_ERREXCEPT 2
diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index 84d28cc3350304..5f425ba1120a23 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -352,6 +352,12 @@ def StdC : StandardSpec<"stdc"> {
Macro<"INFINITY">,
Macro<"NAN">,
+ Macro<"FP_INT_UPWARD">,
+ Macro<"FP_INT_DOWNWARD">,
+ Macro<"FP_INT_TOWARDZERO">,
+ Macro<"FP_INT_TONEARESTFROMZERO">,
+ Macro<"FP_INT_TONEAREST">,
+
Macro<"FP_ILOGB0">,
Macro<"FP_ILOGBNAN">,
@@ -414,6 +420,26 @@ def StdC : StandardSpec<"stdc"> {
FunctionSpec<"frexpl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<IntPtr>]>,
GuardedFunctionSpec<"frexpf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>, ArgSpec<IntPtr>], "LIBC_TYPES_HAS_FLOAT128">,
+ FunctionSpec<"fromfp", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>]>,
+ FunctionSpec<"fromfpf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>]>,
+ FunctionSpec<"fromfpl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>]>,
+ FunctionSpec<"fromfpf128", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>]>,
+
+ FunctionSpec<"fromfpx", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>]>,
+ FunctionSpec<"fromfpxf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>]>,
+ FunctionSpec<"fromfpxl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>]>,
+ FunctionSpec<"fromfpxf128", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>]>,
+
+ FunctionSpec<"ufromfp", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>]>,
+ FunctionSpec<"ufromfpf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>]>,
+ FunctionSpec<"ufromfpl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>]>,
+ FunctionSpec<"ufromfpf128", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>]>,
+
+ FunctionSpec<"ufromfpx", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>]>,
+ FunctionSpec<"ufromfpxf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>]>,
+ FunctionSpec<"ufromfpxl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>]>,
+ FunctionSpec<"ufromfpxf128", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<IntType>, ArgSpec<UnsignedIntType>]>,
+
FunctionSpec<"hypot", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<DoubleType>]>,
FunctionSpec<"hypotf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<FloatType>]>,
diff --git a/libc/src/__support/FPUtil/NearestIntegerOperations.h b/libc/src/__support/FPUtil/NearestIntegerOperations.h
index e890e38ba4ae7d..cef612f9263529 100644
--- a/libc/src/__support/FPUtil/NearestIntegerOperations.h
+++ b/libc/src/__support/FPUtil/NearestIntegerOperations.h
@@ -141,7 +141,7 @@ LIBC_INLINE T round(T x) {
}
template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
-LIBC_INLINE T round_using_current_rounding_mode(T x) {
+LIBC_INLINE constexpr T round_using_specific_rounding_mode(T x, int rnd) {
using StorageType = typename FPBits<T>::StorageType;
FPBits<T> bits(x);
@@ -151,7 +151,6 @@ LIBC_INLINE T round_using_current_rounding_mode(T x) {
bool is_neg = bits.is_neg();
int exponent = bits.get_exponent();
- int rounding_mode = quick_get_round();
// If the exponent is greater than the most negative mantissa
// exponent, then x is already an integer.
@@ -159,20 +158,23 @@ LIBC_INLINE T round_using_current_rounding_mode(T x) {
return x;
if (exponent <= -1) {
- switch (rounding_mode) {
- case FE_DOWNWARD:
+ switch (rnd) {
+ case FP_INT_DOWNWARD:
return is_neg ? T(-1.0) : T(0.0);
- case FE_UPWARD:
+ case FP_INT_UPWARD:
return is_neg ? T(-0.0) : T(1.0);
- case FE_TOWARDZERO:
+ case FP_INT_TOWARDZERO:
return is_neg ? T(-0.0) : T(0.0);
- case FE_TONEAREST:
+ case FP_INT_TONEARESTFROMZERO:
+ if (exponent < -1)
+ return is_neg ? T(-0.0) : T(0.0); // abs(x) < 0.5
+ return is_neg ? T(-1.0) : T(1.0); // abs(x) >= 0.5
+ case FP_INT_TONEAREST:
+ default:
if (exponent <= -2 || bits.get_mantissa() == 0)
return is_neg ? T(-0.0) : T(0.0); // abs(x) <= 0.5
else
return is_neg ? T(-1.0) : T(1.0); // abs(x) > 0.5
- default:
- __builtin_unreachable();
}
}
@@ -194,14 +196,19 @@ LIBC_INLINE T round_using_current_rounding_mode(T x) {
StorageType trunc_is_odd =
new_bits.get_mantissa() & (StorageType(1) << trim_size);
- switch (rounding_mode) {
- case FE_DOWNWARD:
+ switch (rnd) {
+ case FP_INT_DOWNWARD:
return is_neg ? trunc_value - T(1.0) : trunc_value;
- case FE_UPWARD:
+ case FP_INT_UPWARD:
return is_neg ? trunc_value : trunc_value + T(1.0);
- case FE_TOWARDZERO:
+ case FP_INT_TOWARDZERO:
return trunc_value;
- case FE_TONEAREST:
+ case FP_INT_TONEARESTFROMZERO:
+ if (trim_value >= half_value)
+ return is_neg ? trunc_value - T(1.0) : trunc_value + T(1.0);
+ return trunc_value;
+ case FP_INT_TONEAREST:
+ default:
if (trim_value > half_value) {
return is_neg ? trunc_value - T(1.0) : trunc_value + T(1.0);
} else if (trim_value == half_value) {
@@ -214,11 +221,66 @@ LIBC_INLINE T round_using_current_rounding_mode(T x) {
} else {
return trunc_value;
}
+ }
+}
+
+template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
+LIBC_INLINE T round_using_current_rounding_mode(T x) {
+ int rounding_mode = quick_get_round();
+
+ switch (rounding_mode) {
+ case FE_DOWNWARD:
+ return round_using_specific_rounding_mode(x, FP_INT_DOWNWARD);
+ case FE_UPWARD:
+ return round_using_specific_rounding_mode(x, FP_INT_UPWARD);
+ case FE_TOWARDZERO:
+ return round_using_specific_rounding_mode(x, FP_INT_TOWARDZERO);
+ case FE_TONEAREST:
+ return round_using_specific_rounding_mode(x, FP_INT_TONEAREST);
default:
__builtin_unreachable();
}
}
+template <bool IsSigned, typename T,
+ cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
+LIBC_INLINE constexpr T fromfp(T x, int rnd, unsigned int width) {
+ if (width == 0U)
+ return FPBits<T>::quiet_nan().get_val();
+
+ T rounded_value = round_using_specific_rounding_mode(x, rnd);
+
+ if constexpr (IsSigned) {
+ // T can't hold a finite number >= 2.0 * 2^EXP_BIAS.
+ if (width - 1 > FPBits<T>::EXP_BIAS)
+ return rounded_value;
+ if (rounded_value < -T(1U << (width - 1U)))
+ return FPBits<T>::quiet_nan().get_val();
+ if (rounded_value > T((1U << (width - 1U)) - 1U))
+ return FPBits<T>::quiet_nan().get_val();
+ return rounded_value;
+ }
+
+ if (rounded_value < T(0.0))
+ return FPBits<T>::quiet_nan().get_val();
+ // T can't hold a finite number >= 2.0 * 2^EXP_BIAS.
+ if (width <= FPBits<T>::EXP_BIAS && rounded_value > T(1U << width) - 1U)
+ return FPBits<T>::quiet_nan().get_val();
+ return rounded_value;
+}
+
+template <bool IsSigned, typename T,
+ cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
+LIBC_INLINE constexpr T fromfpx(T x, int rnd, unsigned int width) {
+ T rounded_value = fromfp<IsSigned>(x, rnd, width);
+ FPBits<T> bits(rounded_value);
+
+ if (!bits.is_nan() && rounded_value != x)
+ raise_except_if_required(FE_INEXACT);
+
+ return rounded_value;
+}
+
namespace internal {
template <typename F, typename I,
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index 5e2e6e699d0e0c..2f1d65780013f8 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -127,6 +127,16 @@ add_math_entrypoint_object(frexpf)
add_math_entrypoint_object(frexpl)
add_math_entrypoint_object(frexpf128)
+add_math_entrypoint_object(fromfp)
+add_math_entrypoint_object(fromfpf)
+add_math_entrypoint_object(fromfpl)
+add_math_entrypoint_object(fromfpf128)
+
+add_math_entrypoint_object(fromfpx)
+add_math_entrypoint_object(fromfpxf)
+add_math_entrypoint_object(fromfpxl)
+add_math_entrypoint_object(fromfpxf128)
+
add_math_entrypoint_object(hypot)
add_math_entrypoint_object(hypotf)
@@ -267,3 +277,13 @@ add_math_entrypoint_object(trunc)
add_math_entrypoint_object(truncf)
add_math_entrypoint_object(truncl)
add_math_entrypoint_object(truncf128)
+
+add_math_entrypoint_object(ufromfp)
+add_math_entrypoint_object(ufromfpf)
+add_math_entrypoint_object(ufromfpl)
+add_math_entrypoint_object(ufromfpf128)
+
+add_math_entrypoint_object(ufromfpx)
+add_math_entrypoint_object(ufromfpxf)
+add_math_entrypoint_object(ufromfpxl)
+add_math_entrypoint_object(ufromfpxf128)
diff --git a/libc/src/math/fromfp.h b/libc/src/math/fromfp.h
new file mode 100644
index 00000000000000..d3de2dd3460832
--- /dev/null
+++ b/libc/src/math/fromfp.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for fromfp ------------------------*- 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_FROMFP_H
+#define LLVM_LIBC_SRC_MATH_FROMFP_H
+
+namespace LIBC_NAMESPACE {
+
+double fromfp(double x, int rnd, unsigned int width);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FROMFP_H
diff --git a/libc/src/math/fromfpf.h b/libc/src/math/fromfpf.h
new file mode 100644
index 00000000000000..11d432148d0189
--- /dev/null
+++ b/libc/src/math/fromfpf.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for fromfpf -----------------------*- 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_FROMFPF_H
+#define LLVM_LIBC_SRC_MATH_FROMFPF_H
+
+namespace LIBC_NAMESPACE {
+
+float fromfpf(float x, int rnd, unsigned int width);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FROMFPF_H
diff --git a/libc/src/math/fromfpf128.h b/libc/src/math/fromfpf128.h
new file mode 100644
index 00000000000000..5f85fde570a0fb
--- /dev/null
+++ b/libc/src/math/fromfpf128.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for fromfpf128 --------------------*- 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_FROMFPF128_H
+#define LLVM_LIBC_SRC_MATH_FROMFPF128_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float128 fromfpf128(float128 x, int rnd, unsigned int width);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FROMFPF128_H
diff --git a/libc/src/math/fromfpl.h b/libc/src/math/fromfpl.h
new file mode 100644
index 00000000000000..dd8e1eebdea994
--- /dev/null
+++ b/libc/src/math/fromfpl.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for fromfpl -----------------------*- 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_FROMFPL_H
+#define LLVM_LIBC_SRC_MATH_FROMFPL_H
+
+namespace LIBC_NAMESPACE {
+
+long double fromfpl(long double x, int rnd, unsigned int width);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FROMFPL_H
diff --git a/libc/src/math/fromfpx.h b/libc/src/math/fromfpx.h
new file mode 100644
index 0000000000...
[truncated]
|
HDRS | ||
FromfpTest.h | ||
DEPENDS | ||
libc.src.math.fromfp |
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.
In my previous PR for nextup
and nextdown
I had added more dependencies: https://github.com/llvm/llvm-project/pull/85431/files#diff-2269fc16d8717f30b774875846f93f54879dae7515bdfd3dd5d5645fd7413aa7R1626-R1628.
Now that I think about it again, I assume that depending on libc.src.math.<func>
is enough to also depend on the header and dependencies declared in the add_entrypoint_object
call for the function in libc/src/math/generic/CMakeLists.txt.
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.
Yes, but include-what-you-use is always better, instead of completely relying on transitive dependence. So if your test directly calls something in those targets, it's always better to directly include them in our DEPENDS list.
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.
Right, but the nextup
and nextdown
tests only directly use libc.src.math.{nextup,nextdown}
and test/UnitTest/{FPMatcher.h,Test.h}, and add_fp_unittest
already takes care of the latter.
EXPECT_FP_EQ(aNaN, func(T(-1234.96), FP_INT_DOWNWARD, 11U)); | ||
} | ||
|
||
void testFractionsTowardZeroWithinRange(FromfpxFunc func) { |
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.
The formatting for the tests that use EXPECT_FP_EQ_WITH_EXCEPTION
isn't great with lines of different lengths triggering different wrap-arounds, but I'm not sure if it's a problem.
Note that FromfpxTest.h is pretty much a copy-paste of FromfpTest.h with testFractions*WithinRange
tests changed to use EXPECT_FP_EQ_WITH_EXCEPTION
. Same for UfromfpxTest.h vs UfromfpTest.h. I'm not sure if something should be done about this either.
I added tests for the fallback to |
libc/docs/dev/undefined_behavior.rst
Outdated
|
||
Unknown Math Rounding Direction | ||
------------------------------- | ||
The C standard states that if the value of the ``rnd`` argument of the |
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.
nit: C23
libc/src/math/generic/CMakeLists.txt
Outdated
libc.src.__support.macros.properties.types | ||
libc.src.__support.FPUtil.nearest_integer | ||
COMPILE_OPTIONS | ||
-O3 |
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.
nit: alignment
9616f21
to
ac71b02
Compare
Had to rebase as Bazel builds were broken before #86298. |
✅ With the latest revision this PR passed the C/C++ code formatter. |
✅ With the latest revision this PR passed the Python code formatter. |
@@ -141,7 +141,7 @@ LIBC_INLINE T round(T x) { | |||
} | |||
|
|||
template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0> | |||
LIBC_INLINE T round_using_current_rounding_mode(T x) { | |||
LIBC_INLINE constexpr T round_using_specific_rounding_mode(T x, int rnd) { |
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.
Since you are here, would you mind updating the enable_if
to be on the returning type instead:
template <typename T>
LIBC_INLINE constexpr typename cpp::enable_if_t<..., T> rounding_using_specific_rounding_mode() { ... }
Same for the other 2 functions below.
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.
CLion Nova warns about the typename
keyword before cpp::enable_if_t
being redundant.
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.
You can remove typename
before cpp::enable_if_t
if it's not needed.
Thanks for adding these functions! I'll merge the patch in the morning when I can watch the bots. |
LIBC_INLINE T round_using_current_rounding_mode(T x) { | ||
template <typename T> | ||
LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_floating_point_v<T>, T> | ||
round_using_specific_rounding_mode(T x, int rnd) { |
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.
Maybe this function should have been made static
or put in a namespace.
You're welcome. By the way, |
Addressed by #87678. |
Fixes #85279.
cc @lntue