[libc-commits] [libc] [libc][math][c23] Add fabsf16 C23 math function (PR #93567)

via libc-commits libc-commits at lists.llvm.org
Tue May 28 09:10:51 PDT 2024


https://github.com/overmighty updated https://github.com/llvm/llvm-project/pull/93567

>From 87d7ef1856660795ae81597b150445be28a94613 Mon Sep 17 00:00:00 2001
From: OverMighty <its.overmighty at gmail.com>
Date: Tue, 28 May 2024 18:01:31 +0200
Subject: [PATCH 1/2] [libc][math][c23] Add fabsf16 C23 math function

---
 .../cmake/modules/CheckCompilerFeatures.cmake |  6 ++-
 .../compiler_features/check_float16.cpp       |  5 +++
 libc/config/linux/x86_64/entrypoints.txt      |  7 ++++
 libc/include/llvm-libc-types/CMakeLists.txt   |  1 +
 libc/include/llvm-libc-types/float16.h        | 38 +++++++++++++++++++
 libc/spec/spec.td                             |  1 +
 libc/spec/stdc.td                             |  2 +
 .../CPP/type_traits/is_floating_point.h       |  9 ++++-
 libc/src/__support/FPUtil/FPBits.h            |  2 +-
 libc/src/__support/macros/properties/types.h  | 25 ++----------
 libc/src/math/CMakeLists.txt                  |  1 +
 libc/src/math/fabsf16.h                       | 20 ++++++++++
 libc/src/math/generic/CMakeLists.txt          | 13 +++++++
 libc/src/math/generic/fabsf16.cpp             | 17 +++++++++
 libc/test/src/math/smoke/CMakeLists.txt       | 13 +++++++
 libc/test/src/math/smoke/fabsf16_test.cpp     | 13 +++++++
 16 files changed, 147 insertions(+), 26 deletions(-)
 create mode 100644 libc/cmake/modules/compiler_features/check_float16.cpp
 create mode 100644 libc/include/llvm-libc-types/float16.h
 create mode 100644 libc/src/math/fabsf16.h
 create mode 100644 libc/src/math/generic/fabsf16.cpp
 create mode 100644 libc/test/src/math/smoke/fabsf16_test.cpp

diff --git a/libc/cmake/modules/CheckCompilerFeatures.cmake b/libc/cmake/modules/CheckCompilerFeatures.cmake
index 3a9e1e3b1cf8b..17806588550eb 100644
--- a/libc/cmake/modules/CheckCompilerFeatures.cmake
+++ b/libc/cmake/modules/CheckCompilerFeatures.cmake
@@ -2,7 +2,7 @@
 # Compiler features definition and flags
 # ------------------------------------------------------------------------------
 
-set(ALL_COMPILER_FEATURES "float128" "fixed_point")
+set(ALL_COMPILER_FEATURES "float16" "float128" "fixed_point")
 
 # Making sure ALL_COMPILER_FEATURES is sorted.
 list(SORT ALL_COMPILER_FEATURES)
@@ -54,7 +54,9 @@ foreach(feature IN LISTS ALL_COMPILER_FEATURES)
   )
   if(has_feature)
     list(APPEND AVAILABLE_COMPILER_FEATURES ${feature})
-    if(${feature} STREQUAL "float128")
+    if(${feature} STREQUAL "float16")
+      set(LIBC_TYPES_HAS_FLOAT16 TRUE)
+    elseif(${feature} STREQUAL "float128")
       set(LIBC_TYPES_HAS_FLOAT128 TRUE)
     elseif(${feature} STREQUAL "fixed_point")
       set(LIBC_COMPILER_HAS_FIXED_POINT TRUE)
diff --git a/libc/cmake/modules/compiler_features/check_float16.cpp b/libc/cmake/modules/compiler_features/check_float16.cpp
new file mode 100644
index 0000000000000..133c559eed219
--- /dev/null
+++ b/libc/cmake/modules/compiler_features/check_float16.cpp
@@ -0,0 +1,5 @@
+#include "src/__support/macros/properties/types.h"
+
+#ifndef LIBC_TYPES_HAS_FLOAT16
+#error unsupported
+#endif
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 5e3ddd34fb4dc..03cd17a8090cb 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -528,6 +528,13 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.ufromfpxl
 )
 
+if(LIBC_TYPES_HAS_FLOAT16)
+  list(APPEND TARGET_LIBM_ENTRYPOINTS
+    # math.h C23 _Float16 entrypoints
+    libc.src.math.fabsf16
+  )
+endif()
+
 if(LIBC_TYPES_HAS_FLOAT128)
   list(APPEND TARGET_LIBM_ENTRYPOINTS
     # math.h C23 _Float128 entrypoints
diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt
index 018b6c58316c3..6f3e123f78d8f 100644
--- a/libc/include/llvm-libc-types/CMakeLists.txt
+++ b/libc/include/llvm-libc-types/CMakeLists.txt
@@ -119,6 +119,7 @@ add_header(ENTRY HDR ENTRY.h)
 add_header(struct_hsearch_data HDR struct_hsearch_data.h)
 add_header(struct_epoll_event HDR struct_epoll_event.h)
 add_header(struct_epoll_data HDR struct_epoll_data.h)
+add_header(float16 HDR float16.h)
 add_header(
   float128
   HDR
diff --git a/libc/include/llvm-libc-types/float16.h b/libc/include/llvm-libc-types/float16.h
new file mode 100644
index 0000000000000..671d9c1b97b7f
--- /dev/null
+++ b/libc/include/llvm-libc-types/float16.h
@@ -0,0 +1,38 @@
+//===-- Definition of float16 type ----------------------------------------===//
+//
+// 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_TYPES_FLOAT16_H
+#define LLVM_LIBC_TYPES_FLOAT16_H
+
+#include "src/__support/macros/properties/architectures.h"
+#include "src/__support/macros/properties/compiler.h"
+#include "src/__support/macros/properties/cpu_features.h"
+
+#if defined(LIBC_TARGET_ARCH_IS_X86_64) && defined(LIBC_TARGET_CPU_HAS_SSE2)
+#if (defined(LIBC_COMPILER_CLANG_VER) && (LIBC_COMPILER_CLANG_VER >= 1500)) || \
+    (defined(LIBC_COMPILER_GCC_VER) && (LIBC_COMPILER_GCC_VER >= 1201))
+#define LIBC_TYPES_HAS_FLOAT16
+using float16 = _Float16;
+#endif
+#endif
+#if defined(LIBC_TARGET_ARCH_IS_AARCH64)
+#if (defined(LIBC_COMPILER_CLANG_VER) && (LIBC_COMPILER_CLANG_VER >= 900)) ||  \
+    (defined(LIBC_COMPILER_GCC_VER) && (LIBC_COMPILER_GCC_VER >= 1301))
+#define LIBC_TYPES_HAS_FLOAT16
+using float16 = _Float16;
+#endif
+#endif
+#if defined(LIBC_TARGET_ARCH_IS_ANY_RISCV)
+#if (defined(LIBC_COMPILER_CLANG_VER) && (LIBC_COMPILER_CLANG_VER >= 1300)) || \
+    (defined(LIBC_COMPILER_GCC_VER) && (LIBC_COMPILER_GCC_VER >= 1301))
+#define LIBC_TYPES_HAS_FLOAT16
+using float16 = _Float16;
+#endif
+#endif
+
+#endif // LLVM_LIBC_TYPES_FLOAT16_H
diff --git a/libc/spec/spec.td b/libc/spec/spec.td
index ea8fa4cd373cf..966e1f5df47c1 100644
--- a/libc/spec/spec.td
+++ b/libc/spec/spec.td
@@ -53,6 +53,7 @@ def UnsignedCharType : NamedType<"unsigned char">;
 def UnsignedShortType : NamedType<"unsigned short">;
 def BoolType : NamedType<"bool">;
 
+def Float16Type : NamedType<"float16">;
 def Float128Type : NamedType<"float128">;
 
 // Common types
diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index eb67c9b0b009b..6034a6e1aa703 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -378,6 +378,7 @@ def StdC : StandardSpec<"stdc"> {
       [
           NamedType<"float_t">,
           NamedType<"double_t">,
+          Float16Type,
           NamedType<"float128">,
       ],
       [], // Enumerations
@@ -395,6 +396,7 @@ def StdC : StandardSpec<"stdc"> {
           FunctionSpec<"fabs", RetValSpec<DoubleType>, [ArgSpec<DoubleType>], [ConstAttr]>,
           FunctionSpec<"fabsf", RetValSpec<FloatType>, [ArgSpec<FloatType>]>,
           FunctionSpec<"fabsl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>]>,
+          GuardedFunctionSpec<"fabsf16", RetValSpec<Float16Type>, [ArgSpec<Float16Type>], "LIBC_TYPES_HAS_FLOAT16">,
           GuardedFunctionSpec<"fabsf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT128">,
 
           FunctionSpec<"fdim", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<DoubleType>]>,
diff --git a/libc/src/__support/CPP/type_traits/is_floating_point.h b/libc/src/__support/CPP/type_traits/is_floating_point.h
index 4c8f50f4e91f9..39150d64b7876 100644
--- a/libc/src/__support/CPP/type_traits/is_floating_point.h
+++ b/libc/src/__support/CPP/type_traits/is_floating_point.h
@@ -24,7 +24,14 @@ template <typename T> struct is_floating_point {
   }
 
 public:
-#if defined(LIBC_TYPES_HAS_FLOAT128)
+#if defined(LIBC_TYPES_HAS_FLOAT16) && defined(LIBC_TYPES_HAS_FLOAT128)
+  LIBC_INLINE_VAR static constexpr bool value =
+      __is_unqualified_any_of<T, float, double, long double, float16,
+                              float128>();
+#elif defined(LIBC_TYPES_HAS_FLOAT16)
+  LIBC_INLINE_VAR static constexpr bool value =
+      __is_unqualified_any_of<T, float, double, long double, float16>();
+#elif defined(LIBC_TYPES_HAS_FLOAT128)
   LIBC_INLINE_VAR static constexpr bool value =
       __is_unqualified_any_of<T, float, double, long double, float128>();
 #else
diff --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h
index ab050360c353b..d3c96d2d613d6 100644
--- a/libc/src/__support/FPUtil/FPBits.h
+++ b/libc/src/__support/FPUtil/FPBits.h
@@ -651,7 +651,7 @@ struct FPRepImpl : public FPRepSem<fp_type, RetT> {
 
   // Modifiers
   LIBC_INLINE constexpr RetT abs() const {
-    return RetT(bits & UP::EXP_SIG_MASK);
+    return RetT(static_cast<StorageType>(bits & UP::EXP_SIG_MASK));
   }
 
   // Observers
diff --git a/libc/src/__support/macros/properties/types.h b/libc/src/__support/macros/properties/types.h
index d43cf99e6859b..4baf9fae36f7f 100644
--- a/libc/src/__support/macros/properties/types.h
+++ b/libc/src/__support/macros/properties/types.h
@@ -12,6 +12,7 @@
 
 #include "include/llvm-libc-macros/float-macros.h" // LDBL_MANT_DIG
 #include "include/llvm-libc-types/float128.h"      // float128
+#include "include/llvm-libc-types/float16.h"       // float16
 #include "src/__support/macros/properties/architectures.h"
 #include "src/__support/macros/properties/compiler.h"
 #include "src/__support/macros/properties/cpu_features.h"
@@ -39,28 +40,8 @@
 #endif // defined(__SIZEOF_INT128__)
 
 // -- float16 support ---------------------------------------------------------
-// TODO: move this logic to "llvm-libc-types/float16.h"
-#if defined(LIBC_TARGET_ARCH_IS_X86_64) && defined(LIBC_TARGET_CPU_HAS_SSE2)
-#if (defined(LIBC_COMPILER_CLANG_VER) && (LIBC_COMPILER_CLANG_VER >= 1500)) || \
-    (defined(LIBC_COMPILER_GCC_VER) && (LIBC_COMPILER_GCC_VER >= 1201))
-#define LIBC_TYPES_HAS_FLOAT16
-using float16 = _Float16;
-#endif
-#endif
-#if defined(LIBC_TARGET_ARCH_IS_AARCH64)
-#if (defined(LIBC_COMPILER_CLANG_VER) && (LIBC_COMPILER_CLANG_VER >= 900)) ||  \
-    (defined(LIBC_COMPILER_GCC_VER) && (LIBC_COMPILER_GCC_VER >= 1301))
-#define LIBC_TYPES_HAS_FLOAT16
-using float16 = _Float16;
-#endif
-#endif
-#if defined(LIBC_TARGET_ARCH_IS_ANY_RISCV)
-#if (defined(LIBC_COMPILER_CLANG_VER) && (LIBC_COMPILER_CLANG_VER >= 1300)) || \
-    (defined(LIBC_COMPILER_GCC_VER) && (LIBC_COMPILER_GCC_VER >= 1301))
-#define LIBC_TYPES_HAS_FLOAT16
-using float16 = _Float16;
-#endif
-#endif
+// LIBC_TYPES_HAS_FLOAT16 and 'float16' type are provided by
+// "include/llvm-libc-types/float16.h"
 
 // -- float128 support --------------------------------------------------------
 // LIBC_TYPES_HAS_FLOAT128 and 'float128' type are provided by
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index c34c58575441d..31df5d0ab8809 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -99,6 +99,7 @@ add_math_entrypoint_object(expm1f)
 add_math_entrypoint_object(fabs)
 add_math_entrypoint_object(fabsf)
 add_math_entrypoint_object(fabsl)
+add_math_entrypoint_object(fabsf16)
 add_math_entrypoint_object(fabsf128)
 
 add_math_entrypoint_object(fdim)
diff --git a/libc/src/math/fabsf16.h b/libc/src/math/fabsf16.h
new file mode 100644
index 0000000000000..532662a77e9a6
--- /dev/null
+++ b/libc/src/math/fabsf16.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for fabsf16 -----------------------*- 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_FABSF16_H
+#define LLVM_LIBC_SRC_MATH_FABSF16_H
+
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE {
+
+float16 fabsf16(float16 x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_FABSF16_H
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index daaf505008ca1..2a4dcdcf7ddde 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -241,6 +241,19 @@ add_entrypoint_object(
     -O2
 )
 
+add_entrypoint_object(
+  fabsf16
+  SRCS
+    fabsf16.cpp
+  HDRS
+    ../fabsf16.h
+  DEPENDS
+    libc.src.__support.macros.properties.types
+    libc.src.__support.FPUtil.basic_operations
+  COMPILE_OPTIONS
+    -O3
+)
+
 add_entrypoint_object(
   fabsf128
   SRCS
diff --git a/libc/src/math/generic/fabsf16.cpp b/libc/src/math/generic/fabsf16.cpp
new file mode 100644
index 0000000000000..4de84f35da302
--- /dev/null
+++ b/libc/src/math/generic/fabsf16.cpp
@@ -0,0 +1,17 @@
+//===-- Implementation of fabsf16 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/fabsf16.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float16, fabsf16, (float16 x)) { return fputil::abs(x); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index 112b2985829ca..c74f68daeb082 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -92,6 +92,19 @@ add_fp_unittest(
     libc.src.__support.FPUtil.fp_bits
 )
 
+add_fp_unittest(
+  fabsf16_test
+  SUITE
+    libc-math-smoke-tests
+  SRCS
+    fabsf16_test.cpp
+  HDRS
+    FAbsTest.h
+  DEPENDS
+    libc.src.math.fabsf16
+    libc.src.__support.FPUtil.fp_bits
+)
+
 add_fp_unittest(
   fabsf128_test
   SUITE
diff --git a/libc/test/src/math/smoke/fabsf16_test.cpp b/libc/test/src/math/smoke/fabsf16_test.cpp
new file mode 100644
index 0000000000000..c43bd5090f90b
--- /dev/null
+++ b/libc/test/src/math/smoke/fabsf16_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for fabsf16 ---------------------------------------------===//
+//
+// 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 "FAbsTest.h"
+
+#include "src/math/fabsf16.h"
+
+LIST_FABS_TESTS(float16, LIBC_NAMESPACE::fabsf16)

>From ffa73cc5ed61cbec2d00a5008d342916009ae775 Mon Sep 17 00:00:00 2001
From: OverMighty <its.overmighty at gmail.com>
Date: Tue, 28 May 2024 18:10:22 +0200
Subject: [PATCH 2/2] fixup! [libc][math][c23] Add fabsf16 C23 math function

Fix usage of internal float16 alias in generated headers.
---
 libc/spec/spec.td | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libc/spec/spec.td b/libc/spec/spec.td
index 966e1f5df47c1..056a3143c5a71 100644
--- a/libc/spec/spec.td
+++ b/libc/spec/spec.td
@@ -53,7 +53,7 @@ def UnsignedCharType : NamedType<"unsigned char">;
 def UnsignedShortType : NamedType<"unsigned short">;
 def BoolType : NamedType<"bool">;
 
-def Float16Type : NamedType<"float16">;
+def Float16Type : NamedType<"_Float16">;
 def Float128Type : NamedType<"float128">;
 
 // Common types



More information about the libc-commits mailing list