[libc-commits] [libc] [libc][math] Implement `issignaling[f|l]` as a libc math function (PR #110556)

via libc-commits libc-commits at lists.llvm.org
Mon Sep 30 12:29:05 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libc

Author: Shourya Goel (Sh0g0-1758)

<details>
<summary>Changes</summary>

This PR implements the issignaling function as part of the libc math library, addressing the TODO items mentioned in #<!-- -->110011

The addition of this function is crucial for completing the implementation of remaining math macros, as referenced in #<!-- -->109201

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


17 Files Affected:

- (modified) libc/config/linux/aarch64/entrypoints.txt (+3) 
- (modified) libc/config/linux/riscv/entrypoints.txt (+3) 
- (modified) libc/config/linux/x86_64/entrypoints.txt (+3) 
- (modified) libc/src/__support/FPUtil/BasicOperations.h (+10) 
- (modified) libc/src/math/CMakeLists.txt (+4) 
- (modified) libc/src/math/generic/CMakeLists.txt (+30) 
- (added) libc/src/math/generic/issignaling.cpp (+20) 
- (added) libc/src/math/generic/issignalingf.cpp (+20) 
- (added) libc/src/math/generic/issignalingl.cpp (+21) 
- (added) libc/src/math/issignaling.h (+20) 
- (added) libc/src/math/issignalingf.h (+20) 
- (added) libc/src/math/issignalingl.h (+20) 
- (modified) libc/test/src/math/smoke/CMakeLists.txt (+39) 
- (added) libc/test/src/math/smoke/IsSignalingTest.h (+60) 
- (added) libc/test/src/math/smoke/issignaling_test.cpp (+13) 
- (added) libc/test/src/math/smoke/issignalingf_test.cpp (+13) 
- (added) libc/test/src/math/smoke/issignalingl_test.cpp (+13) 


``````````diff
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 64fbe1a250c0ba..21288d894705bc 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -479,6 +479,9 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.isnan
     libc.src.math.isnanf
     libc.src.math.isnanl
+    libc.src.math.issignaling
+    libc.src.math.issignalingf
+    libc.src.math.issignalingl
     libc.src.math.ldexp
     libc.src.math.ldexpf
     libc.src.math.ldexpl
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index ff3d821c664c5b..135a46099cb1fc 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -482,6 +482,9 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.isnan
     libc.src.math.isnanf
     libc.src.math.isnanl
+    libc.src.math.issignaling
+    libc.src.math.issignalingf
+    libc.src.math.issignalingl
     libc.src.math.ldexp
     libc.src.math.ldexpf
     libc.src.math.ldexpl
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index dd658af3bfb674..d877e3d696c67a 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -482,6 +482,9 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.isnan
     libc.src.math.isnanf
     libc.src.math.isnanl
+    libc.src.math.issignaling
+    libc.src.math.issignalingf
+    libc.src.math.issignalingl
     libc.src.math.ldexp
     libc.src.math.ldexpf
     libc.src.math.ldexpl
diff --git a/libc/src/__support/FPUtil/BasicOperations.h b/libc/src/__support/FPUtil/BasicOperations.h
index 824c9bfb3947f3..5b14feabe441a7 100644
--- a/libc/src/__support/FPUtil/BasicOperations.h
+++ b/libc/src/__support/FPUtil/BasicOperations.h
@@ -247,6 +247,16 @@ LIBC_INLINE T fdim(T x, T y) {
   return (x > y ? x - y : 0);
 }
 
+template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
+LIBC_INLINE int issignaling(const T &x) {
+  FPBits<T> sx(x);
+  if (LIBC_UNLIKELY(sx.is_signaling_nan())) {
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
 template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
 LIBC_INLINE int canonicalize(T &cx, const T &x) {
   FPBits<T> sx(x);
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index 3cba34fc249322..440f343f5c0bc0 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -302,6 +302,10 @@ add_math_entrypoint_object(isnan)
 add_math_entrypoint_object(isnanf)
 add_math_entrypoint_object(isnanl)
 
+add_math_entrypoint_object(issignaling)
+add_math_entrypoint_object(issignalingf)
+add_math_entrypoint_object(issignalingl)
+
 add_math_entrypoint_object(llogb)
 add_math_entrypoint_object(llogbf)
 add_math_entrypoint_object(llogbl)
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index d0676d03420c68..17e014adcae984 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -3377,6 +3377,36 @@ add_entrypoint_object(
     -O3
 )
 
+add_entrypoint_object(
+  issignaling
+  SRCS
+    issignaling.cpp
+  HDRS
+    ../issignaling.h
+  COMPILE_OPTIONS
+    -O3
+)
+
+add_entrypoint_object(
+  issignalingf
+  SRCS
+    issignalingf.cpp
+  HDRS
+    ../issignalingf.h
+  COMPILE_OPTIONS
+    -O3
+)
+
+add_entrypoint_object(
+  issignalingl
+  SRCS
+    issignalingl.cpp
+  HDRS
+    ../issignalingl.h
+  COMPILE_OPTIONS
+    -O3
+)
+
 add_entrypoint_object(
   isnan
   SRCS
diff --git a/libc/src/math/generic/issignaling.cpp b/libc/src/math/generic/issignaling.cpp
new file mode 100644
index 00000000000000..0687a32817b295
--- /dev/null
+++ b/libc/src/math/generic/issignaling.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of issignaling 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/issignaling.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, issignaling, (double x)) {
+  return fputil::issignaling(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/issignalingf.cpp b/libc/src/math/generic/issignalingf.cpp
new file mode 100644
index 00000000000000..410bf7b4d42782
--- /dev/null
+++ b/libc/src/math/generic/issignalingf.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of issignalingf 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/issignalingf.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, issignalingf, (float x)) {
+  return fputil::issignaling(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/generic/issignalingl.cpp b/libc/src/math/generic/issignalingl.cpp
new file mode 100644
index 00000000000000..b399bd2d5bc6a7
--- /dev/null
+++ b/libc/src/math/generic/issignalingl.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of issignalingl 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/issignalingl.h"
+#include "src/__support/FPUtil/BasicOperations.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, issignalingl, (long double x)) {
+  return fputil::issignaling(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/math/issignaling.h b/libc/src/math/issignaling.h
new file mode 100644
index 00000000000000..093fd7d48770dd
--- /dev/null
+++ b/libc/src/math/issignaling.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for issignaling -------------------*- 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_ISSIGNALING_H
+#define LLVM_LIBC_SRC_MATH_ISSIGNALING_H
+
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int issignaling(double x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_ISSIGNALING_H
diff --git a/libc/src/math/issignalingf.h b/libc/src/math/issignalingf.h
new file mode 100644
index 00000000000000..97522600916cce
--- /dev/null
+++ b/libc/src/math/issignalingf.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for issignalingf ------------------*- 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_ISSIGNALINGF_H
+#define LLVM_LIBC_SRC_MATH_ISSIGNALINGF_H
+
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int issignalingf(float x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_ISSIGNALINGF_H
diff --git a/libc/src/math/issignalingl.h b/libc/src/math/issignalingl.h
new file mode 100644
index 00000000000000..edc039416d1f4e
--- /dev/null
+++ b/libc/src/math/issignalingl.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for issignalingl ------------------*- 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_ISSIGNALINGL_H
+#define LLVM_LIBC_SRC_MATH_ISSIGNALINGL_H
+
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int issignalingl(long double x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_ISSIGNALINGL_H
diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index 9f9203c491d044..bb89f75a8fdad0 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -1597,6 +1597,45 @@ add_fp_unittest(
     libc.src.__support.FPUtil.manipulation_functions
 )
 
+add_fp_unittest(
+  issignaling_test
+  SUITE
+    libc-math-smoke-tests
+  SRCS
+    issignaling_test.cpp
+  HDRS
+    IsSignalingTest.h
+  DEPENDS
+    libc.src.math.issignaling
+    libc.src.__support.FPUtil.fp_bits
+)
+
+add_fp_unittest(
+  issignalingf_test
+  SUITE
+    libc-math-smoke-tests
+  SRCS
+    issignalingf_test.cpp
+  HDRS
+    IsSignalingTest.h
+  DEPENDS
+    libc.src.math.issignalingf
+    libc.src.__support.FPUtil.fp_bits
+)
+
+add_fp_unittest(
+  issignalingl_test
+  SUITE
+    libc-math-smoke-tests
+  SRCS
+    issignalingl_test.cpp
+  HDRS
+    IsSignalingTest.h
+  DEPENDS
+    libc.src.math.issignalingl
+    libc.src.__support.FPUtil.fp_bits
+)
+
 add_fp_unittest(
   llogb_test
   SUITE
diff --git a/libc/test/src/math/smoke/IsSignalingTest.h b/libc/test/src/math/smoke/IsSignalingTest.h
new file mode 100644
index 00000000000000..60773e2ccc4161
--- /dev/null
+++ b/libc/test/src/math/smoke/IsSignalingTest.h
@@ -0,0 +1,60 @@
+//===-- Utility class to test issignaling[f|l] ------------------*- 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_TEST_SRC_MATH_SMOKE_ISSIGNALINGTEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_ISSIGNALINGTEST_H
+
+#include "test/UnitTest/FEnvSafeTest.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+#include "hdr/math_macros.h"
+
+template <typename T>
+class IssignalingTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
+
+  DECLARE_SPECIAL_CONSTANTS(T)
+
+public:
+  typedef int (*IsSignalingFunc)(T);
+
+  void testSpecialNumbers(IsSignalingFunc func) {
+    EXPECT_EQ(func(aNaN), 0);
+    EXPECT_EQ(func(neg_aNaN), 0);
+    EXPECT_EQ(func(sNaN), 1);
+    EXPECT_EQ(func(neg_sNaN), 1);
+    EXPECT_EQ(func(inf), 0);
+    EXPECT_EQ(func(neg_inf), 0);
+    EXPECT_EQ(func(min_normal), 0);
+    EXPECT_EQ(func(max_normal), 0);
+    EXPECT_EQ(func(neg_max_normal), 0);
+    EXPECT_EQ(func(min_denormal), 0);
+    EXPECT_EQ(func(neg_min_denormal), 0);
+    EXPECT_EQ(func(max_denormal), 0);
+    EXPECT_EQ(func(zero), 0);
+    EXPECT_EQ(func(neg_zero), 0);
+  }
+
+  void testRoundedNumbers(IsSignalingFunc func) {
+    EXPECT_EQ(func(T(1.0)), 0);
+    EXPECT_EQ(func(T(-1.0)), 0);
+    EXPECT_EQ(func(T(10.0)), 0);
+    EXPECT_EQ(func(T(-10.0)), 0);
+    EXPECT_EQ(func(T(1234.0)), 0);
+    EXPECT_EQ(func(T(-1234.0)), 0);
+  }
+};
+
+#define LIST_ISSIGNALING_TESTS(T, func)                                        \
+  using LlvmLibcIsSignalingTest = IssignalingTest<T>;                          \
+  TEST_F(LlvmLibcIsSignalingTest, SpecialNumbers) {                            \
+    testSpecialNumbers(&func);                                                 \
+  }                                                                            \
+  TEST_F(LlvmLibcIsSignalingTest, RoundedNubmers) { testRoundedNumbers(&func); }
+
+#endif // LLVM_LIBC_TEST_SRC_MATH_SMOKE_ISSIGNALINGTEST_H
diff --git a/libc/test/src/math/smoke/issignaling_test.cpp b/libc/test/src/math/smoke/issignaling_test.cpp
new file mode 100644
index 00000000000000..4292cbbb852b49
--- /dev/null
+++ b/libc/test/src/math/smoke/issignaling_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for issignaling -----------------------------------------===//
+//
+// 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 "IsSignalingTest.h"
+
+#include "src/math/issignaling.h"
+
+LIST_ISSIGNALING_TESTS(double, LIBC_NAMESPACE::issignaling)
diff --git a/libc/test/src/math/smoke/issignalingf_test.cpp b/libc/test/src/math/smoke/issignalingf_test.cpp
new file mode 100644
index 00000000000000..0ceb9a80c03108
--- /dev/null
+++ b/libc/test/src/math/smoke/issignalingf_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for issignalingf ----------------------------------------===//
+//
+// 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 "IsSignalingTest.h"
+
+#include "src/math/issignalingf.h"
+
+LIST_ISSIGNALING_TESTS(float, LIBC_NAMESPACE::issignalingf)
diff --git a/libc/test/src/math/smoke/issignalingl_test.cpp b/libc/test/src/math/smoke/issignalingl_test.cpp
new file mode 100644
index 00000000000000..049769009ba7c6
--- /dev/null
+++ b/libc/test/src/math/smoke/issignalingl_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for issignalingl ----------------------------------------===//
+//
+// 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 "IsSignalingTest.h"
+
+#include "src/math/issignalingl.h"
+
+LIST_ISSIGNALING_TESTS(long double, LIBC_NAMESPACE::issignalingl)

``````````

</details>


https://github.com/llvm/llvm-project/pull/110556


More information about the libc-commits mailing list