[libc-commits] [libc] [libc][math] Add some explicit macro checks to round and roundf. (PR #217822)

via libc-commits libc-commits at lists.llvm.org
Thu Aug 20 22:48:52 PDT 2026


https://github.com/lntue created https://github.com/llvm/llvm-project/pull/217822

This will allow users to use them without going through our cmake build checks or forcing the flag `__LIBC_USE_BUILTIN_ROUND`.

>From 04a33ef02641520fba8788df60f2c3d339503ffe Mon Sep 17 00:00:00 2001
From: Tue Ly <lntue.h at gmail.com>
Date: Fri, 21 Aug 2026 05:44:58 +0000
Subject: [PATCH] [libc][math] Add some explicit macro checks to round and
 roundf.

This will allow users to use them without going through our cmake build checks
or forcing the flag `__LIBC_USE_BUILTIN_ROUND`.
---
 libc/src/__support/math/round.h  | 29 ++++++++++++++++++++++++++++-
 libc/src/__support/math/roundf.h | 29 ++++++++++++++++++++++++++++-
 2 files changed, 56 insertions(+), 2 deletions(-)

diff --git a/libc/src/__support/math/round.h b/libc/src/__support/math/round.h
index 8cbfa3ff79e9a..d35c9f437a630 100644
--- a/libc/src/__support/math/round.h
+++ b/libc/src/__support/math/round.h
@@ -10,13 +10,40 @@
 #define LLVM_LIBC_SRC___SUPPORT_MATH_ROUND_H
 
 #include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/macros/attributes.h"
 #include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/compiler.h"
+#include "src/__support/macros/properties/cpu_features.h"
 
 namespace LIBC_NAMESPACE_DECL {
 namespace math {
 
+// For the following targets, clang will generate rounding instructions
+// by default:
+//   - x86-64 with sse4.1 or after
+//   - ARM v8
+//   - RISC-V
+
+// Notes: gcc does not generate the instructions for x86-64 by default.
+
+// Notes: for x86-64, if `-ffp-model=strict` is set, `__builtin_round` will
+// generate a callback to `round` and it does not look like there is any way for
+// us to detect that just from the pre-defined macros.  The only way to really
+// detect the call back is to compile and link with nostdlib.
+// This also affects `__builtin_elementwise_round`, making it behave identical
+// to `__builtin_round`.
+
+// Notes: `__builtin_elementwise_round` is slightly better than
+// `__builtin_round` in that it is not defined for x86-64 pre-SSE4.1, but it
+// still generate callback for ARM version < 8, and for x86-64 with
+// `-ffp-model=strict`.
+
 LIBC_INLINE LIBC_CONSTEXPR double round(double x) {
-#if defined(__LIBC_USE_BUILTIN_ROUND) && !defined(LIBC_USE_CONSTEXPR)
+#if __has_builtin(__builtin_round) && !defined(LIBC_USE_CONSTEXPR) &&          \
+    (defined(__LIBC_USE_BUILTIN_ROUND) ||                                      \
+     (defined(LIBC_COMPILER_IS_CLANG) &&                                       \
+      defined(LIBC_TARGET_CPU_HAS_FPU_DOUBLE) &&                               \
+      (!defined(__ARM_ARCH) || (__ARM_ARCH >= 8))))
   return __builtin_round(x);
 #else
   return fputil::round(x);
diff --git a/libc/src/__support/math/roundf.h b/libc/src/__support/math/roundf.h
index e20b9d2e7f763..5abe9ebad15b0 100644
--- a/libc/src/__support/math/roundf.h
+++ b/libc/src/__support/math/roundf.h
@@ -10,13 +10,40 @@
 #define LLVM_LIBC_SRC___SUPPORT_MATH_ROUNDF_H
 
 #include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/macros/attributes.h"
 #include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/compiler.h"
+#include "src/__support/macros/properties/cpu_features.h"
 
 namespace LIBC_NAMESPACE_DECL {
 namespace math {
 
+// For the following targets, clang will generate rounding instructions
+// by default:
+//   - x86-64 with sse4.1 or after
+//   - ARM v8
+//   - RISC-V
+
+// Notes: gcc does not generate the instructions for x86-64 by default.
+
+// Notes: for x86-64, if `-ffp-model=strict` is set, `__builtin_round` will
+// generate a callback to `round` and it does not look like there is any way for
+// us to detect that just from the pre-defined macros.  The only way to really
+// detect the call back is to compile and link with nostdlib.
+// This also affects `__builtin_elementwise_round`, making it behave identical
+// to `__builtin_round`.
+
+// Notes: `__builtin_elementwise_round` is slightly better than
+// `__builtin_round` in that it is not defined for x86-64 pre-SSE4.1, but it
+// still generate callback for ARM version < 8, and for x86-64 with
+// `-ffp-model=strict`.
+
 LIBC_INLINE LIBC_CONSTEXPR float roundf(float x) {
-#if defined(__LIBC_USE_BUILTIN_ROUND) && !defined(LIBC_USE_CONSTEXPR)
+#if __has_builtin(__builtin_roundf) && !defined(LIBC_USE_CONSTEXPR) &&         \
+    (defined(__LIBC_USE_BUILTIN_ROUND) ||                                      \
+     (defined(LIBC_COMPILER_IS_CLANG) &&                                       \
+      defined(LIBC_TARGET_CPU_HAS_FPU_FLOAT) &&                                \
+      (!defined(__ARM_ARCH) || (__ARM_ARCH >= 8))))
   return __builtin_roundf(x);
 #else
   return fputil::round(x);



More information about the libc-commits mailing list