[libc-commits] [libc] [libc][math] Implement `issignaling` and `iscanonical` macro. (PR #111403)

via libc-commits libc-commits at lists.llvm.org
Mon Oct 7 09:47:10 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libc

Author: Shourya Goel (Sh0g0-1758)

<details>
<summary>Changes</summary>

#<!-- -->109201 

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


9 Files Affected:

- (modified) libc/cmake/modules/LLVMLibCTestRules.cmake (+3) 
- (modified) libc/include/llvm-libc-macros/math-function-macros.h (+13-4) 
- (modified) libc/test/include/CMakeLists.txt (+21-30) 
- (removed) libc/test/include/IsSignalingTest.h (-49) 
- (added) libc/test/include/iscanonical_test.c (+29) 
- (modified) libc/test/include/issignaling_test.c (+9-4) 
- (removed) libc/test/include/issignaling_test.cpp (-18) 
- (removed) libc/test/include/issignalingf_test.cpp (-18) 
- (removed) libc/test/include/issignalingl_test.cpp (-18) 


``````````diff
diff --git a/libc/cmake/modules/LLVMLibCTestRules.cmake b/libc/cmake/modules/LLVMLibCTestRules.cmake
index 1f6ccb27f35f02..bc8c901a028fda 100644
--- a/libc/cmake/modules/LLVMLibCTestRules.cmake
+++ b/libc/cmake/modules/LLVMLibCTestRules.cmake
@@ -68,6 +68,9 @@ function(get_object_files_for_test result skipped_entrypoints_list)
         endif()
         get_target_property(object_file_raw ${dep} "OBJECT_FILE_RAW")
         if(object_file_raw)
+          if(fq_target_name STREQUAL "libc.test.include.issignaling_c_test.__unit__" OR fq_target_name STREQUAL "libc.test.include.iscanonical_c_test.__unit__")
+            string(REPLACE ".__internal__" "" object_file_raw ${object_file_raw})
+          endif()
           list(APPEND dep_obj ${object_file_raw})
         endif()
       elseif(${dep_type} STREQUAL ${ENTRYPOINT_OBJ_VENDOR_TARGET_TYPE})
diff --git a/libc/include/llvm-libc-macros/math-function-macros.h b/libc/include/llvm-libc-macros/math-function-macros.h
index c740eb2d188259..21d09f1f5e1a4f 100644
--- a/libc/include/llvm-libc-macros/math-function-macros.h
+++ b/libc/include/llvm-libc-macros/math-function-macros.h
@@ -11,6 +11,19 @@
 
 #include "math-macros.h"
 
+#ifndef __cplusplus
+#define issignaling(x)                                                         \
+  _Generic((x),                                                                \
+      float: issignalingf,                                                     \
+      double: issignaling,                                                     \
+      long double: issignalingl)(x)
+#define iscanonical(x)                                                         \
+  _Generic((x),                                                                \
+      float: iscanonicalf,                                                     \
+      double: iscanonical,                                                     \
+      long double: iscanonicall)(x)
+#endif
+
 #define isfinite(x) __builtin_isfinite(x)
 #define isinf(x) __builtin_isinf(x)
 #define isnan(x) __builtin_isnan(x)
@@ -20,9 +33,5 @@
   __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, x)
 #define isnormal(x) __builtin_isnormal(x)
 #define issubnormal(x) (fpclassify(x) == FP_SUBNORMAL)
-#if (defined(__clang__) && __clang_major__ >= 18) ||                           \
-    (defined(__GNUC__) && __GNUC__ >= 13)
-#define issignaling(x) __builtin_issignaling(x)
-#endif
 
 #endif // LLVM_LIBC_MACROS_MATH_FUNCTION_MACROS_H
diff --git a/libc/test/include/CMakeLists.txt b/libc/test/include/CMakeLists.txt
index dd8f21bdd07aeb..92185160628790 100644
--- a/libc/test/include/CMakeLists.txt
+++ b/libc/test/include/CMakeLists.txt
@@ -81,36 +81,6 @@ add_libc_test(
     libc.include.llvm-libc-macros.stdckdint_macros
 )
 
-add_libc_test(
-  issignaling_test
-  SUITE
-    libc_include_tests
-  SRCS
-    issignaling_test.cpp
-  DEPENDS
-    libc.include.llvm-libc-macros.math_function_macros
-)
-
-add_libc_test(
-  issignalingf_test
-  SUITE
-    libc_include_tests
-  SRCS
-    issignalingf_test.cpp
-  DEPENDS
-    libc.include.llvm-libc-macros.math_function_macros
-)
-
-add_libc_test(
-  issignalingl_test
-  SUITE
-    libc_include_tests
-  SRCS
-    issignalingl_test.cpp
-  DEPENDS
-    libc.include.llvm-libc-macros.math_function_macros
-)
-
 add_libc_test(
   issubnormal_test
   SUITE
@@ -409,6 +379,27 @@ add_libc_test(
     -Werror
   DEPENDS
     libc.include.llvm-libc-macros.math_function_macros
+    libc.src.math.issignaling
+    libc.src.math.issignalingf
+    libc.src.math.issignalingl
+)
+
+add_libc_test(
+  iscanonical_c_test
+  C_TEST
+  UNIT_TEST_ONLY
+  SUITE
+    libc_include_tests
+  SRCS
+    iscanonical_test.c
+  COMPILE_OPTIONS
+    -Wall
+    -Werror
+  DEPENDS
+    libc.include.llvm-libc-macros.math_function_macros
+    libc.src.math.iscanonical
+    libc.src.math.iscanonicalf
+    libc.src.math.iscanonicall
 )
 
 add_libc_test(
diff --git a/libc/test/include/IsSignalingTest.h b/libc/test/include/IsSignalingTest.h
deleted file mode 100644
index c369cfe090ed30..00000000000000
--- a/libc/test/include/IsSignalingTest.h
+++ /dev/null
@@ -1,49 +0,0 @@
-//===-- Utility class to test the issignaling macro  ------------*- 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_INCLUDE_MATH_ISSIGNALING_H
-#define LLVM_LIBC_TEST_INCLUDE_MATH_ISSIGNALING_H
-
-#include "test/UnitTest/FPMatcher.h"
-#include "test/UnitTest/Test.h"
-
-#include "include/llvm-libc-macros/math-function-macros.h"
-
-template <typename T>
-class IsSignalingTest : public LIBC_NAMESPACE::testing::Test {
-  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);
-  }
-};
-
-#define LIST_ISSIGNALING_TESTS(T, func)                                        \
-  using LlvmLibcIsSignalingTest = IsSignalingTest<T>;                          \
-  TEST_F(LlvmLibcIsSignalingTest, SpecialNumbers) {                            \
-    auto issignaling_func = [](T x) { return func(x); };                       \
-    testSpecialNumbers(issignaling_func);                                      \
-  }
-
-#endif // LLVM_LIBC_TEST_INCLUDE_MATH_ISSIGNALING_H
diff --git a/libc/test/include/iscanonical_test.c b/libc/test/include/iscanonical_test.c
new file mode 100644
index 00000000000000..c0ad23b21826d7
--- /dev/null
+++ b/libc/test/include/iscanonical_test.c
@@ -0,0 +1,29 @@
+//===-- Unittests for iscanonical macro -----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDSList-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+int iscanonical(double);
+int iscanonicalf(float);
+int iscanonicall(long double);
+
+#include "include/llvm-libc-macros/math-function-macros.h"
+
+#include <assert.h>
+
+// check if macro is defined
+#ifndef iscanonical
+#error "iscanonical macro is not defined"
+#else
+int main(void) {
+  assert(iscanonical(__builtin_nans("")) == 0);
+  assert(iscanonical(__builtin_nansf("")) == 0);
+  assert(iscanonical(__builtin_nansl("")) == 0);
+  assert(iscanonical(1.819f) == 1);
+  assert(iscanonical(-1.726) == 1);
+  assert(iscanonical(1.426L) == 1);
+  return 0;
+}
+#endif
diff --git a/libc/test/include/issignaling_test.c b/libc/test/include/issignaling_test.c
index 2c080696404aee..c89970c225469c 100644
--- a/libc/test/include/issignaling_test.c
+++ b/libc/test/include/issignaling_test.c
@@ -5,20 +5,25 @@
 // SPDSList-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
+int issignaling(double);
+int issignalingf(float);
+int issignalingl(long double);
+
 #include "include/llvm-libc-macros/math-function-macros.h"
 
 #include <assert.h>
 
-// TODO: enable the test unconditionally when issignaling macro is fixed for
-//       older compiler
+// check if macro is defined
+#ifndef issignaling
+#error "issignaling macro is not defined"
+#else
 int main(void) {
-#ifdef issignaling
   assert(issignaling(__builtin_nans("")) == 1);
   assert(issignaling(__builtin_nansf("")) == 1);
   assert(issignaling(__builtin_nansl("")) == 1);
   assert(issignaling(1.819f) == 0);
   assert(issignaling(-1.726) == 0);
   assert(issignaling(1.426L) == 0);
-#endif
   return 0;
 }
+#endif
diff --git a/libc/test/include/issignaling_test.cpp b/libc/test/include/issignaling_test.cpp
deleted file mode 100644
index 3d25ea394c835f..00000000000000
--- a/libc/test/include/issignaling_test.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-//===-- Unittest for issignaling[d] macro ---------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDSList-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "IsSignalingTest.h"
-#include "include/llvm-libc-macros/math-function-macros.h"
-
-// TODO: enable the test unconditionally when issignaling macro is fixed for
-//       older compiler
-#ifdef issignaling
-LIST_ISSIGNALING_TESTS(double, issignaling)
-#else
-TEST(LlvmLibcIsSignalingTest, Skip) {}
-#endif
diff --git a/libc/test/include/issignalingf_test.cpp b/libc/test/include/issignalingf_test.cpp
deleted file mode 100644
index 02426ceb24ac84..00000000000000
--- a/libc/test/include/issignalingf_test.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-//===-- Unittest for issignaling[f] macro ---------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDSList-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "IsSignalingTest.h"
-#include "include/llvm-libc-macros/math-function-macros.h"
-
-// TODO: enable the test unconditionally when issignaling macro is fixed for
-//       older compiler
-#ifdef issignaling
-LIST_ISSIGNALING_TESTS(float, issignaling)
-#else
-TEST(LlvmLibcIsSignalingTest, Skip) {}
-#endif
diff --git a/libc/test/include/issignalingl_test.cpp b/libc/test/include/issignalingl_test.cpp
deleted file mode 100644
index 9897647fb1077f..00000000000000
--- a/libc/test/include/issignalingl_test.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-//===-- Unittest for issignaling[l] macro ---------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDSList-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "IsSignalingTest.h"
-#include "include/llvm-libc-macros/math-function-macros.h"
-
-// TODO: enable the test unconditionally when issignaling macro is fixed for
-//       older compiler
-#ifdef issignaling
-LIST_ISSIGNALING_TESTS(long double, issignaling)
-#else
-TEST(LlvmLibcIsSignalingTest, Skip) {}
-#endif

``````````

</details>


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


More information about the libc-commits mailing list