[libc-commits] [libc] 2d784b1 - [libc][math] Implement `iscanonical[f|l]` as a libc math function (#110565)

via libc-commits libc-commits at lists.llvm.org
Wed Oct 2 07:14:08 PDT 2024


Author: Shourya Goel
Date: 2024-10-02T10:14:04-04:00
New Revision: 2d784b194681e9a12b33bffec148d6edf1aadc13

URL: https://github.com/llvm/llvm-project/commit/2d784b194681e9a12b33bffec148d6edf1aadc13
DIFF: https://github.com/llvm/llvm-project/commit/2d784b194681e9a12b33bffec148d6edf1aadc13.diff

LOG: [libc][math] Implement `iscanonical[f|l]` as a libc math function (#110565)

This PR implements the iscanonical function as part of the libc math
library.

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

Added: 
    libc/src/math/generic/iscanonical.cpp
    libc/src/math/generic/iscanonicalf.cpp
    libc/src/math/generic/iscanonicalf128.cpp
    libc/src/math/generic/iscanonicalf16.cpp
    libc/src/math/generic/iscanonicall.cpp
    libc/src/math/iscanonical.h
    libc/src/math/iscanonicalf.h
    libc/src/math/iscanonicalf128.h
    libc/src/math/iscanonicalf16.h
    libc/src/math/iscanonicall.h
    libc/test/src/math/smoke/IsCanonicalTest.h
    libc/test/src/math/smoke/iscanonical_test.cpp
    libc/test/src/math/smoke/iscanonicalf128_test.cpp
    libc/test/src/math/smoke/iscanonicalf16_test.cpp
    libc/test/src/math/smoke/iscanonicalf_test.cpp
    libc/test/src/math/smoke/iscanonicall_test.cpp

Modified: 
    libc/config/linux/aarch64/entrypoints.txt
    libc/config/linux/riscv/entrypoints.txt
    libc/config/linux/x86_64/entrypoints.txt
    libc/docs/math/index.rst
    libc/spec/stdc.td
    libc/src/math/CMakeLists.txt
    libc/src/math/generic/CMakeLists.txt
    libc/test/src/math/smoke/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 5398593a51eac4..283c7bd77b4e8e 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -476,6 +476,9 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.ilogb
     libc.src.math.ilogbf
     libc.src.math.ilogbl
+    libc.src.math.iscanonical
+    libc.src.math.iscanonicalf
+    libc.src.math.iscanonicall
     libc.src.math.isnan
     libc.src.math.isnanf
     libc.src.math.isnanl
@@ -640,6 +643,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
     libc.src.math.fromfpxf16
     libc.src.math.getpayloadf16
     libc.src.math.ilogbf16
+    libc.src.math.iscanonicalf16
     libc.src.math.issignalingf16
     libc.src.math.ldexpf16
     libc.src.math.llogbf16
@@ -724,6 +728,7 @@ if(LIBC_TYPES_HAS_FLOAT128)
     libc.src.math.fsubf128
     libc.src.math.getpayloadf128
     libc.src.math.ilogbf128
+    libc.src.math.iscanonicalf128
     libc.src.math.issignalingf128
     libc.src.math.ldexpf128
     libc.src.math.llogbf128

diff  --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 3bbfb95166abb9..8312b2c453f231 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -479,6 +479,9 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.ilogb
     libc.src.math.ilogbf
     libc.src.math.ilogbl
+    libc.src.math.iscanonical
+    libc.src.math.iscanonicalf
+    libc.src.math.iscanonicall
     libc.src.math.isnan
     libc.src.math.isnanf
     libc.src.math.isnanl
@@ -630,6 +633,7 @@ if(LIBC_TYPES_HAS_FLOAT128)
     libc.src.math.fsubf128
     libc.src.math.getpayloadf128
     libc.src.math.ilogbf128
+    libc.src.math.iscanonicalf128
     libc.src.math.issignalingf128
     libc.src.math.ldexpf128
     libc.src.math.llogbf128

diff  --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 113c6838d06d3b..806ccbcdf820a0 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -479,6 +479,9 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.ilogb
     libc.src.math.ilogbf
     libc.src.math.ilogbl
+    libc.src.math.iscanonical
+    libc.src.math.iscanonicalf
+    libc.src.math.iscanonicall
     libc.src.math.isnan
     libc.src.math.isnanf
     libc.src.math.isnanl
@@ -640,6 +643,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
     libc.src.math.fromfpxf16
     libc.src.math.getpayloadf16
     libc.src.math.ilogbf16
+    libc.src.math.iscanonicalf16
     libc.src.math.issignalingf16
     libc.src.math.ldexpf16
     libc.src.math.llogbf16
@@ -721,6 +725,7 @@ if(LIBC_TYPES_HAS_FLOAT128)
     libc.src.math.fsubf128
     libc.src.math.getpayloadf128
     libc.src.math.ilogbf128
+    libc.src.math.iscanonicalf128
     libc.src.math.issignalingf128
     libc.src.math.ldexpf128
     libc.src.math.llogbf128

diff  --git a/libc/docs/math/index.rst b/libc/docs/math/index.rst
index a98f107e5cb23b..0e757e7978bfa5 100644
--- a/libc/docs/math/index.rst
+++ b/libc/docs/math/index.rst
@@ -182,6 +182,8 @@ Basic Operations
 +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
 | ilogb            | |check|          | |check|         | |check|                | |check|              | |check|                | 7.12.6.8               | F.10.3.8                   |
 +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
+| iscanonical      | |check|          | |check|         | |check|                | |check|              | |check|                | 7.12.3.2               | N/A                        |
++------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
 | issignaling      | |check|          | |check|         | |check|                | |check|              | |check|                | 7.12.3.8               | N/A                        |
 +------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
 | ldexp            | |check|          | |check|         | |check|                | |check|              | |check|                | 7.12.6.9               | F.10.3.9                   |

diff  --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index 834ac786b25196..dadd1ef11d7d3f 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -837,6 +837,12 @@ def StdC : StandardSpec<"stdc"> {
           GuardedFunctionSpec<"canonicalizef16", RetValSpec<IntType>, [ArgSpec<Float16Type>, ArgSpec<Float16Type>], "LIBC_TYPES_HAS_FLOAT16">,
           GuardedFunctionSpec<"canonicalizef128", RetValSpec<IntType>, [ArgSpec<Float128Type>, ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT128">,
 
+          FunctionSpec<"iscanonical", RetValSpec<IntType>, [ArgSpec<DoubleType>]>,
+          FunctionSpec<"iscanonicalf", RetValSpec<IntType>, [ArgSpec<FloatType>]>,
+          FunctionSpec<"iscanonicall", RetValSpec<IntType>, [ArgSpec<LongDoubleType>]>,
+          GuardedFunctionSpec<"iscanonicalf16", RetValSpec<IntType>, [ArgSpec<Float16Type>], "LIBC_TYPES_HAS_FLOAT16">,
+          GuardedFunctionSpec<"iscanonicalf128", RetValSpec<IntType>, [ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT128">,
+
           FunctionSpec<"dsqrtl", RetValSpec<DoubleType>, [ArgSpec<LongDoubleType>]>,
 
           FunctionSpec<"totalorder", RetValSpec<IntType>, [ArgSpec<ConstDoublePtr>, ArgSpec<ConstDoublePtr>]>,

diff  --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index dab5bb43ed59ce..97e2d0d64a147b 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -66,6 +66,12 @@ add_math_entrypoint_object(canonicalizel)
 add_math_entrypoint_object(canonicalizef16)
 add_math_entrypoint_object(canonicalizef128)
 
+add_math_entrypoint_object(iscanonical)
+add_math_entrypoint_object(iscanonicalf)
+add_math_entrypoint_object(iscanonicall)
+add_math_entrypoint_object(iscanonicalf16)
+add_math_entrypoint_object(iscanonicalf128)
+
 add_math_entrypoint_object(cbrt)
 add_math_entrypoint_object(cbrtf)
 

diff  --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index 5e1b2a54a131a9..93e632c38af238 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -60,6 +60,60 @@ add_entrypoint_object(
     libc.src.__support.FPUtil.basic_operations
 )
 
+add_entrypoint_object(
+  iscanonical
+  SRCS
+    iscanonical.cpp
+  HDRS
+    ../iscanonical.h
+  COMPILE_OPTIONS
+    -O3
+)
+
+add_entrypoint_object(
+  iscanonicalf
+  SRCS
+    iscanonicalf.cpp
+  HDRS
+    ../iscanonicalf.h
+  COMPILE_OPTIONS
+    -O3
+)
+
+add_entrypoint_object(
+  iscanonicall
+  SRCS
+    iscanonicall.cpp
+  HDRS
+    ../iscanonicall.h
+  COMPILE_OPTIONS
+    -O3
+)
+
+add_entrypoint_object(
+  iscanonicalf16
+  SRCS
+    iscanonicalf16.cpp
+  HDRS
+    ../iscanonicalf16.h
+  COMPILE_OPTIONS
+    -O3
+  DEPENDS
+    libc.src.__support.macros.properties.types
+)
+
+add_entrypoint_object(
+  iscanonicalf128
+  SRCS
+    iscanonicalf128.cpp
+  HDRS
+    ../iscanonicalf128.h
+  COMPILE_OPTIONS
+    -O3
+  DEPENDS
+    libc.src.__support.macros.properties.types
+)
+
 add_entrypoint_object(
   ceil
   SRCS

diff  --git a/libc/src/math/generic/iscanonical.cpp b/libc/src/math/generic/iscanonical.cpp
new file mode 100644
index 00000000000000..d67a6b87b3e506
--- /dev/null
+++ b/libc/src/math/generic/iscanonical.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of iscanonical 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/iscanonical.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, iscanonical, (double x)) {
+  double temp;
+  return static_cast<int>(fputil::canonicalize(temp, x) == 0);
+}
+
+} // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/src/math/generic/iscanonicalf.cpp b/libc/src/math/generic/iscanonicalf.cpp
new file mode 100644
index 00000000000000..daa0708794d2f4
--- /dev/null
+++ b/libc/src/math/generic/iscanonicalf.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of iscanonicalf 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/iscanonicalf.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, iscanonicalf, (float x)) {
+  float temp;
+  return static_cast<int>(fputil::canonicalize(temp, x) == 0);
+}
+
+} // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/src/math/generic/iscanonicalf128.cpp b/libc/src/math/generic/iscanonicalf128.cpp
new file mode 100644
index 00000000000000..9be50050f8234c
--- /dev/null
+++ b/libc/src/math/generic/iscanonicalf128.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of iscanonicalf128 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/iscanonicalf128.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, iscanonicalf128, (float128 x)) {
+  float128 temp;
+  return static_cast<int>(fputil::canonicalize(temp, x) == 0);
+}
+
+} // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/src/math/generic/iscanonicalf16.cpp b/libc/src/math/generic/iscanonicalf16.cpp
new file mode 100644
index 00000000000000..4f7bb1a0050f51
--- /dev/null
+++ b/libc/src/math/generic/iscanonicalf16.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of iscanonicalf16 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/iscanonicalf16.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, iscanonicalf16, (float16 x)) {
+  float16 temp;
+  return static_cast<int>(fputil::canonicalize(temp, x) == 0);
+}
+
+} // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/src/math/generic/iscanonicall.cpp b/libc/src/math/generic/iscanonicall.cpp
new file mode 100644
index 00000000000000..756c1f8fb4abfa
--- /dev/null
+++ b/libc/src/math/generic/iscanonicall.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of iscanonicall 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/iscanonicall.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, iscanonicall, (long double x)) {
+  long double temp;
+  return static_cast<int>(fputil::canonicalize(temp, x) == 0);
+}
+
+} // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/src/math/iscanonical.h b/libc/src/math/iscanonical.h
new file mode 100644
index 00000000000000..14b2d17c8bbe9a
--- /dev/null
+++ b/libc/src/math/iscanonical.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for iscanonical -------------------*- 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_ISCANONICAL_H
+#define LLVM_LIBC_SRC_MATH_ISCANONICAL_H
+
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int iscanonical(double x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_ISCANONICAL_H

diff  --git a/libc/src/math/iscanonicalf.h b/libc/src/math/iscanonicalf.h
new file mode 100644
index 00000000000000..fdb48bc2767be4
--- /dev/null
+++ b/libc/src/math/iscanonicalf.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for iscanonicalf ------------------*- 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_ISCANONICALF_H
+#define LLVM_LIBC_SRC_MATH_ISCANONICALF_H
+
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int iscanonicalf(float x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_ISCANONICALF_H

diff  --git a/libc/src/math/iscanonicalf128.h b/libc/src/math/iscanonicalf128.h
new file mode 100644
index 00000000000000..9ba021c86ec147
--- /dev/null
+++ b/libc/src/math/iscanonicalf128.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for iscanonicalf128 ---------------*- 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_ISCANONICALF128_H
+#define LLVM_LIBC_SRC_MATH_ISCANONICALF128_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int iscanonicalf128(float128 x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_ISCANONICALF128_H

diff  --git a/libc/src/math/iscanonicalf16.h b/libc/src/math/iscanonicalf16.h
new file mode 100644
index 00000000000000..565d3eae35c49c
--- /dev/null
+++ b/libc/src/math/iscanonicalf16.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for iscanonicalf16 ----------------*- 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_ISCANONICALF16_H
+#define LLVM_LIBC_SRC_MATH_ISCANONICALF16_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/types.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int iscanonicalf16(float16 x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_ISCANONICALF16_H

diff  --git a/libc/src/math/iscanonicall.h b/libc/src/math/iscanonicall.h
new file mode 100644
index 00000000000000..edda6e334f1ab9
--- /dev/null
+++ b/libc/src/math/iscanonicall.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for iscanonicall ------------------*- 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_ISCANONICALL_H
+#define LLVM_LIBC_SRC_MATH_ISCANONICALL_H
+
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+int iscanonicall(long double x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_MATH_ISCANONICALL_H

diff  --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index 5c3068eb0de886..a70b65f23f4b71 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -327,6 +327,66 @@ add_fp_unittest(
     libc.src.__support.integer_literals
 )
 
+add_fp_unittest(
+  iscanonical_test
+  SUITE
+    libc-math-smoke-tests
+  SRCS
+    iscanonical_test.cpp
+  HDRS
+    IsCanonicalTest.h
+  DEPENDS
+    libc.src.math.iscanonical
+)
+
+add_fp_unittest(
+  iscanonicalf_test
+  SUITE
+    libc-math-smoke-tests
+  SRCS
+    iscanonicalf_test.cpp
+  HDRS
+    IsCanonicalTest.h
+  DEPENDS
+    libc.src.math.iscanonicalf
+)
+
+add_fp_unittest(
+  iscanonicall_test
+  SUITE
+    libc-math-smoke-tests
+  SRCS
+    iscanonicall_test.cpp
+  HDRS
+    IsCanonicalTest.h
+  DEPENDS
+    libc.src.math.iscanonicall
+)
+
+add_fp_unittest(
+  iscanonicalf16_test
+  SUITE
+    libc-math-smoke-tests
+  SRCS
+    iscanonicalf16_test.cpp
+  HDRS
+    IsCanonicalTest.h
+  DEPENDS
+    libc.src.math.iscanonicalf16
+)
+
+add_fp_unittest(
+  iscanonicalf128_test
+  SUITE
+    libc-math-smoke-tests
+  SRCS
+    iscanonicalf128_test.cpp
+  HDRS
+    IsCanonicalTest.h
+  DEPENDS
+    libc.src.math.iscanonicalf128
+)
+
 add_fp_unittest(
   ceil_test
   SUITE

diff  --git a/libc/test/src/math/smoke/IsCanonicalTest.h b/libc/test/src/math/smoke/IsCanonicalTest.h
new file mode 100644
index 00000000000000..8b6554b97f0351
--- /dev/null
+++ b/libc/test/src/math/smoke/IsCanonicalTest.h
@@ -0,0 +1,58 @@
+//===-- Utility class to test 
diff erent flavors of iscanonical --*- 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_ISCANONICALTEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_ISCANONICALTEST_H
+
+#include "test/UnitTest/FEnvSafeTest.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+template <typename T>
+class IsCanonicalTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
+
+  DECLARE_SPECIAL_CONSTANTS(T)
+
+public:
+  typedef int (*IsCanonicalFunc)(T);
+
+  void testSpecialNumbers(IsCanonicalFunc func) {
+    EXPECT_EQ(func(aNaN), 1);
+    EXPECT_EQ(func(neg_aNaN), 1);
+    EXPECT_EQ(func(sNaN), 0);
+    EXPECT_EQ(func(neg_sNaN), 0);
+    EXPECT_EQ(func(inf), 1);
+    EXPECT_EQ(func(neg_inf), 1);
+    EXPECT_EQ(func(min_normal), 1);
+    EXPECT_EQ(func(max_normal), 1);
+    EXPECT_EQ(func(neg_max_normal), 1);
+    EXPECT_EQ(func(min_denormal), 1);
+    EXPECT_EQ(func(neg_min_denormal), 1);
+    EXPECT_EQ(func(max_denormal), 1);
+    EXPECT_EQ(func(zero), 1);
+    EXPECT_EQ(func(neg_zero), 1);
+  }
+
+  void testRoundedNumbers(IsCanonicalFunc func) {
+    EXPECT_EQ(func(T(1.0)), 1);
+    EXPECT_EQ(func(T(-1.0)), 1);
+    EXPECT_EQ(func(T(10.0)), 1);
+    EXPECT_EQ(func(T(-10.0)), 1);
+    EXPECT_EQ(func(T(1234.0)), 1);
+    EXPECT_EQ(func(T(-1234.0)), 1);
+  }
+};
+
+#define LIST_ISCANONICAL_TESTS(T, func)                                        \
+  using LlvmLibcIsCanonicalTest = IsCanonicalTest<T>;                          \
+  TEST_F(LlvmLibcIsCanonicalTest, SpecialNumbers) {                            \
+    testSpecialNumbers(&func);                                                 \
+  }                                                                            \
+  TEST_F(LlvmLibcIsCanonicalTest, RoundedNubmers) { testRoundedNumbers(&func); }
+
+#endif // LLVM_LIBC_TEST_SRC_MATH_SMOKE_ISCANONICALTEST_H

diff  --git a/libc/test/src/math/smoke/iscanonical_test.cpp b/libc/test/src/math/smoke/iscanonical_test.cpp
new file mode 100644
index 00000000000000..2dd1c2ac6f0451
--- /dev/null
+++ b/libc/test/src/math/smoke/iscanonical_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for iscanonical -----------------------------------------===//
+//
+// 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 "IsCanonicalTest.h"
+
+#include "src/math/iscanonical.h"
+
+LIST_ISCANONICAL_TESTS(double, LIBC_NAMESPACE::iscanonical)

diff  --git a/libc/test/src/math/smoke/iscanonicalf128_test.cpp b/libc/test/src/math/smoke/iscanonicalf128_test.cpp
new file mode 100644
index 00000000000000..0176ae2f223dad
--- /dev/null
+++ b/libc/test/src/math/smoke/iscanonicalf128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for iscanonicalf128 -------------------------------------===//
+//
+// 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 "IsCanonicalTest.h"
+
+#include "src/math/iscanonicalf128.h"
+
+LIST_ISCANONICAL_TESTS(float128, LIBC_NAMESPACE::iscanonicalf128)

diff  --git a/libc/test/src/math/smoke/iscanonicalf16_test.cpp b/libc/test/src/math/smoke/iscanonicalf16_test.cpp
new file mode 100644
index 00000000000000..d17d79f86139e0
--- /dev/null
+++ b/libc/test/src/math/smoke/iscanonicalf16_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for iscanonicalf16 --------------------------------------===//
+//
+// 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 "IsCanonicalTest.h"
+
+#include "src/math/iscanonicalf16.h"
+
+LIST_ISCANONICAL_TESTS(float16, LIBC_NAMESPACE::iscanonicalf16)

diff  --git a/libc/test/src/math/smoke/iscanonicalf_test.cpp b/libc/test/src/math/smoke/iscanonicalf_test.cpp
new file mode 100644
index 00000000000000..eba8688f61f940
--- /dev/null
+++ b/libc/test/src/math/smoke/iscanonicalf_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for iscanonicalf ----------------------------------------===//
+//
+// 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 "IsCanonicalTest.h"
+
+#include "src/math/iscanonicalf.h"
+
+LIST_ISCANONICAL_TESTS(float, LIBC_NAMESPACE::iscanonicalf)

diff  --git a/libc/test/src/math/smoke/iscanonicall_test.cpp b/libc/test/src/math/smoke/iscanonicall_test.cpp
new file mode 100644
index 00000000000000..d180bcb7443e54
--- /dev/null
+++ b/libc/test/src/math/smoke/iscanonicall_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for iscanonicall ----------------------------------------===//
+//
+// 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 "IsCanonicalTest.h"
+
+#include "src/math/iscanonicall.h"
+
+LIST_ISCANONICAL_TESTS(long double, LIBC_NAMESPACE::iscanonicall)


        


More information about the libc-commits mailing list