diff options
| author | Shourya Goel <shouryagoel10000@gmail.com> | 2024-10-09 22:55:49 +0530 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-10-09 10:25:49 -0700 |
| commit | 4e33afee5a167d5293edeef15e414c0dbbcf3cef (patch) | |
| tree | 912e51073d335b0b416fc30c1ae4b655f16705a4 | |
| parent | 3a08551a0337e999d5d8ca0b0e591d1a2b934865 (diff) | |
| download | llvm-4e33afee5a167d5293edeef15e414c0dbbcf3cef.zip llvm-4e33afee5a167d5293edeef15e414c0dbbcf3cef.tar.gz llvm-4e33afee5a167d5293edeef15e414c0dbbcf3cef.tar.bz2 | |
[libc][math] Implement `issignaling` and `iscanonical` macro. (#111403)
#109201
| -rw-r--r-- | libc/cmake/modules/LLVMLibCTestRules.cmake | 4 | ||||
| -rw-r--r-- | libc/include/llvm-libc-macros/math-function-macros.h | 17 | ||||
| -rw-r--r-- | libc/test/include/CMakeLists.txt | 51 | ||||
| -rw-r--r-- | libc/test/include/IsSignalingTest.h | 49 | ||||
| -rw-r--r-- | libc/test/include/iscanonical_test.c | 29 | ||||
| -rw-r--r-- | libc/test/include/issignaling_test.c | 13 | ||||
| -rw-r--r-- | libc/test/include/issignaling_test.cpp | 18 | ||||
| -rw-r--r-- | libc/test/include/issignalingf_test.cpp | 18 | ||||
| -rw-r--r-- | libc/test/include/issignalingl_test.cpp | 18 |
9 files changed, 76 insertions, 141 deletions
diff --git a/libc/cmake/modules/LLVMLibCTestRules.cmake b/libc/cmake/modules/LLVMLibCTestRules.cmake index 1f6ccb2..35cc6fe4 100644 --- a/libc/cmake/modules/LLVMLibCTestRules.cmake +++ b/libc/cmake/modules/LLVMLibCTestRules.cmake @@ -68,6 +68,10 @@ 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) + # TODO: Remove this once we stop suffixing the target with ".__internal__" + 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 c740eb2..21d09f1 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 dd8f21b..9218516 100644 --- a/libc/test/include/CMakeLists.txt +++ b/libc/test/include/CMakeLists.txt @@ -82,36 +82,6 @@ add_libc_test( ) 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 libc_include_tests @@ -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 c369cfe..0000000 --- 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 0000000..c0ad23b --- /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 2c08069..c89970c 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 3d25ea3..0000000 --- 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 02426ce..0000000 --- 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 9897647..0000000 --- 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 |
