42 changes: 42 additions & 0 deletions libc/src/math/generic/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ add_entrypoint_object(
-O3
DEPENDS
libc.src.__support.FPUtil.nearest_integer_operations
FLAGS
ROUND_OPT
)

add_entrypoint_object(
Expand All @@ -82,6 +84,8 @@ add_entrypoint_object(
-O3
DEPENDS
libc.src.__support.FPUtil.nearest_integer_operations
FLAGS
ROUND_OPT
)

add_entrypoint_object(
Expand All @@ -107,6 +111,9 @@ add_entrypoint_object(
DEPENDS
libc.src.__support.macros.properties.types
libc.src.__support.FPUtil.nearest_integer_operations
libc.src.__support.macros.properties.architectures
FLAGS
ROUND_OPT
)

add_entrypoint_object(
Expand Down Expand Up @@ -455,6 +462,8 @@ add_entrypoint_object(
-O3
DEPENDS
libc.src.__support.FPUtil.nearest_integer_operations
FLAGS
ROUND_OPT
)

add_entrypoint_object(
Expand All @@ -467,6 +476,8 @@ add_entrypoint_object(
-O3
DEPENDS
libc.src.__support.FPUtil.nearest_integer_operations
FLAGS
ROUND_OPT
)

add_entrypoint_object(
Expand All @@ -492,6 +503,9 @@ add_entrypoint_object(
DEPENDS
libc.src.__support.macros.properties.types
libc.src.__support.FPUtil.nearest_integer_operations
libc.src.__support.macros.properties.architectures
FLAGS
ROUND_OPT
)

add_entrypoint_object(
Expand All @@ -517,6 +531,8 @@ add_entrypoint_object(
-O3
DEPENDS
libc.src.__support.FPUtil.nearest_integer_operations
FLAGS
ROUND_OPT
)

add_entrypoint_object(
Expand All @@ -529,6 +545,8 @@ add_entrypoint_object(
-O3
DEPENDS
libc.src.__support.FPUtil.nearest_integer_operations
FLAGS
ROUND_OPT
)

add_entrypoint_object(
Expand All @@ -554,6 +572,9 @@ add_entrypoint_object(
DEPENDS
libc.src.__support.macros.properties.types
libc.src.__support.FPUtil.nearest_integer_operations
libc.src.__support.macros.properties.architectures
FLAGS
ROUND_OPT
)

add_entrypoint_object(
Expand All @@ -579,6 +600,8 @@ add_entrypoint_object(
-O3
DEPENDS
libc.src.__support.FPUtil.nearest_integer_operations
FLAGS
ROUND_OPT
)

add_entrypoint_object(
Expand All @@ -591,6 +614,8 @@ add_entrypoint_object(
-O3
DEPENDS
libc.src.__support.FPUtil.nearest_integer_operations
FLAGS
ROUND_OPT
)

add_entrypoint_object(
Expand All @@ -616,6 +641,9 @@ add_entrypoint_object(
DEPENDS
libc.src.__support.macros.properties.types
libc.src.__support.FPUtil.nearest_integer_operations
libc.src.__support.macros.properties.architectures
FLAGS
ROUND_OPT
)

add_entrypoint_object(
Expand All @@ -641,6 +669,8 @@ add_entrypoint_object(
-O3
DEPENDS
libc.src.__support.FPUtil.nearest_integer_operations
FLAGS
ROUND_OPT
)

add_entrypoint_object(
Expand All @@ -653,6 +683,8 @@ add_entrypoint_object(
-O3
DEPENDS
libc.src.__support.FPUtil.nearest_integer_operations
FLAGS
ROUND_OPT
)

add_entrypoint_object(
Expand All @@ -678,6 +710,9 @@ add_entrypoint_object(
DEPENDS
libc.src.__support.macros.properties.types
libc.src.__support.FPUtil.nearest_integer_operations
libc.src.__support.macros.properties.architectures
FLAGS
ROUND_OPT
)

add_entrypoint_object(
Expand Down Expand Up @@ -827,6 +862,8 @@ add_entrypoint_object(
-O3
DEPENDS
libc.src.__support.FPUtil.nearest_integer_operations
FLAGS
ROUND_OPT
)

add_entrypoint_object(
Expand All @@ -839,6 +876,8 @@ add_entrypoint_object(
-O3
DEPENDS
libc.src.__support.FPUtil.nearest_integer_operations
FLAGS
ROUND_OPT
)

add_entrypoint_object(
Expand All @@ -864,6 +903,9 @@ add_entrypoint_object(
DEPENDS
libc.src.__support.macros.properties.types
libc.src.__support.FPUtil.nearest_integer_operations
libc.src.__support.macros.properties.architectures
FLAGS
ROUND_OPT
)

add_entrypoint_object(
Expand Down
8 changes: 7 additions & 1 deletion libc/src/math/generic/ceil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(double, ceil, (double x)) { return fputil::ceil(x); }
LLVM_LIBC_FUNCTION(double, ceil, (double x)) {
#ifdef __LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC
return __builtin_ceil(x);
#else
return fputil::ceil(x);
#endif
}

} // namespace LIBC_NAMESPACE_DECL
8 changes: 7 additions & 1 deletion libc/src/math/generic/ceilf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(float, ceilf, (float x)) { return fputil::ceil(x); }
LLVM_LIBC_FUNCTION(float, ceilf, (float x)) {
#ifdef __LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC
return __builtin_ceilf(x);
#else
return fputil::ceil(x);
#endif
}

} // namespace LIBC_NAMESPACE_DECL
10 changes: 9 additions & 1 deletion libc/src/math/generic/ceilf16.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,17 @@
#include "src/__support/FPUtil/NearestIntegerOperations.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/properties/architectures.h"

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(float16, ceilf16, (float16 x)) { return fputil::ceil(x); }
LLVM_LIBC_FUNCTION(float16, ceilf16, (float16 x)) {
#if defined(__LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC) && \
defined(LIBC_TARGET_ARCH_IS_AARCH64)
return static_cast<float16>(__builtin_ceilf(x));
#else
return fputil::ceil(x);
#endif
}

} // namespace LIBC_NAMESPACE_DECL
8 changes: 7 additions & 1 deletion libc/src/math/generic/floor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(double, floor, (double x)) { return fputil::floor(x); }
LLVM_LIBC_FUNCTION(double, floor, (double x)) {
#ifdef __LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC
return __builtin_floor(x);
#else
return fputil::floor(x);
#endif
}

} // namespace LIBC_NAMESPACE_DECL
8 changes: 7 additions & 1 deletion libc/src/math/generic/floorf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(float, floorf, (float x)) { return fputil::floor(x); }
LLVM_LIBC_FUNCTION(float, floorf, (float x)) {
#ifdef __LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC
return __builtin_floorf(x);
#else
return fputil::floor(x);
#endif
}

} // namespace LIBC_NAMESPACE_DECL
10 changes: 9 additions & 1 deletion libc/src/math/generic/floorf16.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,17 @@
#include "src/__support/FPUtil/NearestIntegerOperations.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/properties/architectures.h"

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(float16, floorf16, (float16 x)) { return fputil::floor(x); }
LLVM_LIBC_FUNCTION(float16, floorf16, (float16 x)) {
#if defined(__LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC) && \
defined(LIBC_TARGET_ARCH_IS_AARCH64)
return static_cast<float16>(__builtin_floorf(x));
#else
return fputil::floor(x);
#endif
}

} // namespace LIBC_NAMESPACE_DECL
4 changes: 4 additions & 0 deletions libc/src/math/generic/rint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@
namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(double, rint, (double x)) {
#ifdef __LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC
return __builtin_rint(x);
#else
return fputil::round_using_current_rounding_mode(x);
#endif
}

} // namespace LIBC_NAMESPACE_DECL
4 changes: 4 additions & 0 deletions libc/src/math/generic/rintf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@
namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(float, rintf, (float x)) {
#ifdef __LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC
return __builtin_rintf(x);
#else
return fputil::round_using_current_rounding_mode(x);
#endif
}

} // namespace LIBC_NAMESPACE_DECL
6 changes: 6 additions & 0 deletions libc/src/math/generic/rintf16.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,17 @@
#include "src/__support/FPUtil/NearestIntegerOperations.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/properties/architectures.h"

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(float16, rintf16, (float16 x)) {
#if defined(__LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC) && \
defined(LIBC_TARGET_ARCH_IS_AARCH64)
return static_cast<float16>(__builtin_rintf(x));
#else
return fputil::round_using_current_rounding_mode(x);
#endif
}

} // namespace LIBC_NAMESPACE_DECL
8 changes: 7 additions & 1 deletion libc/src/math/generic/round.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(double, round, (double x)) { return fputil::round(x); }
LLVM_LIBC_FUNCTION(double, round, (double x)) {
#ifdef __LIBC_USE_BUILTIN_ROUND
return __builtin_round(x);
#else
return fputil::round(x);
#endif
}

} // namespace LIBC_NAMESPACE_DECL
4 changes: 4 additions & 0 deletions libc/src/math/generic/roundeven.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@
namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(double, roundeven, (double x)) {
#ifdef __LIBC_USE_BUILTIN_ROUNDEVEN
return __builtin_roundeven(x);
#else
return fputil::round_using_specific_rounding_mode(x, FP_INT_TONEAREST);
#endif
}

} // namespace LIBC_NAMESPACE_DECL
4 changes: 4 additions & 0 deletions libc/src/math/generic/roundevenf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@
namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(float, roundevenf, (float x)) {
#ifdef __LIBC_USE_BUILTIN_ROUNDEVEN
return __builtin_roundevenf(x);
#else
return fputil::round_using_specific_rounding_mode(x, FP_INT_TONEAREST);
#endif
}

} // namespace LIBC_NAMESPACE_DECL
6 changes: 6 additions & 0 deletions libc/src/math/generic/roundevenf16.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,17 @@
#include "src/__support/FPUtil/NearestIntegerOperations.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/properties/architectures.h"

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(float16, roundevenf16, (float16 x)) {
#if defined(__LIBC_USE_BUILTIN_ROUNDEVEN) && \
defined(LIBC_TARGET_ARCH_IS_AARCH64)
return static_cast<float16>(__builtin_roundevenf(x));
#else
return fputil::round_using_specific_rounding_mode(x, FP_INT_TONEAREST);
#endif
}

} // namespace LIBC_NAMESPACE_DECL
8 changes: 7 additions & 1 deletion libc/src/math/generic/roundf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(float, roundf, (float x)) { return fputil::round(x); }
LLVM_LIBC_FUNCTION(float, roundf, (float x)) {
#ifdef __LIBC_USE_BUILTIN_ROUND
return __builtin_roundf(x);
#else
return fputil::round(x);
#endif
}

} // namespace LIBC_NAMESPACE_DECL
9 changes: 8 additions & 1 deletion libc/src/math/generic/roundf16.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,16 @@
#include "src/__support/FPUtil/NearestIntegerOperations.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/properties/architectures.h"

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(float16, roundf16, (float16 x)) { return fputil::round(x); }
LLVM_LIBC_FUNCTION(float16, roundf16, (float16 x)) {
#if defined(__LIBC_USE_BUILTIN_ROUND) && defined(LIBC_TARGET_ARCH_IS_AARCH64)
return static_cast<float16>(__builtin_roundf(x));
#else
return fputil::round(x);
#endif
}

} // namespace LIBC_NAMESPACE_DECL
8 changes: 7 additions & 1 deletion libc/src/math/generic/trunc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(double, trunc, (double x)) { return fputil::trunc(x); }
LLVM_LIBC_FUNCTION(double, trunc, (double x)) {
#ifdef __LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC
return __builtin_trunc(x);
#else
return fputil::trunc(x);
#endif
}

} // namespace LIBC_NAMESPACE_DECL
8 changes: 7 additions & 1 deletion libc/src/math/generic/truncf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(float, truncf, (float x)) { return fputil::trunc(x); }
LLVM_LIBC_FUNCTION(float, truncf, (float x)) {
#ifdef __LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC
return __builtin_truncf(x);
#else
return fputil::trunc(x);
#endif
}

} // namespace LIBC_NAMESPACE_DECL
10 changes: 9 additions & 1 deletion libc/src/math/generic/truncf16.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,17 @@
#include "src/__support/FPUtil/NearestIntegerOperations.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/properties/architectures.h"

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(float16, truncf16, (float16 x)) { return fputil::trunc(x); }
LLVM_LIBC_FUNCTION(float16, truncf16, (float16 x)) {
#if defined(__LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC) && \
defined(LIBC_TARGET_ARCH_IS_AARCH64)
return static_cast<float16>(__builtin_truncf(x));
#else
return fputil::trunc(x);
#endif
}

} // namespace LIBC_NAMESPACE_DECL
16 changes: 12 additions & 4 deletions libc/test/src/math/performance_testing/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ function(add_perf_binary target_name)
"PERF"
"" # No optional arguments
"SUITE;CXX_STANDARD" # Single value arguments
"SRCS;HDRS;DEPENDS;COMPILE_OPTIONS" # Multi-value arguments
"SRCS;HDRS;DEPENDS;COMPILE_OPTIONS;LINK_LIBRARIES" # Multi-value arguments
${ARGN}
)
if(NOT PERF_SRCS)
Expand Down Expand Up @@ -64,9 +64,13 @@ function(add_perf_binary target_name)
)
endif()

set(link_libraries ${link_object_files})
foreach(lib IN LISTS PERF_LINK_LIBRARIES)
list(APPEND link_libraries ${lib}.unit)
endforeach()
target_link_libraries(
${fq_target_name}
PRIVATE ${link_object_files} libc_diff_test_utils)
PRIVATE ${link_libraries} libc_diff_test_utils)

set_target_properties(${fq_target_name}
PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
Expand Down Expand Up @@ -385,12 +389,16 @@ add_perf_binary(
libc.src.math.ceilf16
libc.src.math.floorf
libc.src.math.floorf16
libc.src.math.roundevenf
libc.src.math.roundevenf16
libc.src.math.rintf
libc.src.math.rintf16
libc.src.math.roundf
libc.src.math.roundf16
libc.src.math.roundevenf
libc.src.math.roundevenf16
libc.src.math.truncf
libc.src.math.truncf16
COMPILE_OPTIONS
-fno-builtin
LINK_LIBRARIES
LibcFPTestHelpers
)
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,23 @@
#include "src/math/ceilf16.h"
#include "src/math/floorf.h"
#include "src/math/floorf16.h"
#include "src/math/rintf.h"
#include "src/math/rintf16.h"
#include "src/math/roundevenf.h"
#include "src/math/roundevenf16.h"
#include "src/math/roundf.h"
#include "src/math/roundf16.h"
#include "src/math/truncf.h"
#include "src/math/truncf16.h"
#include "test/UnitTest/RoundingModeUtils.h"
#include "test/src/math/performance_testing/Timer.h"

#include <fstream>
#include <math.h>

using LIBC_NAMESPACE::fputil::testing::ForceRoundingMode;
using LIBC_NAMESPACE::fputil::testing::RoundingMode;

namespace LIBC_NAMESPACE::testing {

template <typename T> class NearestIntegerPerf {
Expand All @@ -36,7 +42,7 @@ template <typename T> class NearestIntegerPerf {
StorageType ending_bit, StorageType step,
size_t rounds, std::ofstream &log) {
auto runner = [=](Func func) {
volatile T result;
[[maybe_unused]] volatile T result;
for (size_t i = 0; i < rounds; i++) {
for (StorageType bits = starting_bit; bits <= ending_bit;
bits += step) {
Expand Down Expand Up @@ -146,23 +152,48 @@ int main() {
FLOAT16_ROUNDS, "ceilf16_perf.log")
NEAREST_INTEGER_PERF(float16, LIBC_NAMESPACE::floorf16, ::placeholderf16,
FLOAT16_ROUNDS, "floorf16_perf.log")
NEAREST_INTEGER_PERF(float16, LIBC_NAMESPACE::roundevenf16, ::placeholderf16,
FLOAT16_ROUNDS, "roundevenf16_perf.log")
NEAREST_INTEGER_PERF(float16, LIBC_NAMESPACE::roundf16, ::placeholderf16,
FLOAT16_ROUNDS, "roundf16_perf.log")
NEAREST_INTEGER_PERF(float16, LIBC_NAMESPACE::roundevenf16, ::placeholderf16,
FLOAT16_ROUNDS, "roundevenf16_perf.log")
NEAREST_INTEGER_PERF(float16, LIBC_NAMESPACE::truncf16, ::placeholderf16,
FLOAT16_ROUNDS, "truncf16_perf.log")

NEAREST_INTEGER_PERF(float, LIBC_NAMESPACE::ceilf, ::ceilf, FLOAT_ROUNDS,
"ceilf_perf.log")
NEAREST_INTEGER_PERF(float, LIBC_NAMESPACE::floorf, ::floorf, FLOAT_ROUNDS,
"floorf_perf.log")
NEAREST_INTEGER_PERF(float, LIBC_NAMESPACE::roundevenf, ::placeholderf,
FLOAT_ROUNDS, "roundevenf_perf.log")
NEAREST_INTEGER_PERF(float, LIBC_NAMESPACE::roundf, ::roundf, FLOAT_ROUNDS,
"roundf_perf.log")
NEAREST_INTEGER_PERF(float, LIBC_NAMESPACE::roundevenf, ::placeholderf,
FLOAT_ROUNDS, "roundevenf_perf.log")
NEAREST_INTEGER_PERF(float, LIBC_NAMESPACE::truncf, ::truncf, FLOAT_ROUNDS,
"truncf_perf.log")

if (ForceRoundingMode r(RoundingMode::Upward); r.success) {
NEAREST_INTEGER_PERF(float16, LIBC_NAMESPACE::rintf16, ::placeholderf16,
FLOAT16_ROUNDS, "rintf16_upward_perf.log")
NEAREST_INTEGER_PERF(float, LIBC_NAMESPACE::rintf, ::rintf, FLOAT_ROUNDS,
"rintf_upward_perf.log")
}
if (ForceRoundingMode r(RoundingMode::Downward); r.success) {
NEAREST_INTEGER_PERF(float16, LIBC_NAMESPACE::rintf16, ::placeholderf16,
FLOAT16_ROUNDS, "rintf16_downward_perf.log")
NEAREST_INTEGER_PERF(float, LIBC_NAMESPACE::rintf, ::rintf, FLOAT_ROUNDS,
"rintf_downward_perf.log")
}
if (ForceRoundingMode r(RoundingMode::TowardZero); r.success) {
NEAREST_INTEGER_PERF(float16, LIBC_NAMESPACE::rintf16, ::placeholderf16,
FLOAT16_ROUNDS, "rintf16_towardzero_perf.log")
NEAREST_INTEGER_PERF(float, LIBC_NAMESPACE::rintf, ::rintf, FLOAT_ROUNDS,
"rintf_towardzero_perf.log")
}
if (ForceRoundingMode r(RoundingMode::Nearest); r.success) {
NEAREST_INTEGER_PERF(float16, LIBC_NAMESPACE::rintf16, ::placeholderf16,
FLOAT16_ROUNDS, "rintf16_nearest_perf.log")
NEAREST_INTEGER_PERF(float, LIBC_NAMESPACE::rintf, ::rintf, FLOAT_ROUNDS,
"rintf_nearest_perf.log")
}

return 0;
}