Skip to content
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 fabsf16 C23 math function #93567

Merged
merged 12 commits into from
May 30, 2024

Conversation

overmighty
Copy link
Member

cc @lntue

@llvmbot llvmbot added the libc label May 28, 2024
@llvmbot
Copy link

llvmbot commented May 28, 2024

@llvm/pr-subscribers-libc

Author: OverMighty (overmighty)

Changes

cc @lntue


Full diff: https://github.com/llvm/llvm-project/pull/93567.diff

16 Files Affected:

  • (modified) libc/cmake/modules/CheckCompilerFeatures.cmake (+4-2)
  • (added) libc/cmake/modules/compiler_features/check_float16.cpp (+5)
  • (modified) libc/config/linux/x86_64/entrypoints.txt (+7)
  • (modified) libc/include/llvm-libc-types/CMakeLists.txt (+1)
  • (added) libc/include/llvm-libc-types/float16.h (+38)
  • (modified) libc/spec/spec.td (+1)
  • (modified) libc/spec/stdc.td (+2)
  • (modified) libc/src/__support/CPP/type_traits/is_floating_point.h (+8-1)
  • (modified) libc/src/__support/FPUtil/FPBits.h (+1-1)
  • (modified) libc/src/__support/macros/properties/types.h (+3-22)
  • (modified) libc/src/math/CMakeLists.txt (+1)
  • (added) libc/src/math/fabsf16.h (+20)
  • (modified) libc/src/math/generic/CMakeLists.txt (+13)
  • (added) libc/src/math/generic/fabsf16.cpp (+17)
  • (modified) libc/test/src/math/smoke/CMakeLists.txt (+13)
  • (added) libc/test/src/math/smoke/fabsf16_test.cpp (+13)
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)

Copy link
Member Author

@overmighty overmighty left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we #include "src/__support/macros/properties/types.h" for float16, like we do for float128, or should we #include "llvm-libc-types/float16.h"?

libc/include/llvm-libc-types/float16.h Outdated Show resolved Hide resolved
libc/spec/stdc.td Outdated Show resolved Hide resolved
@nickdesaulniers
Copy link
Member

Should we #include "src/__support/macros/properties/types.h" for float16, like we do for float128, or should we #include "llvm-libc-types/float16.h"?

I think it's nice to be as specific as possible. To me, long include lists that are precise are a feature, not a bug.

libc/spec/stdc.td Outdated Show resolved Hide resolved
libc/config/linux/api.td Outdated Show resolved Hide resolved
Fix usage of internal float16 alias in generated headers.
Add check mark for fabsf16 in docs.
Fix missing include in generated math.h public header.
Replace includes for float16 alias with "include/llvm-libc-types/float16.h".
Simplify check for _Float16 support.
Fix llvm-libc-types/float16.h including internal header and exposing internal C++ using float16 stmt.
Remove unused direct dependency from fabsf16_test target.
Move _Float16 detection header to llvm-libc-macros/float16-macros.h.
@overmighty
Copy link
Member Author

Rebased and fixed the merge conflict.

Enable fabsf16 entrypoint on linux/aarch64.
Delete libc/include/llvm-libc-types/float16.h.
@lntue lntue merged commit 0eb9e02 into llvm:main May 30, 2024
7 checks passed
keith added a commit that referenced this pull request May 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants