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

Shourya Goel via libc-commits libc-commits at lists.llvm.org
Mon Oct 7 09:46:30 PDT 2024


https://github.com/Sh0g0-1758 created https://github.com/llvm/llvm-project/pull/111403

#109201 

>From a32e012b52043350169e6f6b18b0bded8021669b Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Fri, 4 Oct 2024 00:10:52 +0530
Subject: [PATCH 1/8] init

---
 .../llvm-libc-macros/math-function-macros.h   | 10 ++++---
 libc/test/include/CMakeLists.txt              | 30 -------------------
 libc/test/include/issignaling_test.c          |  9 +++---
 libc/test/include/issignaling_test.cpp        | 18 -----------
 libc/test/include/issignalingf_test.cpp       | 18 -----------
 libc/test/include/issignalingl_test.cpp       | 18 -----------
 6 files changed, 11 insertions(+), 92 deletions(-)
 delete mode 100644 libc/test/include/issignaling_test.cpp
 delete mode 100644 libc/test/include/issignalingf_test.cpp
 delete mode 100644 libc/test/include/issignalingl_test.cpp

diff --git a/libc/include/llvm-libc-macros/math-function-macros.h b/libc/include/llvm-libc-macros/math-function-macros.h
index c740eb2d188259..9ab1a4c70774e7 100644
--- a/libc/include/llvm-libc-macros/math-function-macros.h
+++ b/libc/include/llvm-libc-macros/math-function-macros.h
@@ -11,6 +11,12 @@
 
 #include "math-macros.h"
 
+#ifndef __cplusplus
+#define issignaling(x)                                                          \
+  _Generic((x), float : issignalingf, double : issignaling, long double :       \
+                 issignalingl)(x)
+#endif
+
 #define isfinite(x) __builtin_isfinite(x)
 #define isinf(x) __builtin_isinf(x)
 #define isnan(x) __builtin_isnan(x)
@@ -20,9 +26,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..a258bcddfddde4 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
diff --git a/libc/test/include/issignaling_test.c b/libc/test/include/issignaling_test.c
index 2c080696404aee..d65d3a818083e0 100644
--- a/libc/test/include/issignaling_test.c
+++ b/libc/test/include/issignaling_test.c
@@ -9,16 +9,17 @@
 
 #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

>From a1db27f2c01c929cc92f1d83fd15bb77902a2233 Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Fri, 4 Oct 2024 00:52:03 +0530
Subject: [PATCH 2/8] new changes

---
 libc/test/include/CMakeLists.txt     | 3 +++
 libc/test/include/issignaling_test.c | 3 +++
 2 files changed, 6 insertions(+)

diff --git a/libc/test/include/CMakeLists.txt b/libc/test/include/CMakeLists.txt
index a258bcddfddde4..a44214fd66679e 100644
--- a/libc/test/include/CMakeLists.txt
+++ b/libc/test/include/CMakeLists.txt
@@ -379,6 +379,9 @@ 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(
diff --git a/libc/test/include/issignaling_test.c b/libc/test/include/issignaling_test.c
index d65d3a818083e0..cce75ce9cce2d7 100644
--- a/libc/test/include/issignaling_test.c
+++ b/libc/test/include/issignaling_test.c
@@ -5,6 +5,9 @@
 // SPDSList-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
+#include "src/math/issignaling.h"
+#include "src/math/issignalingf.h"
+#include "src/math/issignalingl.h"
 #include "include/llvm-libc-macros/math-function-macros.h"
 
 #include <assert.h>

>From dd8a65f11befafad1010766e7e6f58168eec86c6 Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Fri, 4 Oct 2024 01:34:56 +0530
Subject: [PATCH 3/8] ok

---
 libc/test/include/CMakeLists.txt     | 6 +++---
 libc/test/include/issignaling_test.c | 7 ++++---
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/libc/test/include/CMakeLists.txt b/libc/test/include/CMakeLists.txt
index a44214fd66679e..5f45178a78c322 100644
--- a/libc/test/include/CMakeLists.txt
+++ b/libc/test/include/CMakeLists.txt
@@ -379,9 +379,9 @@ 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
+    libc.src.math.generic.issignaling
+    libc.src.math.generic.issignalingf
+    libc.src.math.generic.issignalingl
 )
 
 add_libc_test(
diff --git a/libc/test/include/issignaling_test.c b/libc/test/include/issignaling_test.c
index cce75ce9cce2d7..c89970c225469c 100644
--- a/libc/test/include/issignaling_test.c
+++ b/libc/test/include/issignaling_test.c
@@ -5,9 +5,10 @@
 // SPDSList-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-#include "src/math/issignaling.h"
-#include "src/math/issignalingf.h"
-#include "src/math/issignalingl.h"
+int issignaling(double);
+int issignalingf(float);
+int issignalingl(long double);
+
 #include "include/llvm-libc-macros/math-function-macros.h"
 
 #include <assert.h>

>From d0a5dc2f8dd8b90494bc1f2c0f7ee2be048d519a Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Fri, 4 Oct 2024 01:35:08 +0530
Subject: [PATCH 4/8] revert

---
 libc/test/include/CMakeLists.txt | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/libc/test/include/CMakeLists.txt b/libc/test/include/CMakeLists.txt
index 5f45178a78c322..a44214fd66679e 100644
--- a/libc/test/include/CMakeLists.txt
+++ b/libc/test/include/CMakeLists.txt
@@ -379,9 +379,9 @@ add_libc_test(
     -Werror
   DEPENDS
     libc.include.llvm-libc-macros.math_function_macros
-    libc.src.math.generic.issignaling
-    libc.src.math.generic.issignalingf
-    libc.src.math.generic.issignalingl
+    libc.src.math.issignaling
+    libc.src.math.issignalingf
+    libc.src.math.issignalingl
 )
 
 add_libc_test(

>From c617476253219bc85fd876b733eff3c4d287fc34 Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Mon, 7 Oct 2024 21:46:59 +0530
Subject: [PATCH 5/8] Fix cmake error

---
 libc/cmake/modules/LLVMLibCTestRules.cmake | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/libc/cmake/modules/LLVMLibCTestRules.cmake b/libc/cmake/modules/LLVMLibCTestRules.cmake
index 1f6ccb27f35f02..2549aa03eb5d16 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__")
+            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})

>From c748f563cc79eb8a37f3fc6a06a8f131d526def0 Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Mon, 7 Oct 2024 22:00:19 +0530
Subject: [PATCH 6/8] implement iscanonical macro

---
 libc/cmake/modules/LLVMLibCTestRules.cmake    |  2 +-
 .../llvm-libc-macros/math-function-macros.h   |  3 ++
 libc/test/include/CMakeLists.txt              | 18 +++++++
 libc/test/include/IsSignalingTest.h           | 49 -------------------
 libc/test/include/iscanonical_test.c          | 29 +++++++++++
 5 files changed, 51 insertions(+), 50 deletions(-)
 delete mode 100644 libc/test/include/IsSignalingTest.h
 create mode 100644 libc/test/include/iscanonical_test.c

diff --git a/libc/cmake/modules/LLVMLibCTestRules.cmake b/libc/cmake/modules/LLVMLibCTestRules.cmake
index 2549aa03eb5d16..0a636baa5d3e1a 100644
--- a/libc/cmake/modules/LLVMLibCTestRules.cmake
+++ b/libc/cmake/modules/LLVMLibCTestRules.cmake
@@ -68,7 +68,7 @@ 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__")
+          if(fq_target_name STREQUAL "libc.test.include.issignaling_c_test.__unit__" OR fq_targe_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})
diff --git a/libc/include/llvm-libc-macros/math-function-macros.h b/libc/include/llvm-libc-macros/math-function-macros.h
index 9ab1a4c70774e7..8cbca689235042 100644
--- a/libc/include/llvm-libc-macros/math-function-macros.h
+++ b/libc/include/llvm-libc-macros/math-function-macros.h
@@ -15,6 +15,9 @@
 #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)
diff --git a/libc/test/include/CMakeLists.txt b/libc/test/include/CMakeLists.txt
index a44214fd66679e..92185160628790 100644
--- a/libc/test/include/CMakeLists.txt
+++ b/libc/test/include/CMakeLists.txt
@@ -384,6 +384,24 @@ add_libc_test(
     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(
   isinf_c_test
   C_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

>From 2e2d8cfe0a56f6e8e754cad87840930d5d35bfd6 Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Mon, 7 Oct 2024 22:00:55 +0530
Subject: [PATCH 7/8] format

---
 .../llvm-libc-macros/math-function-macros.h      | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/libc/include/llvm-libc-macros/math-function-macros.h b/libc/include/llvm-libc-macros/math-function-macros.h
index 8cbca689235042..21d09f1f5e1a4f 100644
--- a/libc/include/llvm-libc-macros/math-function-macros.h
+++ b/libc/include/llvm-libc-macros/math-function-macros.h
@@ -12,12 +12,16 @@
 #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)
+#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)

>From 575c11d8d390fe0c94b9b12ce533686e61b9b14c Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Mon, 7 Oct 2024 22:13:01 +0530
Subject: [PATCH 8/8] fix typo

---
 libc/cmake/modules/LLVMLibCTestRules.cmake | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libc/cmake/modules/LLVMLibCTestRules.cmake b/libc/cmake/modules/LLVMLibCTestRules.cmake
index 0a636baa5d3e1a..bc8c901a028fda 100644
--- a/libc/cmake/modules/LLVMLibCTestRules.cmake
+++ b/libc/cmake/modules/LLVMLibCTestRules.cmake
@@ -68,7 +68,7 @@ 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_targe_name STREQUAL "libc.test.include.iscanonical_c_test.__unit__")
+          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})



More information about the libc-commits mailing list