[libc-commits] [libc] [libc][math] Optimize nearest integer functions using builtins when available (PR #98376)
via libc-commits
libc-commits at lists.llvm.org
Fri Jul 12 11:52:54 PDT 2024
https://github.com/overmighty updated https://github.com/llvm/llvm-project/pull/98376
>From 50f1237543a1c08fb56c039370587f2fa0441936 Mon Sep 17 00:00:00 2001
From: OverMighty <its.overmighty at gmail.com>
Date: Wed, 10 Jul 2024 20:41:57 +0200
Subject: [PATCH 1/5] [libc][math] Optimize nearest integer functions using
builtins when available
---
.../cmake/modules/CheckCompilerFeatures.cmake | 26 ++++++++++++--
.../modules/LLVMLibCCompileOptionRules.cmake | 20 +++++++++--
libc/cmake/modules/LLVMLibCFlagRules.cmake | 3 +-
.../check_builtin_ceil_floor_trunc.cpp | 9 +++++
.../compiler_features/check_builtin_round.cpp | 5 +++
.../check_builtin_roundeven.cpp | 5 +++
libc/src/math/generic/CMakeLists.txt | 35 +++++++++++++++++++
libc/src/math/generic/ceil.cpp | 8 ++++-
libc/src/math/generic/ceilf.cpp | 8 ++++-
libc/src/math/generic/ceilf16.cpp | 10 +++++-
libc/src/math/generic/floor.cpp | 8 ++++-
libc/src/math/generic/floorf.cpp | 8 ++++-
libc/src/math/generic/floorf16.cpp | 10 +++++-
libc/src/math/generic/round.cpp | 8 ++++-
libc/src/math/generic/roundeven.cpp | 4 +++
libc/src/math/generic/roundevenf.cpp | 4 +++
libc/src/math/generic/roundevenf16.cpp | 6 ++++
libc/src/math/generic/roundf.cpp | 8 ++++-
libc/src/math/generic/roundf16.cpp | 9 ++++-
libc/src/math/generic/trunc.cpp | 8 ++++-
libc/src/math/generic/truncf.cpp | 8 ++++-
libc/src/math/generic/truncf16.cpp | 10 +++++-
22 files changed, 202 insertions(+), 18 deletions(-)
create mode 100644 libc/cmake/modules/compiler_features/check_builtin_ceil_floor_trunc.cpp
create mode 100644 libc/cmake/modules/compiler_features/check_builtin_round.cpp
create mode 100644 libc/cmake/modules/compiler_features/check_builtin_roundeven.cpp
diff --git a/libc/cmake/modules/CheckCompilerFeatures.cmake b/libc/cmake/modules/CheckCompilerFeatures.cmake
index d84c07b35d2d7..83822892c8096 100644
--- a/libc/cmake/modules/CheckCompilerFeatures.cmake
+++ b/libc/cmake/modules/CheckCompilerFeatures.cmake
@@ -2,7 +2,15 @@
# Compiler features definition and flags
# ------------------------------------------------------------------------------
-set(ALL_COMPILER_FEATURES "float16" "float128" "fixed_point")
+set(
+ ALL_COMPILER_FEATURES
+ "builtin_ceil_floor_trunc"
+ "builtin_round"
+ "builtin_roundeven"
+ "float16"
+ "float128"
+ "fixed_point"
+)
# Making sure ALL_COMPILER_FEATURES is sorted.
list(SORT ALL_COMPILER_FEATURES)
@@ -39,11 +47,19 @@ endfunction()
set(AVAILABLE_COMPILER_FEATURES "")
# Try compile a C file to check if flag is supported.
-set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
foreach(feature IN LISTS ALL_COMPILER_FEATURES)
+ set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
set(compile_options ${LIBC_COMPILE_OPTIONS_NATIVE})
if(${feature} STREQUAL "fixed_point")
list(APPEND compile_options "-ffixed-point")
+ elseif(${feature} MATCHES "^builtin_")
+ set(compile_options ${LIBC_COMPILE_OPTIONS_DEFAULT})
+ # The compiler might handle calls to rounding builtins by generating calls
+ # to the respective libc math functions, in which case we cannot use these
+ # builtins in our implementations of these functions. We check that this is
+ # not the case by trying to link an executable, since linking would fail due
+ # to unresolved references if calls to libc functions were generated.
+ set(CMAKE_TRY_COMPILE_TARGET_TYPE EXECUTABLE)
endif()
try_compile(
@@ -60,6 +76,12 @@ foreach(feature IN LISTS ALL_COMPILER_FEATURES)
set(LIBC_TYPES_HAS_FLOAT128 TRUE)
elseif(${feature} STREQUAL "fixed_point")
set(LIBC_COMPILER_HAS_FIXED_POINT TRUE)
+ elseif(${feature} STREQUAL "builtin_ceil_floor_trunc")
+ set(LIBC_COMPILER_HAS_BUILTIN_CEIL_FLOOR_TRUNC TRUE)
+ elseif(${feature} STREQUAL "builtin_round")
+ set(LIBC_COMPILER_HAS_BUILTIN_ROUND TRUE)
+ elseif(${feature} STREQUAL "builtin_roundeven")
+ set(LIBC_COMPILER_HAS_BUILTIN_ROUNDEVEN TRUE)
endif()
endif()
endforeach()
diff --git a/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake b/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake
index c5e7dfe8abd0f..855d69d2a0fc9 100644
--- a/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake
+++ b/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake
@@ -4,7 +4,7 @@ function(_get_compile_options_from_flags output_var)
if(LIBC_TARGET_ARCHITECTURE_IS_RISCV64 OR(LIBC_CPU_FEATURES MATCHES "FMA"))
check_flag(ADD_FMA_FLAG ${FMA_OPT_FLAG} ${ARGN})
endif()
- check_flag(ADD_SSE4_2_FLAG ${ROUND_OPT_FLAG} ${ARGN})
+ check_flag(ADD_ROUND_OPT_FLAG ${ROUND_OPT_FLAG} ${ARGN})
check_flag(ADD_EXPLICIT_SIMD_OPT_FLAG ${EXPLICIT_SIMD_OPT_FLAG} ${ARGN})
if(LLVM_COMPILER_IS_GCC_COMPATIBLE)
@@ -16,8 +16,22 @@ function(_get_compile_options_from_flags output_var)
list(APPEND compile_options "-D__LIBC_RISCV_USE_FMA")
endif()
endif()
- if(ADD_SSE4_2_FLAG)
- list(APPEND compile_options "-msse4.2")
+ if(ADD_ROUND_OPT_FLAG)
+ if(LIBC_TARGET_ARCHITECTURE_IS_X86)
+ # ROUND_OPT_FLAG is only enabled if SSE4.2 is detected, not just SSE4.1,
+ # because there was code to check for SSE4.2 already, and few CPUs only
+ # have SSE4.1.
+ list(APPEND compile_options "-msse4.2")
+ endif()
+ if(LIBC_COMPILER_HAS_BUILTIN_CEIL_FLOOR_TRUNC)
+ list(APPEND compile_options "-D__LIBC_USE_BUILTIN_CEIL_FLOOR_TRUNC")
+ endif()
+ if(LIBC_COMPILER_HAS_BUILTIN_ROUND)
+ list(APPEND compile_options "-D__LIBC_USE_BUILTIN_ROUND")
+ endif()
+ if(LIBC_COMPILER_HAS_BUILTIN_ROUNDEVEN)
+ list(APPEND compile_options "-D__LIBC_USE_BUILTIN_ROUNDEVEN")
+ endif()
endif()
if(ADD_EXPLICIT_SIMD_OPT_FLAG)
list(APPEND compile_options "-D__LIBC_EXPLICIT_SIMD_OPT")
diff --git a/libc/cmake/modules/LLVMLibCFlagRules.cmake b/libc/cmake/modules/LLVMLibCFlagRules.cmake
index 18e36dfde5cc1..eca7ba8d183e6 100644
--- a/libc/cmake/modules/LLVMLibCFlagRules.cmake
+++ b/libc/cmake/modules/LLVMLibCFlagRules.cmake
@@ -277,6 +277,7 @@ if(NOT(LIBC_TARGET_ARCHITECTURE_IS_X86 AND (LIBC_CPU_FEATURES MATCHES "SSE2")))
endif()
# Skip ROUND_OPT flag for targets that don't support SSE 4.2.
-if(NOT(LIBC_TARGET_ARCHITECTURE_IS_X86 AND (LIBC_CPU_FEATURES MATCHES "SSE4_2")))
+if(NOT((LIBC_TARGET_ARCHITECTURE_IS_X86 AND (LIBC_CPU_FEATURES MATCHES "SSE4_2")) OR
+ LIBC_TARGET_ARCHITECTURE_IS_AARCH64))
set(SKIP_FLAG_EXPANSION_ROUND_OPT TRUE)
endif()
diff --git a/libc/cmake/modules/compiler_features/check_builtin_ceil_floor_trunc.cpp b/libc/cmake/modules/compiler_features/check_builtin_ceil_floor_trunc.cpp
new file mode 100644
index 0000000000000..031dd9376f3c1
--- /dev/null
+++ b/libc/cmake/modules/compiler_features/check_builtin_ceil_floor_trunc.cpp
@@ -0,0 +1,9 @@
+float try_builtin_ceilf(float x) { return __builtin_ceilf(x); }
+float try_builtin_floorf(float x) { return __builtin_ceilf(x); }
+float try_builtin_truncf(float x) { return __builtin_truncf(x); }
+
+double try_builtin_ceil(double x) { return __builtin_ceil(x); }
+double try_builtin_floor(double x) { return __builtin_ceil(x); }
+double try_builtin_trunc(double x) { return __builtin_trunc(x); }
+
+int main() {}
diff --git a/libc/cmake/modules/compiler_features/check_builtin_round.cpp b/libc/cmake/modules/compiler_features/check_builtin_round.cpp
new file mode 100644
index 0000000000000..8c3065c2de06a
--- /dev/null
+++ b/libc/cmake/modules/compiler_features/check_builtin_round.cpp
@@ -0,0 +1,5 @@
+float try_builtin_roundf(float x) { return __builtin_roundf(x); }
+
+double try_builtin_round(double x) { return __builtin_round(x); }
+
+int main() {}
diff --git a/libc/cmake/modules/compiler_features/check_builtin_roundeven.cpp b/libc/cmake/modules/compiler_features/check_builtin_roundeven.cpp
new file mode 100644
index 0000000000000..2480abae84c36
--- /dev/null
+++ b/libc/cmake/modules/compiler_features/check_builtin_roundeven.cpp
@@ -0,0 +1,5 @@
+float try_builtin_roundevenf(float x) { return __builtin_roundevenf(x); }
+
+double try_builtin_roundeven(double x) { return __builtin_roundeven(x); }
+
+int main() {}
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index 5e920307d39de..915fc076826f9 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -70,6 +70,8 @@ add_entrypoint_object(
-O3
DEPENDS
libc.src.__support.FPUtil.nearest_integer_operations
+ FLAGS
+ ROUND_OPT
)
add_entrypoint_object(
@@ -82,6 +84,8 @@ add_entrypoint_object(
-O3
DEPENDS
libc.src.__support.FPUtil.nearest_integer_operations
+ FLAGS
+ ROUND_OPT
)
add_entrypoint_object(
@@ -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(
@@ -455,6 +462,8 @@ add_entrypoint_object(
-O3
DEPENDS
libc.src.__support.FPUtil.nearest_integer_operations
+ FLAGS
+ ROUND_OPT
)
add_entrypoint_object(
@@ -467,6 +476,8 @@ add_entrypoint_object(
-O3
DEPENDS
libc.src.__support.FPUtil.nearest_integer_operations
+ FLAGS
+ ROUND_OPT
)
add_entrypoint_object(
@@ -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(
@@ -517,6 +531,8 @@ add_entrypoint_object(
-O3
DEPENDS
libc.src.__support.FPUtil.nearest_integer_operations
+ FLAGS
+ ROUND_OPT
)
add_entrypoint_object(
@@ -529,6 +545,8 @@ add_entrypoint_object(
-O3
DEPENDS
libc.src.__support.FPUtil.nearest_integer_operations
+ FLAGS
+ ROUND_OPT
)
add_entrypoint_object(
@@ -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(
@@ -579,6 +600,8 @@ add_entrypoint_object(
-O3
DEPENDS
libc.src.__support.FPUtil.nearest_integer_operations
+ FLAGS
+ ROUND_OPT
)
add_entrypoint_object(
@@ -591,6 +614,8 @@ add_entrypoint_object(
-O3
DEPENDS
libc.src.__support.FPUtil.nearest_integer_operations
+ FLAGS
+ ROUND_OPT
)
add_entrypoint_object(
@@ -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(
@@ -641,6 +669,8 @@ add_entrypoint_object(
-O3
DEPENDS
libc.src.__support.FPUtil.nearest_integer_operations
+ FLAGS
+ ROUND_OPT
)
add_entrypoint_object(
@@ -653,6 +683,8 @@ add_entrypoint_object(
-O3
DEPENDS
libc.src.__support.FPUtil.nearest_integer_operations
+ FLAGS
+ ROUND_OPT
)
add_entrypoint_object(
@@ -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(
diff --git a/libc/src/math/generic/ceil.cpp b/libc/src/math/generic/ceil.cpp
index efd0f246a9b90..63da803033e22 100644
--- a/libc/src/math/generic/ceil.cpp
+++ b/libc/src/math/generic/ceil.cpp
@@ -12,6 +12,12 @@
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(double, ceil, (double x)) { return fputil::ceil(x); }
+LLVM_LIBC_FUNCTION(double, ceil, (double x)) {
+#ifdef __LIBC_USE_BUILTIN_CEIL_FLOOR_TRUNC
+ return __builtin_ceil(x);
+#else
+ return fputil::ceil(x);
+#endif
+}
} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/ceilf.cpp b/libc/src/math/generic/ceilf.cpp
index d49b34242da4f..51ef68f1dd871 100644
--- a/libc/src/math/generic/ceilf.cpp
+++ b/libc/src/math/generic/ceilf.cpp
@@ -12,6 +12,12 @@
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(float, ceilf, (float x)) { return fputil::ceil(x); }
+LLVM_LIBC_FUNCTION(float, ceilf, (float x)) {
+#ifdef __LIBC_USE_BUILTIN_CEIL_FLOOR_TRUNC
+ return __builtin_ceilf(x);
+#else
+ return fputil::ceil(x);
+#endif
+}
} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/ceilf16.cpp b/libc/src/math/generic/ceilf16.cpp
index 205d7428f66e6..ee584c25a4ae9 100644
--- a/libc/src/math/generic/ceilf16.cpp
+++ b/libc/src/math/generic/ceilf16.cpp
@@ -9,9 +9,17 @@
#include "src/math/ceilf16.h"
#include "src/__support/FPUtil/NearestIntegerOperations.h"
#include "src/__support/common.h"
+#include "src/__support/macros/properties/architectures.h"
namespace LIBC_NAMESPACE {
-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_TRUNC) && \
+ defined(LIBC_TARGET_ARCH_IS_AARCH64)
+ return static_cast<float16>(__builtin_ceilf(x));
+#else
+ return fputil::ceil(x);
+#endif
+}
} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/floor.cpp b/libc/src/math/generic/floor.cpp
index 60386f0c9cf81..bb58ca6a35402 100644
--- a/libc/src/math/generic/floor.cpp
+++ b/libc/src/math/generic/floor.cpp
@@ -12,6 +12,12 @@
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(double, floor, (double x)) { return fputil::floor(x); }
+LLVM_LIBC_FUNCTION(double, floor, (double x)) {
+#ifdef __LIBC_USE_BUILTIN_CEIL_FLOOR_TRUNC
+ return __builtin_floor(x);
+#else
+ return fputil::floor(x);
+#endif
+}
} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/floorf.cpp b/libc/src/math/generic/floorf.cpp
index 85666688685dc..459f338d897be 100644
--- a/libc/src/math/generic/floorf.cpp
+++ b/libc/src/math/generic/floorf.cpp
@@ -12,6 +12,12 @@
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(float, floorf, (float x)) { return fputil::floor(x); }
+LLVM_LIBC_FUNCTION(float, floorf, (float x)) {
+#ifdef __LIBC_USE_BUILTIN_CEIL_FLOOR_TRUNC
+ return __builtin_floorf(x);
+#else
+ return fputil::floor(x);
+#endif
+}
} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/floorf16.cpp b/libc/src/math/generic/floorf16.cpp
index db0b326c0e5f6..6d8c497946c84 100644
--- a/libc/src/math/generic/floorf16.cpp
+++ b/libc/src/math/generic/floorf16.cpp
@@ -9,9 +9,17 @@
#include "src/math/floorf16.h"
#include "src/__support/FPUtil/NearestIntegerOperations.h"
#include "src/__support/common.h"
+#include "src/__support/macros/properties/architectures.h"
namespace LIBC_NAMESPACE {
-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_TRUNC) && \
+ defined(LIBC_TARGET_ARCH_IS_AARCH64)
+ return static_cast<float16>(__builtin_floorf(x));
+#else
+ return fputil::floor(x);
+#endif
+}
} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/round.cpp b/libc/src/math/generic/round.cpp
index ca8f19f35f7fe..d873524ad9f42 100644
--- a/libc/src/math/generic/round.cpp
+++ b/libc/src/math/generic/round.cpp
@@ -12,6 +12,12 @@
namespace LIBC_NAMESPACE {
-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
diff --git a/libc/src/math/generic/roundeven.cpp b/libc/src/math/generic/roundeven.cpp
index 5f2adf9b5fce6..76409d526e208 100644
--- a/libc/src/math/generic/roundeven.cpp
+++ b/libc/src/math/generic/roundeven.cpp
@@ -13,7 +13,11 @@
namespace LIBC_NAMESPACE {
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
diff --git a/libc/src/math/generic/roundevenf.cpp b/libc/src/math/generic/roundevenf.cpp
index 353bec74ecf02..22538272bedbd 100644
--- a/libc/src/math/generic/roundevenf.cpp
+++ b/libc/src/math/generic/roundevenf.cpp
@@ -13,7 +13,11 @@
namespace LIBC_NAMESPACE {
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
diff --git a/libc/src/math/generic/roundevenf16.cpp b/libc/src/math/generic/roundevenf16.cpp
index 9ecf79ce6f6c2..90c75a10d3ddb 100644
--- a/libc/src/math/generic/roundevenf16.cpp
+++ b/libc/src/math/generic/roundevenf16.cpp
@@ -9,11 +9,17 @@
#include "src/math/roundevenf16.h"
#include "src/__support/FPUtil/NearestIntegerOperations.h"
#include "src/__support/common.h"
+#include "src/__support/macros/properties/architectures.h"
namespace LIBC_NAMESPACE {
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
diff --git a/libc/src/math/generic/roundf.cpp b/libc/src/math/generic/roundf.cpp
index 9627390ea8b8d..8b3add7cb9e2d 100644
--- a/libc/src/math/generic/roundf.cpp
+++ b/libc/src/math/generic/roundf.cpp
@@ -12,6 +12,12 @@
namespace LIBC_NAMESPACE {
-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
diff --git a/libc/src/math/generic/roundf16.cpp b/libc/src/math/generic/roundf16.cpp
index 75a255d7798d5..fca0194ec5dbb 100644
--- a/libc/src/math/generic/roundf16.cpp
+++ b/libc/src/math/generic/roundf16.cpp
@@ -9,9 +9,16 @@
#include "src/math/roundf16.h"
#include "src/__support/FPUtil/NearestIntegerOperations.h"
#include "src/__support/common.h"
+#include "src/__support/macros/properties/architectures.h"
namespace LIBC_NAMESPACE {
-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
diff --git a/libc/src/math/generic/trunc.cpp b/libc/src/math/generic/trunc.cpp
index d171ab1f092fd..5761565646c36 100644
--- a/libc/src/math/generic/trunc.cpp
+++ b/libc/src/math/generic/trunc.cpp
@@ -12,6 +12,12 @@
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(double, trunc, (double x)) { return fputil::trunc(x); }
+LLVM_LIBC_FUNCTION(double, trunc, (double x)) {
+#ifdef __LIBC_USE_BUILTIN_CEIL_FLOOR_TRUNC
+ return __builtin_trunc(x);
+#else
+ return fputil::trunc(x);
+#endif
+}
} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/truncf.cpp b/libc/src/math/generic/truncf.cpp
index 93bfb7f2882a5..2186fd6dd942e 100644
--- a/libc/src/math/generic/truncf.cpp
+++ b/libc/src/math/generic/truncf.cpp
@@ -12,6 +12,12 @@
namespace LIBC_NAMESPACE {
-LLVM_LIBC_FUNCTION(float, truncf, (float x)) { return fputil::trunc(x); }
+LLVM_LIBC_FUNCTION(float, truncf, (float x)) {
+#ifdef __LIBC_USE_BUILTIN_CEIL_FLOOR_TRUNC
+ return __builtin_truncf(x);
+#else
+ return fputil::trunc(x);
+#endif
+}
} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/truncf16.cpp b/libc/src/math/generic/truncf16.cpp
index 65bd57d810323..43dfd083eb6f2 100644
--- a/libc/src/math/generic/truncf16.cpp
+++ b/libc/src/math/generic/truncf16.cpp
@@ -9,9 +9,17 @@
#include "src/math/truncf16.h"
#include "src/__support/FPUtil/NearestIntegerOperations.h"
#include "src/__support/common.h"
+#include "src/__support/macros/properties/architectures.h"
namespace LIBC_NAMESPACE {
-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_TRUNC) && \
+ defined(LIBC_TARGET_ARCH_IS_AARCH64)
+ return static_cast<float16>(__builtin_truncf(x));
+#else
+ return fputil::trunc(x);
+#endif
+}
} // namespace LIBC_NAMESPACE
>From 58e555e7215774872d9ad949fd76468ddb6a009a Mon Sep 17 00:00:00 2001
From: OverMighty <its.overmighty at gmail.com>
Date: Fri, 12 Jul 2024 12:29:09 +0200
Subject: [PATCH 2/5] fixup! [libc][math] Optimize nearest integer functions
using builtins when available
Fix check_builtin_ceil_floor_trunc.cpp not checking for __builtin_floor{,f}.
---
.../compiler_features/check_builtin_ceil_floor_trunc.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/libc/cmake/modules/compiler_features/check_builtin_ceil_floor_trunc.cpp b/libc/cmake/modules/compiler_features/check_builtin_ceil_floor_trunc.cpp
index 031dd9376f3c1..c124b5e35cb3f 100644
--- a/libc/cmake/modules/compiler_features/check_builtin_ceil_floor_trunc.cpp
+++ b/libc/cmake/modules/compiler_features/check_builtin_ceil_floor_trunc.cpp
@@ -1,9 +1,9 @@
float try_builtin_ceilf(float x) { return __builtin_ceilf(x); }
-float try_builtin_floorf(float x) { return __builtin_ceilf(x); }
+float try_builtin_floorf(float x) { return __builtin_floorf(x); }
float try_builtin_truncf(float x) { return __builtin_truncf(x); }
double try_builtin_ceil(double x) { return __builtin_ceil(x); }
-double try_builtin_floor(double x) { return __builtin_ceil(x); }
+double try_builtin_floor(double x) { return __builtin_floor(x); }
double try_builtin_trunc(double x) { return __builtin_trunc(x); }
int main() {}
>From 0a1c052e41a9e493fcc44efe189371250a09d367 Mon Sep 17 00:00:00 2001
From: OverMighty <its.overmighty at gmail.com>
Date: Fri, 12 Jul 2024 12:53:08 +0200
Subject: [PATCH 3/5] fixup! [libc][math] Optimize nearest integer functions
using builtins when available
Optimize rint{,f,f16} using __builtin_rint{,f} when available.
---
.../cmake/modules/CheckCompilerFeatures.cmake | 6 ++--
.../modules/LLVMLibCCompileOptionRules.cmake | 5 +--
...> check_builtin_ceil_floor_rint_trunc.cpp} | 2 ++
libc/src/math/generic/CMakeLists.txt | 7 +++++
libc/src/math/generic/ceil.cpp | 2 +-
libc/src/math/generic/ceilf.cpp | 2 +-
libc/src/math/generic/ceilf16.cpp | 2 +-
libc/src/math/generic/floor.cpp | 2 +-
libc/src/math/generic/floorf.cpp | 2 +-
libc/src/math/generic/floorf16.cpp | 2 +-
libc/src/math/generic/rint.cpp | 4 +++
libc/src/math/generic/rintf.cpp | 4 +++
libc/src/math/generic/rintf16.cpp | 6 ++++
libc/src/math/generic/trunc.cpp | 2 +-
libc/src/math/generic/truncf.cpp | 2 +-
libc/src/math/generic/truncf16.cpp | 2 +-
.../math/performance_testing/CMakeLists.txt | 12 +++++--
.../nearest_integer_funcs_perf.cpp | 31 +++++++++++++++++++
18 files changed, 79 insertions(+), 16 deletions(-)
rename libc/cmake/modules/compiler_features/{check_builtin_ceil_floor_trunc.cpp => check_builtin_ceil_floor_rint_trunc.cpp} (76%)
diff --git a/libc/cmake/modules/CheckCompilerFeatures.cmake b/libc/cmake/modules/CheckCompilerFeatures.cmake
index 83822892c8096..449160d544b0d 100644
--- a/libc/cmake/modules/CheckCompilerFeatures.cmake
+++ b/libc/cmake/modules/CheckCompilerFeatures.cmake
@@ -4,7 +4,7 @@
set(
ALL_COMPILER_FEATURES
- "builtin_ceil_floor_trunc"
+ "builtin_ceil_floor_rint_trunc"
"builtin_round"
"builtin_roundeven"
"float16"
@@ -76,8 +76,8 @@ foreach(feature IN LISTS ALL_COMPILER_FEATURES)
set(LIBC_TYPES_HAS_FLOAT128 TRUE)
elseif(${feature} STREQUAL "fixed_point")
set(LIBC_COMPILER_HAS_FIXED_POINT TRUE)
- elseif(${feature} STREQUAL "builtin_ceil_floor_trunc")
- set(LIBC_COMPILER_HAS_BUILTIN_CEIL_FLOOR_TRUNC TRUE)
+ elseif(${feature} STREQUAL "builtin_ceil_floor_rint_trunc")
+ set(LIBC_COMPILER_HAS_BUILTIN_CEIL_FLOOR_RINT_TRUNC TRUE)
elseif(${feature} STREQUAL "builtin_round")
set(LIBC_COMPILER_HAS_BUILTIN_ROUND TRUE)
elseif(${feature} STREQUAL "builtin_roundeven")
diff --git a/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake b/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake
index 855d69d2a0fc9..253da4ae890e5 100644
--- a/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake
+++ b/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake
@@ -23,8 +23,9 @@ function(_get_compile_options_from_flags output_var)
# have SSE4.1.
list(APPEND compile_options "-msse4.2")
endif()
- if(LIBC_COMPILER_HAS_BUILTIN_CEIL_FLOOR_TRUNC)
- list(APPEND compile_options "-D__LIBC_USE_BUILTIN_CEIL_FLOOR_TRUNC")
+ if(LIBC_COMPILER_HAS_BUILTIN_CEIL_FLOOR_RINT_TRUNC)
+ list(APPEND compile_options
+ "-D__LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC")
endif()
if(LIBC_COMPILER_HAS_BUILTIN_ROUND)
list(APPEND compile_options "-D__LIBC_USE_BUILTIN_ROUND")
diff --git a/libc/cmake/modules/compiler_features/check_builtin_ceil_floor_trunc.cpp b/libc/cmake/modules/compiler_features/check_builtin_ceil_floor_rint_trunc.cpp
similarity index 76%
rename from libc/cmake/modules/compiler_features/check_builtin_ceil_floor_trunc.cpp
rename to libc/cmake/modules/compiler_features/check_builtin_ceil_floor_rint_trunc.cpp
index c124b5e35cb3f..51f33be1bea8a 100644
--- a/libc/cmake/modules/compiler_features/check_builtin_ceil_floor_trunc.cpp
+++ b/libc/cmake/modules/compiler_features/check_builtin_ceil_floor_rint_trunc.cpp
@@ -1,9 +1,11 @@
float try_builtin_ceilf(float x) { return __builtin_ceilf(x); }
float try_builtin_floorf(float x) { return __builtin_floorf(x); }
+float try_builtin_rintf(float x) { return __builtin_rintf(x); }
float try_builtin_truncf(float x) { return __builtin_truncf(x); }
double try_builtin_ceil(double x) { return __builtin_ceil(x); }
double try_builtin_floor(double x) { return __builtin_floor(x); }
+double try_builtin_rint(double x) { return __builtin_rint(x); }
double try_builtin_trunc(double x) { return __builtin_trunc(x); }
int main() {}
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index 915fc076826f9..c2f58fb1a4f71 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -862,6 +862,8 @@ add_entrypoint_object(
-O3
DEPENDS
libc.src.__support.FPUtil.nearest_integer_operations
+ FLAGS
+ ROUND_OPT
)
add_entrypoint_object(
@@ -874,6 +876,8 @@ add_entrypoint_object(
-O3
DEPENDS
libc.src.__support.FPUtil.nearest_integer_operations
+ FLAGS
+ ROUND_OPT
)
add_entrypoint_object(
@@ -899,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(
diff --git a/libc/src/math/generic/ceil.cpp b/libc/src/math/generic/ceil.cpp
index 63da803033e22..b3429df7332f1 100644
--- a/libc/src/math/generic/ceil.cpp
+++ b/libc/src/math/generic/ceil.cpp
@@ -13,7 +13,7 @@
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(double, ceil, (double x)) {
-#ifdef __LIBC_USE_BUILTIN_CEIL_FLOOR_TRUNC
+#ifdef __LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC
return __builtin_ceil(x);
#else
return fputil::ceil(x);
diff --git a/libc/src/math/generic/ceilf.cpp b/libc/src/math/generic/ceilf.cpp
index 51ef68f1dd871..a367067da50cf 100644
--- a/libc/src/math/generic/ceilf.cpp
+++ b/libc/src/math/generic/ceilf.cpp
@@ -13,7 +13,7 @@
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(float, ceilf, (float x)) {
-#ifdef __LIBC_USE_BUILTIN_CEIL_FLOOR_TRUNC
+#ifdef __LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC
return __builtin_ceilf(x);
#else
return fputil::ceil(x);
diff --git a/libc/src/math/generic/ceilf16.cpp b/libc/src/math/generic/ceilf16.cpp
index ee584c25a4ae9..8b74eaac6c59f 100644
--- a/libc/src/math/generic/ceilf16.cpp
+++ b/libc/src/math/generic/ceilf16.cpp
@@ -14,7 +14,7 @@
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(float16, ceilf16, (float16 x)) {
-#if defined(__LIBC_USE_BUILTIN_CEIL_FLOOR_TRUNC) && \
+#if defined(__LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC) && \
defined(LIBC_TARGET_ARCH_IS_AARCH64)
return static_cast<float16>(__builtin_ceilf(x));
#else
diff --git a/libc/src/math/generic/floor.cpp b/libc/src/math/generic/floor.cpp
index bb58ca6a35402..56729bf13cd7a 100644
--- a/libc/src/math/generic/floor.cpp
+++ b/libc/src/math/generic/floor.cpp
@@ -13,7 +13,7 @@
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(double, floor, (double x)) {
-#ifdef __LIBC_USE_BUILTIN_CEIL_FLOOR_TRUNC
+#ifdef __LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC
return __builtin_floor(x);
#else
return fputil::floor(x);
diff --git a/libc/src/math/generic/floorf.cpp b/libc/src/math/generic/floorf.cpp
index 459f338d897be..56dd7f39e7812 100644
--- a/libc/src/math/generic/floorf.cpp
+++ b/libc/src/math/generic/floorf.cpp
@@ -13,7 +13,7 @@
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(float, floorf, (float x)) {
-#ifdef __LIBC_USE_BUILTIN_CEIL_FLOOR_TRUNC
+#ifdef __LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC
return __builtin_floorf(x);
#else
return fputil::floor(x);
diff --git a/libc/src/math/generic/floorf16.cpp b/libc/src/math/generic/floorf16.cpp
index 6d8c497946c84..6f6d9296855ef 100644
--- a/libc/src/math/generic/floorf16.cpp
+++ b/libc/src/math/generic/floorf16.cpp
@@ -14,7 +14,7 @@
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(float16, floorf16, (float16 x)) {
-#if defined(__LIBC_USE_BUILTIN_CEIL_FLOOR_TRUNC) && \
+#if defined(__LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC) && \
defined(LIBC_TARGET_ARCH_IS_AARCH64)
return static_cast<float16>(__builtin_floorf(x));
#else
diff --git a/libc/src/math/generic/rint.cpp b/libc/src/math/generic/rint.cpp
index e3189ea48b569..30983940134dc 100644
--- a/libc/src/math/generic/rint.cpp
+++ b/libc/src/math/generic/rint.cpp
@@ -13,7 +13,11 @@
namespace LIBC_NAMESPACE {
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
diff --git a/libc/src/math/generic/rintf.cpp b/libc/src/math/generic/rintf.cpp
index 259a46f376537..24f9aa84505f7 100644
--- a/libc/src/math/generic/rintf.cpp
+++ b/libc/src/math/generic/rintf.cpp
@@ -13,7 +13,11 @@
namespace LIBC_NAMESPACE {
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
diff --git a/libc/src/math/generic/rintf16.cpp b/libc/src/math/generic/rintf16.cpp
index e0caa7ad2550e..4e3858383077f 100644
--- a/libc/src/math/generic/rintf16.cpp
+++ b/libc/src/math/generic/rintf16.cpp
@@ -9,11 +9,17 @@
#include "src/math/rintf16.h"
#include "src/__support/FPUtil/NearestIntegerOperations.h"
#include "src/__support/common.h"
+#include "src/__support/macros/properties/architectures.h"
namespace LIBC_NAMESPACE {
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
diff --git a/libc/src/math/generic/trunc.cpp b/libc/src/math/generic/trunc.cpp
index 5761565646c36..50132b036d2e1 100644
--- a/libc/src/math/generic/trunc.cpp
+++ b/libc/src/math/generic/trunc.cpp
@@ -13,7 +13,7 @@
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(double, trunc, (double x)) {
-#ifdef __LIBC_USE_BUILTIN_CEIL_FLOOR_TRUNC
+#ifdef __LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC
return __builtin_trunc(x);
#else
return fputil::trunc(x);
diff --git a/libc/src/math/generic/truncf.cpp b/libc/src/math/generic/truncf.cpp
index 2186fd6dd942e..8fb7ae2a13020 100644
--- a/libc/src/math/generic/truncf.cpp
+++ b/libc/src/math/generic/truncf.cpp
@@ -13,7 +13,7 @@
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(float, truncf, (float x)) {
-#ifdef __LIBC_USE_BUILTIN_CEIL_FLOOR_TRUNC
+#ifdef __LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC
return __builtin_truncf(x);
#else
return fputil::trunc(x);
diff --git a/libc/src/math/generic/truncf16.cpp b/libc/src/math/generic/truncf16.cpp
index 43dfd083eb6f2..2d2869f84b994 100644
--- a/libc/src/math/generic/truncf16.cpp
+++ b/libc/src/math/generic/truncf16.cpp
@@ -14,7 +14,7 @@
namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(float16, truncf16, (float16 x)) {
-#if defined(__LIBC_USE_BUILTIN_CEIL_FLOOR_TRUNC) && \
+#if defined(__LIBC_USE_BUILTIN_CEIL_FLOOR_RINT_TRUNC) && \
defined(LIBC_TARGET_ARCH_IS_AARCH64)
return static_cast<float16>(__builtin_truncf(x));
#else
diff --git a/libc/test/src/math/performance_testing/CMakeLists.txt b/libc/test/src/math/performance_testing/CMakeLists.txt
index bf88fbb85c5d7..0f1c56739c88c 100644
--- a/libc/test/src/math/performance_testing/CMakeLists.txt
+++ b/libc/test/src/math/performance_testing/CMakeLists.txt
@@ -12,7 +12,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)
@@ -55,9 +55,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})
@@ -376,6 +380,8 @@ add_perf_binary(
libc.src.math.ceilf16
libc.src.math.floorf
libc.src.math.floorf16
+ libc.src.math.rintf
+ libc.src.math.rintf16
libc.src.math.roundevenf
libc.src.math.roundevenf16
libc.src.math.roundf
@@ -384,4 +390,6 @@ add_perf_binary(
libc.src.math.truncf16
COMPILE_OPTIONS
-fno-builtin
+ LINK_LIBRARIES
+ LibcFPTestHelpers
)
diff --git a/libc/test/src/math/performance_testing/nearest_integer_funcs_perf.cpp b/libc/test/src/math/performance_testing/nearest_integer_funcs_perf.cpp
index 24176a377e9d4..1628d28319c70 100644
--- a/libc/test/src/math/performance_testing/nearest_integer_funcs_perf.cpp
+++ b/libc/test/src/math/performance_testing/nearest_integer_funcs_perf.cpp
@@ -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 {
@@ -164,5 +170,30 @@ int main() {
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;
}
>From 82848f97135ba750b1487955bf9e76d242ab43ab Mon Sep 17 00:00:00 2001
From: OverMighty <its.overmighty at gmail.com>
Date: Fri, 12 Jul 2024 17:16:08 +0200
Subject: [PATCH 4/5] fixup! [libc][math] Optimize nearest integer functions
using builtins when available
Nit: sort roundeven after round.
---
libc/test/src/math/performance_testing/CMakeLists.txt | 4 ++--
.../performance_testing/nearest_integer_funcs_perf.cpp | 8 ++++----
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/libc/test/src/math/performance_testing/CMakeLists.txt b/libc/test/src/math/performance_testing/CMakeLists.txt
index 0f1c56739c88c..d2c860c102b23 100644
--- a/libc/test/src/math/performance_testing/CMakeLists.txt
+++ b/libc/test/src/math/performance_testing/CMakeLists.txt
@@ -382,10 +382,10 @@ add_perf_binary(
libc.src.math.floorf16
libc.src.math.rintf
libc.src.math.rintf16
- libc.src.math.roundevenf
- libc.src.math.roundevenf16
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
diff --git a/libc/test/src/math/performance_testing/nearest_integer_funcs_perf.cpp b/libc/test/src/math/performance_testing/nearest_integer_funcs_perf.cpp
index 1628d28319c70..ff5e8f449719c 100644
--- a/libc/test/src/math/performance_testing/nearest_integer_funcs_perf.cpp
+++ b/libc/test/src/math/performance_testing/nearest_integer_funcs_perf.cpp
@@ -152,10 +152,10 @@ 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")
@@ -163,10 +163,10 @@ int main() {
"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")
>From a78bb651d5f8c70c0a340c4941ba8bbd0c0971b6 Mon Sep 17 00:00:00 2001
From: OverMighty <its.overmighty at gmail.com>
Date: Fri, 12 Jul 2024 20:52:31 +0200
Subject: [PATCH 5/5] fixup! [libc][math] Optimize nearest integer functions
using builtins when available
Fix builtin detection succeeding even when calls to functions provided by the system libc are generated.
---
libc/cmake/modules/CheckCompilerFeatures.cmake | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/libc/cmake/modules/CheckCompilerFeatures.cmake b/libc/cmake/modules/CheckCompilerFeatures.cmake
index 449160d544b0d..a6d793d495c45 100644
--- a/libc/cmake/modules/CheckCompilerFeatures.cmake
+++ b/libc/cmake/modules/CheckCompilerFeatures.cmake
@@ -50,15 +50,18 @@ set(AVAILABLE_COMPILER_FEATURES "")
foreach(feature IN LISTS ALL_COMPILER_FEATURES)
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
set(compile_options ${LIBC_COMPILE_OPTIONS_NATIVE})
+ set(link_options "")
if(${feature} STREQUAL "fixed_point")
list(APPEND compile_options "-ffixed-point")
elseif(${feature} MATCHES "^builtin_")
set(compile_options ${LIBC_COMPILE_OPTIONS_DEFAULT})
+ set(link_options -nostdlib)
# The compiler might handle calls to rounding builtins by generating calls
# to the respective libc math functions, in which case we cannot use these
# builtins in our implementations of these functions. We check that this is
# not the case by trying to link an executable, since linking would fail due
- # to unresolved references if calls to libc functions were generated.
+ # to unresolved references with -nostdlib if calls to libc functions were
+ # generated.
set(CMAKE_TRY_COMPILE_TARGET_TYPE EXECUTABLE)
endif()
@@ -67,6 +70,7 @@ foreach(feature IN LISTS ALL_COMPILER_FEATURES)
${CMAKE_CURRENT_BINARY_DIR}/compiler_features
SOURCES ${LIBC_SOURCE_DIR}/cmake/modules/compiler_features/check_${feature}.cpp
COMPILE_DEFINITIONS -I${LIBC_SOURCE_DIR} ${compile_options}
+ LINK_OPTIONS ${link_options}
)
if(has_feature)
list(APPEND AVAILABLE_COMPILER_FEATURES ${feature})
More information about the libc-commits
mailing list