[libc-commits] [libc] [libc][math][c23] Implement canonicalize functions (PR #85940)

Shourya Goel via libc-commits libc-commits at lists.llvm.org
Fri Mar 22 04:30:36 PDT 2024


https://github.com/Sh0g0-1758 updated https://github.com/llvm/llvm-project/pull/85940

>From bac0896cbb68c6badf90b3c6df77e424689d6af2 Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Tue, 19 Mar 2024 17:05:25 +0530
Subject: [PATCH 01/24] Initial commit

---
 libc/config/linux/x86_64/entrypoints.txt    |  4 ++++
 libc/spec/stdc.td                           |  5 +++++
 libc/src/math/CMakeLists.txt                |  5 +++++
 libc/src/math/canonicalize.h                | 18 +++++++++++++++++
 libc/src/math/canonicalizef.h               | 18 +++++++++++++++++
 libc/src/math/canonicalizef128.h            | 18 +++++++++++++++++
 libc/src/math/canonicalizel.h               | 18 +++++++++++++++++
 libc/src/math/generic/canonicalize.cpp      | 22 +++++++++++++++++++++
 libc/src/math/generic/canonicalizef.cpp     | 22 +++++++++++++++++++++
 libc/src/math/generic/canonicalizef128.cpp  | 22 +++++++++++++++++++++
 libc/src/math/generic/canonicalizel.cpp     | 20 +++++++++++++++++++
 libc/test/src/math/smoke/canonicalizeTest.h |  0
 12 files changed, 172 insertions(+)
 create mode 100644 libc/src/math/canonicalize.h
 create mode 100644 libc/src/math/canonicalizef.h
 create mode 100644 libc/src/math/canonicalizef128.h
 create mode 100644 libc/src/math/canonicalizel.h
 create mode 100644 libc/src/math/generic/canonicalize.cpp
 create mode 100644 libc/src/math/generic/canonicalizef.cpp
 create mode 100644 libc/src/math/generic/canonicalizef128.cpp
 create mode 100644 libc/src/math/generic/canonicalizel.cpp
 create mode 100644 libc/test/src/math/smoke/canonicalizeTest.h

diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index f81d334e9e788d..8d1ef82d50122d 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -342,6 +342,10 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.asinhf
     libc.src.math.atanf
     libc.src.math.atanhf
+    libc.src.math.canonicalize
+    libc.src.math.canonicalizef
+    libc.src.math.canonicalizef128
+    libc.src.math.canonicalizel
     libc.src.math.copysign
     libc.src.math.copysignf
     libc.src.math.copysignl
diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index 84d28cc3350304..e696eb24c8c83e 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -570,6 +570,11 @@ def StdC : StandardSpec<"stdc"> {
           FunctionSpec<"nan", RetValSpec<DoubleType>, [ArgSpec<ConstCharPtr>]>,
           FunctionSpec<"nanl", RetValSpec<LongDoubleType>, [ArgSpec<ConstCharPtr>]>,
           GuardedFunctionSpec<"nanf128", RetValSpec<Float128Type>, [ArgSpec<ConstCharPtr>], "LIBC_TYPES_HAS_FLOAT128">,
+
+          FunctionSpec<"canonicalize", RetValSpec<IntType>, [ArgSpec<DoubleType>, ArgSpec<DoubleType>]>,
+          FunctionSpec<"canonicalizef", RetValSpec<IntType>, [ArgSpec<FloatType>, ArgSpec<FloatType>]>,
+          FunctionAttrSpec<"canonicalizef128", RetValSpec<IntType>, [ArgSpec<Float128Type>, ArgSpec<Float128Type>]>,
+          FunctionSpec<"canonicalizel", RetValSpec<IntType>, [ArgSpec<LongDoubleType>, ArgSpec<LongDoubleType>]>,
       ]
   >;
 
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index 5e2e6e699d0e0c..5e027b541a8fe8 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -59,6 +59,11 @@ add_math_entrypoint_object(atan2f)
 add_math_entrypoint_object(atanh)
 add_math_entrypoint_object(atanhf)
 
+add_math_entrypoint_object(canonicalize)
+add_math_entrypoint_object(canonicalizef)
+add_math_entrypoint_object(canonicalizef128)
+add_math_entrypoint_object(canonicalizel)
+
 add_math_entrypoint_object(ceil)
 add_math_entrypoint_object(ceilf)
 add_math_entrypoint_object(ceill)
diff --git a/libc/src/math/canonicalize.h b/libc/src/math/canonicalize.h
new file mode 100644
index 00000000000000..967d4ee26e52f2
--- /dev/null
+++ b/libc/src/math/canonicalize.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for canonicalize ------------------------*- 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_CANONICALIZE_H
+#define LLVM_LIBC_SRC_MATH_CANONICALIZE_H
+
+namespace LIBC_NAMESPACE {
+
+int canonicalize(double* cx, const double *x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_CANONICALIZE_H
diff --git a/libc/src/math/canonicalizef.h b/libc/src/math/canonicalizef.h
new file mode 100644
index 00000000000000..5441ef9913334b
--- /dev/null
+++ b/libc/src/math/canonicalizef.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for canonicalizef ------------------------*- 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_CANONICALIZEF_H
+#define LLVM_LIBC_SRC_MATH_CANONICALIZEF_H
+
+namespace LIBC_NAMESPACE {
+
+int canonicalizef(float* cx, const float *x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_CANONICALIZEF_H
diff --git a/libc/src/math/canonicalizef128.h b/libc/src/math/canonicalizef128.h
new file mode 100644
index 00000000000000..ef7988e4b0df18
--- /dev/null
+++ b/libc/src/math/canonicalizef128.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for canonicalizef128 ------------------------*- 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_CANONICALIZEF128_H
+#define LLVM_LIBC_SRC_MATH_CANONICALIZEF128_H
+
+namespace LIBC_NAMESPACE {
+
+int canonicalizef128(float128* cx, const float128* x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_CANONICALIZEF128_H
diff --git a/libc/src/math/canonicalizel.h b/libc/src/math/canonicalizel.h
new file mode 100644
index 00000000000000..182d102c598564
--- /dev/null
+++ b/libc/src/math/canonicalizel.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for canonicalizel ------------------------*- 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_CANONICALIZEL_H
+#define LLVM_LIBC_SRC_MATH_CANONICALIZEL_H
+
+namespace LIBC_NAMESPACE {
+
+int canonicalizel(long double* cx, const long double *x);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_CANONICALIZEL_H
diff --git a/libc/src/math/generic/canonicalize.cpp b/libc/src/math/generic/canonicalize.cpp
new file mode 100644
index 00000000000000..50411d403149c6
--- /dev/null
+++ b/libc/src/math/generic/canonicalize.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation of canonicalize 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/canonicalize.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, canonicalize, (double *cx, const double *x)) {
+    if (cx == nullptr || x == nullptr || std::isnan(*x) || std::isinf(*x))
+        return 1;
+    *cx = *x;
+    return 0;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/canonicalizef.cpp b/libc/src/math/generic/canonicalizef.cpp
new file mode 100644
index 00000000000000..549e28a167e6e6
--- /dev/null
+++ b/libc/src/math/generic/canonicalizef.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation of canonicalizef 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/canonicalizef.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, canonicalizef, (float *cx, const float *x)) {
+    if (cx == nullptr || x == nullptr || std::isnan(*x) || std::isinf(*x))
+        return 1;
+    *cx = *x;
+    return 0;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/canonicalizef128.cpp b/libc/src/math/generic/canonicalizef128.cpp
new file mode 100644
index 00000000000000..15f1cdaedbab2c
--- /dev/null
+++ b/libc/src/math/generic/canonicalizef128.cpp
@@ -0,0 +1,22 @@
+//===-- Implementation of canonicalizef128 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/canonicalizef128.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, canonicalizef128, (float128 *cx, const float128 *x)) {
+    if (cx == nullptr || x == nullptr || std::isnan(*x) || std::isinf(*x))
+        return 1;
+    *cx = *x;
+    return 0;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/canonicalizel.cpp b/libc/src/math/generic/canonicalizel.cpp
new file mode 100644
index 00000000000000..d60a8edfc460b5
--- /dev/null
+++ b/libc/src/math/generic/canonicalizel.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of canonicalizel 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/canonicalizel.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, canonicalizel, (long double *cx, const long double *x)) {
+    // TO DO : IMPLEMENT
+    return 0;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/test/src/math/smoke/canonicalizeTest.h b/libc/test/src/math/smoke/canonicalizeTest.h
new file mode 100644
index 00000000000000..e69de29bb2d1d6

>From debe41f46bdfc2d24ea085d2ddd0f6fdf79beaf2 Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Wed, 20 Mar 2024 18:04:53 +0530
Subject: [PATCH 02/24] Initial implementation

---
 libc/spec/stdc.td                           |  2 +-
 libc/src/math/canonicalizef128.h            |  2 +
 libc/src/math/generic/CMakeLists.txt        | 52 +++++++++++++++
 libc/src/math/generic/canonicalize.cpp      | 11 ++--
 libc/src/math/generic/canonicalizef.cpp     | 11 ++--
 libc/src/math/generic/canonicalizef128.cpp  |  9 ++-
 libc/src/math/generic/canonicalizel.cpp     |  9 ++-
 libc/test/src/math/smoke/canonicalizeTest.h | 73 +++++++++++++++++++++
 8 files changed, 155 insertions(+), 14 deletions(-)

diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index e696eb24c8c83e..87800784fc173c 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -573,7 +573,7 @@ def StdC : StandardSpec<"stdc"> {
 
           FunctionSpec<"canonicalize", RetValSpec<IntType>, [ArgSpec<DoubleType>, ArgSpec<DoubleType>]>,
           FunctionSpec<"canonicalizef", RetValSpec<IntType>, [ArgSpec<FloatType>, ArgSpec<FloatType>]>,
-          FunctionAttrSpec<"canonicalizef128", RetValSpec<IntType>, [ArgSpec<Float128Type>, ArgSpec<Float128Type>]>,
+          FunctionSpec<"canonicalizef128", RetValSpec<IntType>, [ArgSpec<Float128Type>, ArgSpec<Float128Type>]>,
           FunctionSpec<"canonicalizel", RetValSpec<IntType>, [ArgSpec<LongDoubleType>, ArgSpec<LongDoubleType>]>,
       ]
   >;
diff --git a/libc/src/math/canonicalizef128.h b/libc/src/math/canonicalizef128.h
index ef7988e4b0df18..a5059e84b65993 100644
--- a/libc/src/math/canonicalizef128.h
+++ b/libc/src/math/canonicalizef128.h
@@ -9,6 +9,8 @@
 #ifndef LLVM_LIBC_SRC_MATH_CANONICALIZEF128_H
 #define LLVM_LIBC_SRC_MATH_CANONICALIZEF128_H
 
+#include "src/__support/macros/properties/types.h"
+
 namespace LIBC_NAMESPACE {
 
 int canonicalizef128(float128* cx, const float128* x);
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index b0a35c652cd587..8ee93939575390 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -1,3 +1,55 @@
+add_entrypoint_object(
+  canonicalize
+  SRCS
+    canonicalize.cpp
+  HDRS
+    ../canonicalize.h
+  COMPILE_OPTIONS
+    -O3
+  DEPENDS
+    libc.src.__support.FPUtil.fp_bits
+    libc.src.__support.FPUtil.fenv_impl
+)
+
+add_entrypoint_object(
+  canonicalizef
+  SRCS
+    canonicalizef.cpp
+  HDRS
+    ../canonicalizef.h
+  COMPILE_OPTIONS
+    -O3
+  DEPENDS
+    libc.src.__support.FPUtil.fp_bits
+    libc.src.__support.FPUtil.fenv_impl
+)
+
+add_entrypoint_object(
+  canonicalizef128
+  SRCS
+    canonicalizef128.cpp
+  HDRS
+    ../canonicalizef128.h
+  COMPILE_OPTIONS
+    -O3
+  DEPENDS
+    libc.src.__support.FPUtil.fp_bits
+    libc.src.__support.FPUtil.fenv_impl
+)
+
+add_entrypoint_object(
+  canonicalizel
+  SRCS
+    canonicalizel.cpp
+  HDRS
+    ../canonicalizel.h
+  COMPILE_OPTIONS
+    -O3
+  DEPENDS
+    libc.src.__support.FPUtil.fp_bits
+    libc.src.__support.FPUtil.fenv_impl
+)
+
 add_entrypoint_object(
   ceil
   SRCS
diff --git a/libc/src/math/generic/canonicalize.cpp b/libc/src/math/generic/canonicalize.cpp
index 50411d403149c6..6d4d82b407605e 100644
--- a/libc/src/math/generic/canonicalize.cpp
+++ b/libc/src/math/generic/canonicalize.cpp
@@ -4,17 +4,20 @@
 // See https://llvm.org/LICENSE.txt for license information.
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
-//===----------------------------------------------------------------------===//
+//===-----------------------------------------------------------------------------===//
 
 #include "src/math/canonicalize.h"
-#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
 #include "src/__support/common.h"
 
 namespace LIBC_NAMESPACE {
 
 LLVM_LIBC_FUNCTION(int, canonicalize, (double *cx, const double *x)) {
-    if (cx == nullptr || x == nullptr || std::isnan(*x) || std::isinf(*x))
-        return 1;
+    using FPB = fputil::FPBits<double>;
+    FPB sx(*x);
+    if (sx.is_signaling_nan())
+        fputil::raise_except_if_required(FE_INVALID);
     *cx = *x;
     return 0;
 }
diff --git a/libc/src/math/generic/canonicalizef.cpp b/libc/src/math/generic/canonicalizef.cpp
index 549e28a167e6e6..f2fc232fed60b3 100644
--- a/libc/src/math/generic/canonicalizef.cpp
+++ b/libc/src/math/generic/canonicalizef.cpp
@@ -4,17 +4,20 @@
 // See https://llvm.org/LICENSE.txt for license information.
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
-//===----------------------------------------------------------------------===//
+//===------------------------------------------------------------------------------===//
 
 #include "src/math/canonicalizef.h"
-#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
 #include "src/__support/common.h"
 
 namespace LIBC_NAMESPACE {
 
 LLVM_LIBC_FUNCTION(int, canonicalizef, (float *cx, const float *x)) {
-    if (cx == nullptr || x == nullptr || std::isnan(*x) || std::isinf(*x))
-        return 1;
+    using FPB = fputil::FPBits<float>;
+    FPB sx(*x);
+    if (sx.is_signaling_nan())
+        fputil::raise_except_if_required(FE_INVALID);
     *cx = *x;
     return 0;
 }
diff --git a/libc/src/math/generic/canonicalizef128.cpp b/libc/src/math/generic/canonicalizef128.cpp
index 15f1cdaedbab2c..d83c249e331a2b 100644
--- a/libc/src/math/generic/canonicalizef128.cpp
+++ b/libc/src/math/generic/canonicalizef128.cpp
@@ -7,14 +7,17 @@
 //===---------------------------------------------------------------------------------===//
 
 #include "src/math/canonicalizef128.h"
-#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
 #include "src/__support/common.h"
 
 namespace LIBC_NAMESPACE {
 
 LLVM_LIBC_FUNCTION(int, canonicalizef128, (float128 *cx, const float128 *x)) {
-    if (cx == nullptr || x == nullptr || std::isnan(*x) || std::isinf(*x))
-        return 1;
+    using FPB = fputil::FPBits<float128>;
+    FPB sx(*x);
+    if (sx.is_signaling_nan())
+        fputil::raise_except_if_required(FE_INVALID);
     *cx = *x;
     return 0;
 }
diff --git a/libc/src/math/generic/canonicalizel.cpp b/libc/src/math/generic/canonicalizel.cpp
index d60a8edfc460b5..d067f00311bda8 100644
--- a/libc/src/math/generic/canonicalizel.cpp
+++ b/libc/src/math/generic/canonicalizel.cpp
@@ -7,13 +7,18 @@
 //===----------------------------------------------------------------------===//
 
 #include "src/math/canonicalizel.h"
-#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
 #include "src/__support/common.h"
 
 namespace LIBC_NAMESPACE {
 
 LLVM_LIBC_FUNCTION(int, canonicalizel, (long double *cx, const long double *x)) {
-    // TO DO : IMPLEMENT
+    using FPB = fputil::FPBits<long double>;
+    FPB sx(*x);
+    if (sx.is_signaling_nan())
+        fputil::raise_except_if_required(FE_INVALID);
+    *cx = *x;
     return 0;
 }
 
diff --git a/libc/test/src/math/smoke/canonicalizeTest.h b/libc/test/src/math/smoke/canonicalizeTest.h
index e69de29bb2d1d6..6c57df08791bcf 100644
--- a/libc/test/src/math/smoke/canonicalizeTest.h
+++ b/libc/test/src/math/smoke/canonicalizeTest.h
@@ -0,0 +1,73 @@
+// //===-- Utility class to test canonicalize[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_CANONICALIZETEST_H
+// #define LLVM_LIBC_TEST_SRC_MATH_SMOKE_CANONICALIZETEST_H
+
+// #include "test/UnitTest/FPMatcher.h"
+// #include "test/UnitTest/Test.h"
+
+// #include <math.h>
+
+// template <typename T> class CanonicalizeTest : public LIBC_NAMESPACE::testing::Test {
+
+//   DECLARE_SPECIAL_CONSTANTS(T)
+
+// public:
+//   typedef T (*CeilFunc)(T);
+
+//   void testSpecialNumbers(CeilFunc func) {
+//     EXPECT_FP_EQ(zero, func(zero));
+//     EXPECT_FP_EQ(neg_zero, func(neg_zero));
+
+//     EXPECT_FP_EQ(inf, func(inf));
+//     EXPECT_FP_EQ(neg_inf, func(neg_inf));
+
+//     EXPECT_FP_EQ(aNaN, func(aNaN));
+//   }
+
+//   void testRoundedNumbers(CeilFunc func) {
+//     EXPECT_FP_EQ(T(1.0), func(T(1.0)));
+//     EXPECT_FP_EQ(T(-1.0), func(T(-1.0)));
+//     EXPECT_FP_EQ(T(10.0), func(T(10.0)));
+//     EXPECT_FP_EQ(T(-10.0), func(T(-10.0)));
+//     EXPECT_FP_EQ(T(1234.0), func(T(1234.0)));
+//     EXPECT_FP_EQ(T(-1234.0), func(T(-1234.0)));
+//   }
+
+//   void testFractions(CeilFunc func) {
+//     EXPECT_FP_EQ(T(1.0), func(T(0.5)));
+//     EXPECT_FP_EQ(T(-0.0), func(T(-0.5)));
+//     EXPECT_FP_EQ(T(1.0), func(T(0.115)));
+//     EXPECT_FP_EQ(T(-0.0), func(T(-0.115)));
+//     EXPECT_FP_EQ(T(1.0), func(T(0.715)));
+//     EXPECT_FP_EQ(T(-0.0), func(T(-0.715)));
+//     EXPECT_FP_EQ(T(2.0), func(T(1.3)));
+//     EXPECT_FP_EQ(T(-1.0), func(T(-1.3)));
+//     EXPECT_FP_EQ(T(2.0), func(T(1.5)));
+//     EXPECT_FP_EQ(T(-1.0), func(T(-1.5)));
+//     EXPECT_FP_EQ(T(2.0), func(T(1.75)));
+//     EXPECT_FP_EQ(T(-1.0), func(T(-1.75)));
+//     EXPECT_FP_EQ(T(11.0), func(T(10.32)));
+//     EXPECT_FP_EQ(T(-10.0), func(T(-10.32)));
+//     EXPECT_FP_EQ(T(11.0), func(T(10.65)));
+//     EXPECT_FP_EQ(T(-10.0), func(T(-10.65)));
+//     EXPECT_FP_EQ(T(1235.0), func(T(1234.38)));
+//     EXPECT_FP_EQ(T(-1234.0), func(T(-1234.38)));
+//     EXPECT_FP_EQ(T(1235.0), func(T(1234.96)));
+//     EXPECT_FP_EQ(T(-1234.0), func(T(-1234.96)));
+//   }
+// };
+
+// #define LIST_CEIL_TESTS(T, func)                                               \
+//   using LlvmLibcCeilTest = CeilTest<T>;                                        \
+//   TEST_F(LlvmLibcCeilTest, SpecialNumbers) { testSpecialNumbers(&func); }      \
+//   TEST_F(LlvmLibcCeilTest, RoundedNubmers) { testRoundedNumbers(&func); }      \
+//   TEST_F(LlvmLibcCeilTest, Fractions) { testFractions(&func); }
+
+// #endif // LLVM_LIBC_TEST_SRC_MATH_SMOKE_CEILTEST_H

>From 8e2663ce947d727b05fe3bdbc09f76ab5db7116d Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Wed, 20 Mar 2024 18:16:08 +0530
Subject: [PATCH 03/24] Added space

---
 libc/src/math/generic/canonicalize.cpp  | 5 +++--
 libc/src/math/generic/canonicalizel.cpp | 2 +-
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/libc/src/math/generic/canonicalize.cpp b/libc/src/math/generic/canonicalize.cpp
index 6d4d82b407605e..f711f0a5c57cdb 100644
--- a/libc/src/math/generic/canonicalize.cpp
+++ b/libc/src/math/generic/canonicalize.cpp
@@ -17,8 +17,9 @@ LLVM_LIBC_FUNCTION(int, canonicalize, (double *cx, const double *x)) {
     using FPB = fputil::FPBits<double>;
     FPB sx(*x);
     if (sx.is_signaling_nan())
-        fputil::raise_except_if_required(FE_INVALID);
-    *cx = *x;
+        *cx = quiet_nan();
+    else
+        *cx = *x;
     return 0;
 }
 
diff --git a/libc/src/math/generic/canonicalizel.cpp b/libc/src/math/generic/canonicalizel.cpp
index d067f00311bda8..13db7fa298d39b 100644
--- a/libc/src/math/generic/canonicalizel.cpp
+++ b/libc/src/math/generic/canonicalizel.cpp
@@ -4,7 +4,7 @@
 // See https://llvm.org/LICENSE.txt for license information.
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
-//===----------------------------------------------------------------------===//
+//===-------------------------------------------------------------------------------===//
 
 #include "src/math/canonicalizel.h"
 #include "src/__support/FPUtil/FPBits.h"

>From 911dea8866c2e432046bff93f582120b3e11af62 Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Wed, 20 Mar 2024 18:16:49 +0530
Subject: [PATCH 04/24] Ran formatter

---
 libc/src/math/canonicalize.h                |  5 +++--
 libc/src/math/canonicalizef.h               |  5 +++--
 libc/src/math/canonicalizef128.h            |  5 +++--
 libc/src/math/canonicalizel.h               |  5 +++--
 libc/src/math/generic/canonicalize.cpp      | 19 ++++++++++---------
 libc/src/math/generic/canonicalizef.cpp     | 17 +++++++++--------
 libc/src/math/generic/canonicalizef128.cpp  | 19 ++++++++++---------
 libc/src/math/generic/canonicalizel.cpp     | 20 +++++++++++---------
 libc/test/src/math/smoke/canonicalizeTest.h |  9 ++++++---
 9 files changed, 58 insertions(+), 46 deletions(-)

diff --git a/libc/src/math/canonicalize.h b/libc/src/math/canonicalize.h
index 967d4ee26e52f2..9c682d85e7b73d 100644
--- a/libc/src/math/canonicalize.h
+++ b/libc/src/math/canonicalize.h
@@ -1,4 +1,5 @@
-//===-- Implementation header for canonicalize ------------------------*- C++ -*-===//
+//===-- Implementation header for canonicalize ------------------------*- C++
+//-*-===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -11,7 +12,7 @@
 
 namespace LIBC_NAMESPACE {
 
-int canonicalize(double* cx, const double *x);
+int canonicalize(double *cx, const double *x);
 
 } // namespace LIBC_NAMESPACE
 
diff --git a/libc/src/math/canonicalizef.h b/libc/src/math/canonicalizef.h
index 5441ef9913334b..d7f0c41024721a 100644
--- a/libc/src/math/canonicalizef.h
+++ b/libc/src/math/canonicalizef.h
@@ -1,4 +1,5 @@
-//===-- Implementation header for canonicalizef ------------------------*- C++ -*-===//
+//===-- Implementation header for canonicalizef ------------------------*- C++
+//-*-===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -11,7 +12,7 @@
 
 namespace LIBC_NAMESPACE {
 
-int canonicalizef(float* cx, const float *x);
+int canonicalizef(float *cx, const float *x);
 
 } // namespace LIBC_NAMESPACE
 
diff --git a/libc/src/math/canonicalizef128.h b/libc/src/math/canonicalizef128.h
index a5059e84b65993..3efdbec9334925 100644
--- a/libc/src/math/canonicalizef128.h
+++ b/libc/src/math/canonicalizef128.h
@@ -1,4 +1,5 @@
-//===-- Implementation header for canonicalizef128 ------------------------*- C++ -*-===//
+//===-- Implementation header for canonicalizef128 ------------------------*-
+//C++ -*-===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -13,7 +14,7 @@
 
 namespace LIBC_NAMESPACE {
 
-int canonicalizef128(float128* cx, const float128* x);
+int canonicalizef128(float128 *cx, const float128 *x);
 
 } // namespace LIBC_NAMESPACE
 
diff --git a/libc/src/math/canonicalizel.h b/libc/src/math/canonicalizel.h
index 182d102c598564..febc852514f7a0 100644
--- a/libc/src/math/canonicalizel.h
+++ b/libc/src/math/canonicalizel.h
@@ -1,4 +1,5 @@
-//===-- Implementation header for canonicalizel ------------------------*- C++ -*-===//
+//===-- Implementation header for canonicalizel ------------------------*- C++
+//-*-===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -11,7 +12,7 @@
 
 namespace LIBC_NAMESPACE {
 
-int canonicalizel(long double* cx, const long double *x);
+int canonicalizel(long double *cx, const long double *x);
 
 } // namespace LIBC_NAMESPACE
 
diff --git a/libc/src/math/generic/canonicalize.cpp b/libc/src/math/generic/canonicalize.cpp
index f711f0a5c57cdb..73452ced9302cd 100644
--- a/libc/src/math/generic/canonicalize.cpp
+++ b/libc/src/math/generic/canonicalize.cpp
@@ -1,4 +1,5 @@
-//===-- Implementation of canonicalize function ----------------------------------===//
+//===-- Implementation of canonicalize function
+//----------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -7,20 +8,20 @@
 //===-----------------------------------------------------------------------------===//
 
 #include "src/math/canonicalize.h"
-#include "src/__support/FPUtil/FPBits.h"
 #include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
 #include "src/__support/common.h"
 
 namespace LIBC_NAMESPACE {
 
 LLVM_LIBC_FUNCTION(int, canonicalize, (double *cx, const double *x)) {
-    using FPB = fputil::FPBits<double>;
-    FPB sx(*x);
-    if (sx.is_signaling_nan())
-        *cx = quiet_nan();
-    else
-        *cx = *x;
-    return 0;
+  using FPB = fputil::FPBits<double>;
+  FPB sx(*x);
+  if (sx.is_signaling_nan())
+    *cx = quiet_nan();
+  else
+    *cx = *x;
+  return 0;
 }
 
 } // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/canonicalizef.cpp b/libc/src/math/generic/canonicalizef.cpp
index f2fc232fed60b3..7a41acfbf1d03e 100644
--- a/libc/src/math/generic/canonicalizef.cpp
+++ b/libc/src/math/generic/canonicalizef.cpp
@@ -1,4 +1,5 @@
-//===-- Implementation of canonicalizef function ----------------------------------===//
+//===-- Implementation of canonicalizef function
+//----------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -7,19 +8,19 @@
 //===------------------------------------------------------------------------------===//
 
 #include "src/math/canonicalizef.h"
-#include "src/__support/FPUtil/FPBits.h"
 #include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
 #include "src/__support/common.h"
 
 namespace LIBC_NAMESPACE {
 
 LLVM_LIBC_FUNCTION(int, canonicalizef, (float *cx, const float *x)) {
-    using FPB = fputil::FPBits<float>;
-    FPB sx(*x);
-    if (sx.is_signaling_nan())
-        fputil::raise_except_if_required(FE_INVALID);
-    *cx = *x;
-    return 0;
+  using FPB = fputil::FPBits<float>;
+  FPB sx(*x);
+  if (sx.is_signaling_nan())
+    fputil::raise_except_if_required(FE_INVALID);
+  *cx = *x;
+  return 0;
 }
 
 } // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/canonicalizef128.cpp b/libc/src/math/generic/canonicalizef128.cpp
index d83c249e331a2b..c1f74d30792746 100644
--- a/libc/src/math/generic/canonicalizef128.cpp
+++ b/libc/src/math/generic/canonicalizef128.cpp
@@ -1,4 +1,5 @@
-//===-- Implementation of canonicalizef128 function ----------------------------------===//
+//===-- Implementation of canonicalizef128 function
+//----------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -7,19 +8,19 @@
 //===---------------------------------------------------------------------------------===//
 
 #include "src/math/canonicalizef128.h"
-#include "src/__support/FPUtil/FPBits.h"
 #include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
 #include "src/__support/common.h"
 
 namespace LIBC_NAMESPACE {
 
-LLVM_LIBC_FUNCTION(int, canonicalizef128, (float128 *cx, const float128 *x)) {
-    using FPB = fputil::FPBits<float128>;
-    FPB sx(*x);
-    if (sx.is_signaling_nan())
-        fputil::raise_except_if_required(FE_INVALID);
-    *cx = *x;
-    return 0;
+LLVM_LIBC_FUNCTION(int, canonicalizef128, (float128 * cx, const float128 *x)) {
+  using FPB = fputil::FPBits<float128>;
+  FPB sx(*x);
+  if (sx.is_signaling_nan())
+    fputil::raise_except_if_required(FE_INVALID);
+  *cx = *x;
+  return 0;
 }
 
 } // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/canonicalizel.cpp b/libc/src/math/generic/canonicalizel.cpp
index 13db7fa298d39b..a90755783c508a 100644
--- a/libc/src/math/generic/canonicalizel.cpp
+++ b/libc/src/math/generic/canonicalizel.cpp
@@ -1,4 +1,5 @@
-//===-- Implementation of canonicalizel function ----------------------------------===//
+//===-- Implementation of canonicalizel function
+//----------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -7,19 +8,20 @@
 //===-------------------------------------------------------------------------------===//
 
 #include "src/math/canonicalizel.h"
-#include "src/__support/FPUtil/FPBits.h"
 #include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
 #include "src/__support/common.h"
 
 namespace LIBC_NAMESPACE {
 
-LLVM_LIBC_FUNCTION(int, canonicalizel, (long double *cx, const long double *x)) {
-    using FPB = fputil::FPBits<long double>;
-    FPB sx(*x);
-    if (sx.is_signaling_nan())
-        fputil::raise_except_if_required(FE_INVALID);
-    *cx = *x;
-    return 0;
+LLVM_LIBC_FUNCTION(int, canonicalizel,
+                   (long double *cx, const long double *x)) {
+  using FPB = fputil::FPBits<long double>;
+  FPB sx(*x);
+  if (sx.is_signaling_nan())
+    fputil::raise_except_if_required(FE_INVALID);
+  *cx = *x;
+  return 0;
 }
 
 } // namespace LIBC_NAMESPACE
diff --git a/libc/test/src/math/smoke/canonicalizeTest.h b/libc/test/src/math/smoke/canonicalizeTest.h
index 6c57df08791bcf..d481d96e5459e6 100644
--- a/libc/test/src/math/smoke/canonicalizeTest.h
+++ b/libc/test/src/math/smoke/canonicalizeTest.h
@@ -1,6 +1,8 @@
-// //===-- Utility class to test canonicalize[f|l] -------------------------*- C++ -*-===//
+// //===-- Utility class to test canonicalize[f|l] -------------------------*-
+// C++ -*-===//
 // //
-// // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// // 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
 // //
@@ -14,7 +16,8 @@
 
 // #include <math.h>
 
-// template <typename T> class CanonicalizeTest : public LIBC_NAMESPACE::testing::Test {
+// template <typename T> class CanonicalizeTest : public
+// LIBC_NAMESPACE::testing::Test {
 
 //   DECLARE_SPECIAL_CONSTANTS(T)
 

>From 60d5f939c6c35cdd0b2ec50d8dc01111731ba4a7 Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Wed, 20 Mar 2024 18:17:03 +0530
Subject: [PATCH 05/24] Formatter

---
 libc/src/math/canonicalizef128.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libc/src/math/canonicalizef128.h b/libc/src/math/canonicalizef128.h
index 3efdbec9334925..315cee10cb99da 100644
--- a/libc/src/math/canonicalizef128.h
+++ b/libc/src/math/canonicalizef128.h
@@ -1,5 +1,5 @@
 //===-- Implementation header for canonicalizef128 ------------------------*-
-//C++ -*-===//
+// C++ -*-===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.

>From 57c34d3e42f0b634d1de48fb5f519b0545af4431 Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Wed, 20 Mar 2024 20:12:54 +0530
Subject: [PATCH 06/24] minor updates

---
 libc/src/math/generic/canonicalizef.cpp    | 2 +-
 libc/src/math/generic/canonicalizef128.cpp | 2 +-
 libc/src/math/generic/canonicalizel.cpp    | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/libc/src/math/generic/canonicalizef.cpp b/libc/src/math/generic/canonicalizef.cpp
index 7a41acfbf1d03e..d39e7228a6f68c 100644
--- a/libc/src/math/generic/canonicalizef.cpp
+++ b/libc/src/math/generic/canonicalizef.cpp
@@ -18,7 +18,7 @@ LLVM_LIBC_FUNCTION(int, canonicalizef, (float *cx, const float *x)) {
   using FPB = fputil::FPBits<float>;
   FPB sx(*x);
   if (sx.is_signaling_nan())
-    fputil::raise_except_if_required(FE_INVALID);
+    *cx = quiet_nan();
   *cx = *x;
   return 0;
 }
diff --git a/libc/src/math/generic/canonicalizef128.cpp b/libc/src/math/generic/canonicalizef128.cpp
index c1f74d30792746..6b0ef80dd41b61 100644
--- a/libc/src/math/generic/canonicalizef128.cpp
+++ b/libc/src/math/generic/canonicalizef128.cpp
@@ -18,7 +18,7 @@ LLVM_LIBC_FUNCTION(int, canonicalizef128, (float128 * cx, const float128 *x)) {
   using FPB = fputil::FPBits<float128>;
   FPB sx(*x);
   if (sx.is_signaling_nan())
-    fputil::raise_except_if_required(FE_INVALID);
+    *cx = quiet_nan();
   *cx = *x;
   return 0;
 }
diff --git a/libc/src/math/generic/canonicalizel.cpp b/libc/src/math/generic/canonicalizel.cpp
index a90755783c508a..fe03ed6677c5b4 100644
--- a/libc/src/math/generic/canonicalizel.cpp
+++ b/libc/src/math/generic/canonicalizel.cpp
@@ -19,7 +19,7 @@ LLVM_LIBC_FUNCTION(int, canonicalizel,
   using FPB = fputil::FPBits<long double>;
   FPB sx(*x);
   if (sx.is_signaling_nan())
-    fputil::raise_except_if_required(FE_INVALID);
+    *cx = quiet_nan();
   *cx = *x;
   return 0;
 }

>From e17ecb067b750167934d4b4db941c404acc9e0b4 Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Wed, 20 Mar 2024 20:15:03 +0530
Subject: [PATCH 07/24] Cleaned the code

---
 libc/test/src/math/smoke/canonicalizeTest.h | 76 ---------------------
 1 file changed, 76 deletions(-)

diff --git a/libc/test/src/math/smoke/canonicalizeTest.h b/libc/test/src/math/smoke/canonicalizeTest.h
index d481d96e5459e6..e69de29bb2d1d6 100644
--- a/libc/test/src/math/smoke/canonicalizeTest.h
+++ b/libc/test/src/math/smoke/canonicalizeTest.h
@@ -1,76 +0,0 @@
-// //===-- Utility class to test canonicalize[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_CANONICALIZETEST_H
-// #define LLVM_LIBC_TEST_SRC_MATH_SMOKE_CANONICALIZETEST_H
-
-// #include "test/UnitTest/FPMatcher.h"
-// #include "test/UnitTest/Test.h"
-
-// #include <math.h>
-
-// template <typename T> class CanonicalizeTest : public
-// LIBC_NAMESPACE::testing::Test {
-
-//   DECLARE_SPECIAL_CONSTANTS(T)
-
-// public:
-//   typedef T (*CeilFunc)(T);
-
-//   void testSpecialNumbers(CeilFunc func) {
-//     EXPECT_FP_EQ(zero, func(zero));
-//     EXPECT_FP_EQ(neg_zero, func(neg_zero));
-
-//     EXPECT_FP_EQ(inf, func(inf));
-//     EXPECT_FP_EQ(neg_inf, func(neg_inf));
-
-//     EXPECT_FP_EQ(aNaN, func(aNaN));
-//   }
-
-//   void testRoundedNumbers(CeilFunc func) {
-//     EXPECT_FP_EQ(T(1.0), func(T(1.0)));
-//     EXPECT_FP_EQ(T(-1.0), func(T(-1.0)));
-//     EXPECT_FP_EQ(T(10.0), func(T(10.0)));
-//     EXPECT_FP_EQ(T(-10.0), func(T(-10.0)));
-//     EXPECT_FP_EQ(T(1234.0), func(T(1234.0)));
-//     EXPECT_FP_EQ(T(-1234.0), func(T(-1234.0)));
-//   }
-
-//   void testFractions(CeilFunc func) {
-//     EXPECT_FP_EQ(T(1.0), func(T(0.5)));
-//     EXPECT_FP_EQ(T(-0.0), func(T(-0.5)));
-//     EXPECT_FP_EQ(T(1.0), func(T(0.115)));
-//     EXPECT_FP_EQ(T(-0.0), func(T(-0.115)));
-//     EXPECT_FP_EQ(T(1.0), func(T(0.715)));
-//     EXPECT_FP_EQ(T(-0.0), func(T(-0.715)));
-//     EXPECT_FP_EQ(T(2.0), func(T(1.3)));
-//     EXPECT_FP_EQ(T(-1.0), func(T(-1.3)));
-//     EXPECT_FP_EQ(T(2.0), func(T(1.5)));
-//     EXPECT_FP_EQ(T(-1.0), func(T(-1.5)));
-//     EXPECT_FP_EQ(T(2.0), func(T(1.75)));
-//     EXPECT_FP_EQ(T(-1.0), func(T(-1.75)));
-//     EXPECT_FP_EQ(T(11.0), func(T(10.32)));
-//     EXPECT_FP_EQ(T(-10.0), func(T(-10.32)));
-//     EXPECT_FP_EQ(T(11.0), func(T(10.65)));
-//     EXPECT_FP_EQ(T(-10.0), func(T(-10.65)));
-//     EXPECT_FP_EQ(T(1235.0), func(T(1234.38)));
-//     EXPECT_FP_EQ(T(-1234.0), func(T(-1234.38)));
-//     EXPECT_FP_EQ(T(1235.0), func(T(1234.96)));
-//     EXPECT_FP_EQ(T(-1234.0), func(T(-1234.96)));
-//   }
-// };
-
-// #define LIST_CEIL_TESTS(T, func)                                               \
-//   using LlvmLibcCeilTest = CeilTest<T>;                                        \
-//   TEST_F(LlvmLibcCeilTest, SpecialNumbers) { testSpecialNumbers(&func); }      \
-//   TEST_F(LlvmLibcCeilTest, RoundedNubmers) { testRoundedNumbers(&func); }      \
-//   TEST_F(LlvmLibcCeilTest, Fractions) { testFractions(&func); }
-
-// #endif // LLVM_LIBC_TEST_SRC_MATH_SMOKE_CEILTEST_H

>From 73d828ee16c333deeff59a8f78d2065ae360d2fa Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Thu, 21 Mar 2024 13:40:22 +0530
Subject: [PATCH 08/24] Moved logic to BasicOperations.h

---
 libc/spec/stdc.td                           |  2 +-
 libc/src/__support/FPUtil/BasicOperations.h | 11 +++++++++++
 libc/src/math/generic/CMakeLists.txt        | 12 ++++--------
 libc/src/math/generic/canonicalize.cpp      | 16 ++++------------
 libc/src/math/generic/canonicalizef.cpp     | 15 ++++-----------
 libc/src/math/generic/canonicalizef128.cpp  | 15 ++++-----------
 libc/src/math/generic/canonicalizel.cpp     | 18 +++++-------------
 7 files changed, 33 insertions(+), 56 deletions(-)

diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index 87800784fc173c..4fd858b28ab7bb 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -573,7 +573,7 @@ def StdC : StandardSpec<"stdc"> {
 
           FunctionSpec<"canonicalize", RetValSpec<IntType>, [ArgSpec<DoubleType>, ArgSpec<DoubleType>]>,
           FunctionSpec<"canonicalizef", RetValSpec<IntType>, [ArgSpec<FloatType>, ArgSpec<FloatType>]>,
-          FunctionSpec<"canonicalizef128", RetValSpec<IntType>, [ArgSpec<Float128Type>, ArgSpec<Float128Type>]>,
+          GuardedFunctionSpec<"canonicalizef128", RetValSpec<IntType>, [ArgSpec<Float128Type>, ArgSpec<Float128Type>]>,
           FunctionSpec<"canonicalizel", RetValSpec<IntType>, [ArgSpec<LongDoubleType>, ArgSpec<LongDoubleType>]>,
       ]
   >;
diff --git a/libc/src/__support/FPUtil/BasicOperations.h b/libc/src/__support/FPUtil/BasicOperations.h
index a19d6d0bef08ff..d7399c1e5d182a 100644
--- a/libc/src/__support/FPUtil/BasicOperations.h
+++ b/libc/src/__support/FPUtil/BasicOperations.h
@@ -73,6 +73,17 @@ 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 T canonicalize(T *cx, const T *x) {
+  FPBits<T> sx(*x);
+  if (sx.is_signaling_nan()) {
+    *cx = FPBits<T>::quiet_nan();
+  } else {
+    *cx = *x;
+  }
+  return 0;
+}
+
 } // namespace fputil
 } // namespace LIBC_NAMESPACE
 
diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt
index 8ee93939575390..db19efa14f6661 100644
--- a/libc/src/math/generic/CMakeLists.txt
+++ b/libc/src/math/generic/CMakeLists.txt
@@ -7,8 +7,7 @@ add_entrypoint_object(
   COMPILE_OPTIONS
     -O3
   DEPENDS
-    libc.src.__support.FPUtil.fp_bits
-    libc.src.__support.FPUtil.fenv_impl
+    libc.src.__support.FPUtil.basic_operations
 )
 
 add_entrypoint_object(
@@ -20,8 +19,7 @@ add_entrypoint_object(
   COMPILE_OPTIONS
     -O3
   DEPENDS
-    libc.src.__support.FPUtil.fp_bits
-    libc.src.__support.FPUtil.fenv_impl
+    libc.src.__support.FPUtil.basic_operations
 )
 
 add_entrypoint_object(
@@ -33,8 +31,7 @@ add_entrypoint_object(
   COMPILE_OPTIONS
     -O3
   DEPENDS
-    libc.src.__support.FPUtil.fp_bits
-    libc.src.__support.FPUtil.fenv_impl
+    libc.src.__support.FPUtil.basic_operations
 )
 
 add_entrypoint_object(
@@ -46,8 +43,7 @@ add_entrypoint_object(
   COMPILE_OPTIONS
     -O3
   DEPENDS
-    libc.src.__support.FPUtil.fp_bits
-    libc.src.__support.FPUtil.fenv_impl
+    libc.src.__support.FPUtil.basic_operations
 )
 
 add_entrypoint_object(
diff --git a/libc/src/math/generic/canonicalize.cpp b/libc/src/math/generic/canonicalize.cpp
index 73452ced9302cd..2801ca83714480 100644
--- a/libc/src/math/generic/canonicalize.cpp
+++ b/libc/src/math/generic/canonicalize.cpp
@@ -1,27 +1,19 @@
-//===-- Implementation of canonicalize function
-//----------------------------------===//
+//===-- Implementation of canonicalize 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/canonicalize.h"
-#include "src/__support/FPUtil/FEnvImpl.h"
-#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/BasicOperations.h"
 #include "src/__support/common.h"
 
 namespace LIBC_NAMESPACE {
 
 LLVM_LIBC_FUNCTION(int, canonicalize, (double *cx, const double *x)) {
-  using FPB = fputil::FPBits<double>;
-  FPB sx(*x);
-  if (sx.is_signaling_nan())
-    *cx = quiet_nan();
-  else
-    *cx = *x;
-  return 0;
+    return fputil::canonicalize(&cx, &x);
 }
 
 } // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/canonicalizef.cpp b/libc/src/math/generic/canonicalizef.cpp
index d39e7228a6f68c..c6f4a0bff74333 100644
--- a/libc/src/math/generic/canonicalizef.cpp
+++ b/libc/src/math/generic/canonicalizef.cpp
@@ -1,26 +1,19 @@
-//===-- Implementation of canonicalizef function
-//----------------------------------===//
+//===-- Implementation of canonicalizef 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/canonicalizef.h"
-#include "src/__support/FPUtil/FEnvImpl.h"
-#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/BasicOperations.h"
 #include "src/__support/common.h"
 
 namespace LIBC_NAMESPACE {
 
 LLVM_LIBC_FUNCTION(int, canonicalizef, (float *cx, const float *x)) {
-  using FPB = fputil::FPBits<float>;
-  FPB sx(*x);
-  if (sx.is_signaling_nan())
-    *cx = quiet_nan();
-  *cx = *x;
-  return 0;
+    return fputil::canonicalize(&cx, &x);
 }
 
 } // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/canonicalizef128.cpp b/libc/src/math/generic/canonicalizef128.cpp
index 6b0ef80dd41b61..629b7d541f7899 100644
--- a/libc/src/math/generic/canonicalizef128.cpp
+++ b/libc/src/math/generic/canonicalizef128.cpp
@@ -1,26 +1,19 @@
-//===-- Implementation of canonicalizef128 function
-//----------------------------------===//
+//===-- Implementation of canonicalizef128 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/canonicalizef128.h"
-#include "src/__support/FPUtil/FEnvImpl.h"
-#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/BasicOperations.h"
 #include "src/__support/common.h"
 
 namespace LIBC_NAMESPACE {
 
 LLVM_LIBC_FUNCTION(int, canonicalizef128, (float128 * cx, const float128 *x)) {
-  using FPB = fputil::FPBits<float128>;
-  FPB sx(*x);
-  if (sx.is_signaling_nan())
-    *cx = quiet_nan();
-  *cx = *x;
-  return 0;
+    return fputil::canonicalize(&cx, &x);
 }
 
 } // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/canonicalizel.cpp b/libc/src/math/generic/canonicalizel.cpp
index fe03ed6677c5b4..63d4bb9559c7e6 100644
--- a/libc/src/math/generic/canonicalizel.cpp
+++ b/libc/src/math/generic/canonicalizel.cpp
@@ -1,27 +1,19 @@
-//===-- Implementation of canonicalizel function
-//----------------------------------===//
+//===-- Implementation of canonicalizel 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/canonicalizel.h"
-#include "src/__support/FPUtil/FEnvImpl.h"
-#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/BasicOperations.h"
 #include "src/__support/common.h"
 
 namespace LIBC_NAMESPACE {
 
-LLVM_LIBC_FUNCTION(int, canonicalizel,
-                   (long double *cx, const long double *x)) {
-  using FPB = fputil::FPBits<long double>;
-  FPB sx(*x);
-  if (sx.is_signaling_nan())
-    *cx = quiet_nan();
-  *cx = *x;
-  return 0;
+LLVM_LIBC_FUNCTION(int, canonicalizel,(long double *cx, const long double *x)) {
+    return fputil::canonicalize(&cx, &x);
 }
 
 } // namespace LIBC_NAMESPACE

>From 22d821dee97720cd4bf4632412afabe84c962bca Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Thu, 21 Mar 2024 13:41:14 +0530
Subject: [PATCH 09/24] formatter

---
 libc/src/math/generic/canonicalize.cpp     | 2 +-
 libc/src/math/generic/canonicalizef.cpp    | 2 +-
 libc/src/math/generic/canonicalizef128.cpp | 2 +-
 libc/src/math/generic/canonicalizel.cpp    | 5 +++--
 4 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/libc/src/math/generic/canonicalize.cpp b/libc/src/math/generic/canonicalize.cpp
index 2801ca83714480..9e278e21609515 100644
--- a/libc/src/math/generic/canonicalize.cpp
+++ b/libc/src/math/generic/canonicalize.cpp
@@ -13,7 +13,7 @@
 namespace LIBC_NAMESPACE {
 
 LLVM_LIBC_FUNCTION(int, canonicalize, (double *cx, const double *x)) {
-    return fputil::canonicalize(&cx, &x);
+  return fputil::canonicalize(&cx, &x);
 }
 
 } // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/canonicalizef.cpp b/libc/src/math/generic/canonicalizef.cpp
index c6f4a0bff74333..9219d732bbdfe6 100644
--- a/libc/src/math/generic/canonicalizef.cpp
+++ b/libc/src/math/generic/canonicalizef.cpp
@@ -13,7 +13,7 @@
 namespace LIBC_NAMESPACE {
 
 LLVM_LIBC_FUNCTION(int, canonicalizef, (float *cx, const float *x)) {
-    return fputil::canonicalize(&cx, &x);
+  return fputil::canonicalize(&cx, &x);
 }
 
 } // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/canonicalizef128.cpp b/libc/src/math/generic/canonicalizef128.cpp
index 629b7d541f7899..79a9cbbe74d8cc 100644
--- a/libc/src/math/generic/canonicalizef128.cpp
+++ b/libc/src/math/generic/canonicalizef128.cpp
@@ -13,7 +13,7 @@
 namespace LIBC_NAMESPACE {
 
 LLVM_LIBC_FUNCTION(int, canonicalizef128, (float128 * cx, const float128 *x)) {
-    return fputil::canonicalize(&cx, &x);
+  return fputil::canonicalize(&cx, &x);
 }
 
 } // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/canonicalizel.cpp b/libc/src/math/generic/canonicalizel.cpp
index 63d4bb9559c7e6..389df98cc5b3a1 100644
--- a/libc/src/math/generic/canonicalizel.cpp
+++ b/libc/src/math/generic/canonicalizel.cpp
@@ -12,8 +12,9 @@
 
 namespace LIBC_NAMESPACE {
 
-LLVM_LIBC_FUNCTION(int, canonicalizel,(long double *cx, const long double *x)) {
-    return fputil::canonicalize(&cx, &x);
+LLVM_LIBC_FUNCTION(int, canonicalizel,
+                   (long double *cx, const long double *x)) {
+  return fputil::canonicalize(&cx, &x);
 }
 
 } // namespace LIBC_NAMESPACE

>From d940736f9b54c1e1047f1676c85f2f6502d3a6e3 Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Thu, 21 Mar 2024 13:43:04 +0530
Subject: [PATCH 10/24] Updated EntryPoints.txt

---
 libc/config/linux/x86_64/entrypoints.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 8d1ef82d50122d..0a91f12f3cf8f6 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -344,7 +344,6 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.atanhf
     libc.src.math.canonicalize
     libc.src.math.canonicalizef
-    libc.src.math.canonicalizef128
     libc.src.math.canonicalizel
     libc.src.math.copysign
     libc.src.math.copysignf
@@ -476,6 +475,7 @@ set(TARGET_LIBM_ENTRYPOINTS
 if(LIBC_TYPES_HAS_FLOAT128)
   list(APPEND TARGET_LIBM_ENTRYPOINTS
     # math.h C23 _Float128 entrypoints
+    libc.src.math.canonicalizef128
     libc.src.math.ceilf128
     libc.src.math.copysignf128
     libc.src.math.fabsf128

>From 5d1fba7496647593ec92f833a5599266e77ddeb3 Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Thu, 21 Mar 2024 14:02:09 +0530
Subject: [PATCH 11/24] Format header

---
 libc/src/math/canonicalize.h     | 5 ++---
 libc/src/math/canonicalizef.h    | 5 ++---
 libc/src/math/canonicalizef128.h | 5 ++---
 libc/src/math/canonicalizel.h    | 5 ++---
 4 files changed, 8 insertions(+), 12 deletions(-)

diff --git a/libc/src/math/canonicalize.h b/libc/src/math/canonicalize.h
index 9c682d85e7b73d..b7b5959fb667cf 100644
--- a/libc/src/math/canonicalize.h
+++ b/libc/src/math/canonicalize.h
@@ -1,11 +1,10 @@
-//===-- Implementation header for canonicalize ------------------------*- C++
-//-*-===//
+//===-- Implementation header for canonicalize -------------------*- 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_CANONICALIZE_H
 #define LLVM_LIBC_SRC_MATH_CANONICALIZE_H
diff --git a/libc/src/math/canonicalizef.h b/libc/src/math/canonicalizef.h
index d7f0c41024721a..556607f1334967 100644
--- a/libc/src/math/canonicalizef.h
+++ b/libc/src/math/canonicalizef.h
@@ -1,11 +1,10 @@
-//===-- Implementation header for canonicalizef ------------------------*- C++
-//-*-===//
+//===-- Implementation header for canonicalizef ------------------*- 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_CANONICALIZEF_H
 #define LLVM_LIBC_SRC_MATH_CANONICALIZEF_H
diff --git a/libc/src/math/canonicalizef128.h b/libc/src/math/canonicalizef128.h
index 315cee10cb99da..6db80094753767 100644
--- a/libc/src/math/canonicalizef128.h
+++ b/libc/src/math/canonicalizef128.h
@@ -1,11 +1,10 @@
-//===-- Implementation header for canonicalizef128 ------------------------*-
-// C++ -*-===//
+//===-- Implementation header for canonicalizef128 ---------------*-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_CANONICALIZEF128_H
 #define LLVM_LIBC_SRC_MATH_CANONICALIZEF128_H
diff --git a/libc/src/math/canonicalizel.h b/libc/src/math/canonicalizel.h
index febc852514f7a0..1cab29e8e8b1c9 100644
--- a/libc/src/math/canonicalizel.h
+++ b/libc/src/math/canonicalizel.h
@@ -1,11 +1,10 @@
-//===-- Implementation header for canonicalizel ------------------------*- C++
-//-*-===//
+//===-- Implementation header for canonicalizel ------------------*- 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_CANONICALIZEL_H
 #define LLVM_LIBC_SRC_MATH_CANONICALIZEL_H

>From 402eb1587ebb31f3ae80544248c7f9b86dd1af63 Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Thu, 21 Mar 2024 20:01:09 +0530
Subject: [PATCH 12/24] Added guard

---
 libc/spec/stdc.td                           | 2 +-
 libc/src/__support/FPUtil/BasicOperations.h | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index 4fd858b28ab7bb..32c787ade6b101 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -573,8 +573,8 @@ def StdC : StandardSpec<"stdc"> {
 
           FunctionSpec<"canonicalize", RetValSpec<IntType>, [ArgSpec<DoubleType>, ArgSpec<DoubleType>]>,
           FunctionSpec<"canonicalizef", RetValSpec<IntType>, [ArgSpec<FloatType>, ArgSpec<FloatType>]>,
-          GuardedFunctionSpec<"canonicalizef128", RetValSpec<IntType>, [ArgSpec<Float128Type>, ArgSpec<Float128Type>]>,
           FunctionSpec<"canonicalizel", RetValSpec<IntType>, [ArgSpec<LongDoubleType>, ArgSpec<LongDoubleType>]>,
+          GuardedFunctionSpec<"canonicalizef128", RetValSpec<IntType>, [ArgSpec<Float128Type>, ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT128">,
       ]
   >;
 
diff --git a/libc/src/__support/FPUtil/BasicOperations.h b/libc/src/__support/FPUtil/BasicOperations.h
index d7399c1e5d182a..f0f551c2ed7b47 100644
--- a/libc/src/__support/FPUtil/BasicOperations.h
+++ b/libc/src/__support/FPUtil/BasicOperations.h
@@ -75,6 +75,7 @@ LIBC_INLINE T fdim(T x, T y) {
 
 template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
 LIBC_INLINE T canonicalize(T *cx, const T *x) {
+  if constexpr (get_fp_type<T>() == FPType::X86_Binary80) {}
   FPBits<T> sx(*x);
   if (sx.is_signaling_nan()) {
     *cx = FPBits<T>::quiet_nan();

>From 8a54183c85d0ff2e578a7cf0eba4b81423f33b27 Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Thu, 21 Mar 2024 20:04:35 +0530
Subject: [PATCH 13/24] Formatter

---
 libc/src/__support/FPUtil/BasicOperations.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libc/src/__support/FPUtil/BasicOperations.h b/libc/src/__support/FPUtil/BasicOperations.h
index f0f551c2ed7b47..3a3dcc6b7518c0 100644
--- a/libc/src/__support/FPUtil/BasicOperations.h
+++ b/libc/src/__support/FPUtil/BasicOperations.h
@@ -75,7 +75,8 @@ LIBC_INLINE T fdim(T x, T y) {
 
 template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
 LIBC_INLINE T canonicalize(T *cx, const T *x) {
-  if constexpr (get_fp_type<T>() == FPType::X86_Binary80) {}
+  if constexpr (get_fp_type<T>() == FPType::X86_Binary80) {
+  }
   FPBits<T> sx(*x);
   if (sx.is_signaling_nan()) {
     *cx = FPBits<T>::quiet_nan();

>From 5559dfa28eaaa43ea6364a443ca22c49784b6d66 Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Thu, 21 Mar 2024 20:21:36 +0530
Subject: [PATCH 14/24] Error handling

---
 libc/src/__support/FPUtil/BasicOperations.h | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/libc/src/__support/FPUtil/BasicOperations.h b/libc/src/__support/FPUtil/BasicOperations.h
index 3a3dcc6b7518c0..505be652794ba0 100644
--- a/libc/src/__support/FPUtil/BasicOperations.h
+++ b/libc/src/__support/FPUtil/BasicOperations.h
@@ -13,6 +13,8 @@
 
 #include "src/__support/CPP/type_traits.h"
 #include "src/__support/common.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+
 
 namespace LIBC_NAMESPACE {
 namespace fputil {
@@ -79,7 +81,9 @@ LIBC_INLINE T canonicalize(T *cx, const T *x) {
   }
   FPBits<T> sx(*x);
   if (sx.is_signaling_nan()) {
-    *cx = FPBits<T>::quiet_nan();
+    T temp = FPBits<T>::quiet_nan().get_val();
+    *cx = &temp;
+    raise_except_if_required(FE_INVALID);
   } else {
     *cx = *x;
   }

>From 6ea153c3fc58df1a7f47272155faf8a2dfc92f7c Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Thu, 21 Mar 2024 20:22:01 +0530
Subject: [PATCH 15/24] Formatter

---
 libc/src/__support/FPUtil/BasicOperations.h | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/libc/src/__support/FPUtil/BasicOperations.h b/libc/src/__support/FPUtil/BasicOperations.h
index 505be652794ba0..e828e260c95758 100644
--- a/libc/src/__support/FPUtil/BasicOperations.h
+++ b/libc/src/__support/FPUtil/BasicOperations.h
@@ -12,9 +12,8 @@
 #include "FPBits.h"
 
 #include "src/__support/CPP/type_traits.h"
-#include "src/__support/common.h"
 #include "src/__support/FPUtil/FEnvImpl.h"
-
+#include "src/__support/common.h"
 
 namespace LIBC_NAMESPACE {
 namespace fputil {

>From 8d63202a0cb799749fdb3cae30c172f66e36e3fa Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Thu, 21 Mar 2024 20:34:14 +0530
Subject: [PATCH 16/24] Corrected Error handling

---
 libc/src/__support/FPUtil/BasicOperations.h | 5 ++---
 libc/src/__support/FPUtil/CMakeLists.txt    | 1 +
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/libc/src/__support/FPUtil/BasicOperations.h b/libc/src/__support/FPUtil/BasicOperations.h
index e828e260c95758..42bd447cfc36d9 100644
--- a/libc/src/__support/FPUtil/BasicOperations.h
+++ b/libc/src/__support/FPUtil/BasicOperations.h
@@ -9,10 +9,10 @@
 #ifndef LLVM_LIBC_SRC___SUPPORT_FPUTIL_BASICOPERATIONS_H
 #define LLVM_LIBC_SRC___SUPPORT_FPUTIL_BASICOPERATIONS_H
 
+#include "FEnvImpl.h"
 #include "FPBits.h"
 
 #include "src/__support/CPP/type_traits.h"
-#include "src/__support/FPUtil/FEnvImpl.h"
 #include "src/__support/common.h"
 
 namespace LIBC_NAMESPACE {
@@ -80,8 +80,7 @@ LIBC_INLINE T canonicalize(T *cx, const T *x) {
   }
   FPBits<T> sx(*x);
   if (sx.is_signaling_nan()) {
-    T temp = FPBits<T>::quiet_nan().get_val();
-    *cx = &temp;
+    *cx = FPBits<T>::quiet_nan(sx.sign(), sx.get_explicit_mantissa());
     raise_except_if_required(FE_INVALID);
   } else {
     *cx = *x;
diff --git a/libc/src/__support/FPUtil/CMakeLists.txt b/libc/src/__support/FPUtil/CMakeLists.txt
index f1c6fba22856dd..5e59096057cd3c 100644
--- a/libc/src/__support/FPUtil/CMakeLists.txt
+++ b/libc/src/__support/FPUtil/CMakeLists.txt
@@ -81,6 +81,7 @@ add_header_library(
     BasicOperations.h
   DEPENDS
     .fp_bits
+    .fenv_impl
     libc.src.__support.CPP.type_traits
     libc.src.__support.common
 )

>From c90fe8171f14c75af0da6afe14b6f04254748ca0 Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Thu, 21 Mar 2024 20:40:22 +0530
Subject: [PATCH 17/24] Added LIBC_UNLIKELY

---
 libc/src/__support/FPUtil/BasicOperations.h | 3 ++-
 libc/src/__support/FPUtil/CMakeLists.txt    | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/libc/src/__support/FPUtil/BasicOperations.h b/libc/src/__support/FPUtil/BasicOperations.h
index 42bd447cfc36d9..d09dfad567c174 100644
--- a/libc/src/__support/FPUtil/BasicOperations.h
+++ b/libc/src/__support/FPUtil/BasicOperations.h
@@ -14,6 +14,7 @@
 
 #include "src/__support/CPP/type_traits.h"
 #include "src/__support/common.h"
+#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
 
 namespace LIBC_NAMESPACE {
 namespace fputil {
@@ -79,7 +80,7 @@ LIBC_INLINE T canonicalize(T *cx, const T *x) {
   if constexpr (get_fp_type<T>() == FPType::X86_Binary80) {
   }
   FPBits<T> sx(*x);
-  if (sx.is_signaling_nan()) {
+  if (LIBC_UNLIKELY(sx.is_signaling_nan())) {
     *cx = FPBits<T>::quiet_nan(sx.sign(), sx.get_explicit_mantissa());
     raise_except_if_required(FE_INVALID);
   } else {
diff --git a/libc/src/__support/FPUtil/CMakeLists.txt b/libc/src/__support/FPUtil/CMakeLists.txt
index 5e59096057cd3c..eb646c8d00dc22 100644
--- a/libc/src/__support/FPUtil/CMakeLists.txt
+++ b/libc/src/__support/FPUtil/CMakeLists.txt
@@ -84,6 +84,7 @@ add_header_library(
     .fenv_impl
     libc.src.__support.CPP.type_traits
     libc.src.__support.common
+    libc.src.__support.macros.optimization.h
 )
 
 add_header_library(

>From cf472ff0eb3e2553d84cef7f5af735f9febe3288 Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Thu, 21 Mar 2024 23:05:29 +0530
Subject: [PATCH 18/24] Changed references

---
 libc/src/__support/FPUtil/BasicOperations.h | 8 ++++----
 libc/src/math/generic/canonicalize.cpp      | 2 +-
 libc/src/math/generic/canonicalizef.cpp     | 2 +-
 libc/src/math/generic/canonicalizef128.cpp  | 2 +-
 libc/src/math/generic/canonicalizel.cpp     | 2 +-
 5 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/libc/src/__support/FPUtil/BasicOperations.h b/libc/src/__support/FPUtil/BasicOperations.h
index d09dfad567c174..53e7ebba64a005 100644
--- a/libc/src/__support/FPUtil/BasicOperations.h
+++ b/libc/src/__support/FPUtil/BasicOperations.h
@@ -76,15 +76,15 @@ LIBC_INLINE T fdim(T x, T y) {
 }
 
 template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
-LIBC_INLINE T canonicalize(T *cx, const T *x) {
+LIBC_INLINE T canonicalize(T &cx, const T &x) {
   if constexpr (get_fp_type<T>() == FPType::X86_Binary80) {
   }
-  FPBits<T> sx(*x);
+  FPBits<T> sx(x);
   if (LIBC_UNLIKELY(sx.is_signaling_nan())) {
-    *cx = FPBits<T>::quiet_nan(sx.sign(), sx.get_explicit_mantissa());
+    cx = FPBits<T>::quiet_nan(sx.sign(), sx.get_explicit_mantissa());
     raise_except_if_required(FE_INVALID);
   } else {
-    *cx = *x;
+    cx = x;
   }
   return 0;
 }
diff --git a/libc/src/math/generic/canonicalize.cpp b/libc/src/math/generic/canonicalize.cpp
index 9e278e21609515..f38ca01e157f88 100644
--- a/libc/src/math/generic/canonicalize.cpp
+++ b/libc/src/math/generic/canonicalize.cpp
@@ -13,7 +13,7 @@
 namespace LIBC_NAMESPACE {
 
 LLVM_LIBC_FUNCTION(int, canonicalize, (double *cx, const double *x)) {
-  return fputil::canonicalize(&cx, &x);
+  return fputil::canonicalize(*cx, *x);
 }
 
 } // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/canonicalizef.cpp b/libc/src/math/generic/canonicalizef.cpp
index 9219d732bbdfe6..dce601de149140 100644
--- a/libc/src/math/generic/canonicalizef.cpp
+++ b/libc/src/math/generic/canonicalizef.cpp
@@ -13,7 +13,7 @@
 namespace LIBC_NAMESPACE {
 
 LLVM_LIBC_FUNCTION(int, canonicalizef, (float *cx, const float *x)) {
-  return fputil::canonicalize(&cx, &x);
+  return fputil::canonicalize(*cx, *x);
 }
 
 } // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/canonicalizef128.cpp b/libc/src/math/generic/canonicalizef128.cpp
index 79a9cbbe74d8cc..0078b478238cb7 100644
--- a/libc/src/math/generic/canonicalizef128.cpp
+++ b/libc/src/math/generic/canonicalizef128.cpp
@@ -13,7 +13,7 @@
 namespace LIBC_NAMESPACE {
 
 LLVM_LIBC_FUNCTION(int, canonicalizef128, (float128 * cx, const float128 *x)) {
-  return fputil::canonicalize(&cx, &x);
+  return fputil::canonicalize(*cx, *x);
 }
 
 } // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/generic/canonicalizel.cpp b/libc/src/math/generic/canonicalizel.cpp
index 389df98cc5b3a1..5310a316acdd3f 100644
--- a/libc/src/math/generic/canonicalizel.cpp
+++ b/libc/src/math/generic/canonicalizel.cpp
@@ -14,7 +14,7 @@ namespace LIBC_NAMESPACE {
 
 LLVM_LIBC_FUNCTION(int, canonicalizel,
                    (long double *cx, const long double *x)) {
-  return fputil::canonicalize(&cx, &x);
+  return fputil::canonicalize(*cx, *x);
 }
 
 } // namespace LIBC_NAMESPACE

>From 977313147de290a4ba53a4f7160a68d34580e219 Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Thu, 21 Mar 2024 23:43:30 +0530
Subject: [PATCH 19/24] Added Canonical X86_80

---
 libc/src/__support/FPUtil/BasicOperations.h | 39 +++++++++++++++++++--
 1 file changed, 36 insertions(+), 3 deletions(-)

diff --git a/libc/src/__support/FPUtil/BasicOperations.h b/libc/src/__support/FPUtil/BasicOperations.h
index 53e7ebba64a005..760958acaac636 100644
--- a/libc/src/__support/FPUtil/BasicOperations.h
+++ b/libc/src/__support/FPUtil/BasicOperations.h
@@ -77,12 +77,45 @@ LIBC_INLINE T fdim(T x, T y) {
 
 template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
 LIBC_INLINE T canonicalize(T &cx, const T &x) {
-  if constexpr (get_fp_type<T>() == FPType::X86_Binary80) {
-  }
   FPBits<T> sx(x);
   if (LIBC_UNLIKELY(sx.is_signaling_nan())) {
-    cx = FPBits<T>::quiet_nan(sx.sign(), sx.get_explicit_mantissa());
+    cx = FPBits<T>::quiet_nan(sx.sign(), sx.get_explicit_mantissa()).get_val();
     raise_except_if_required(FE_INVALID);
+  } else if constexpr (get_fp_type<T>() == FPType::X86_Binary80) {
+    // All the pseudo and unnormal numbers are not canonical.
+    // More precisely :
+    // Exponent   |       Significand      | Meaning
+    //            | Bits 63-62 | Bits 61-0 |
+    // All Ones   |     00     |    Zero   | Pseudo Infinity, Value = Infinty
+    // All Ones   |     00     |  Non-Zero | Pseudo NaN, Value = SNaN
+    // All Ones   |     01     | Anything  | Pseudo NaN, Value = SNaN
+    //            |   Bit 63   | Bits 62-0 |
+    // All zeroes |   One      | Anything  | Pseudo Denormal, Value =
+    //            |            |           | (−1)**s × m × 2**−16382
+    // All Other  |   Zero     | Anything  | Unnormal, Value =
+    //  Values    |            |           | (−1)**s × m × 2**−16382
+    bool bit63 = sx.get_implicit_bit();
+    FPBits<T>::StorageType mantissa = sx.get_explicit_mantissa();
+    bool bit62 = mantissa & (1ULL << 62);
+    bool bit61 = mantissa & (1ULL << 61);
+    int exponent = sx.get_biased_exponent();
+    if (exponent == 0x7FFF) {
+      if (!bit63 && !bit62) {
+        if (!bit61) {
+          cx = FPBits<T>::inf().get_val();
+        } else {
+          cx = FPBits<T>::signaling_nan().get_val();
+        }
+      } else if (!bit63 && bit62) {
+        cx = FPBits<T>::signaling_nan().get_val();
+      }
+    } else if (exponent == 0 && bit63) {
+      cx = FPBits<T>::encode(sx.sign(), Exponent::min(), mantissa).get_val();
+    } else if (!bit63) {
+      cx = FPBits<T>::encode(sx.sign(), Exponent::min(), mantissa).get_val();
+    } else {
+      cx = x;
+    }
   } else {
     cx = x;
   }

>From 7b02aeff9e5295bfa72555cf112e5b6baf81daf6 Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Fri, 22 Mar 2024 01:30:37 +0530
Subject: [PATCH 20/24] Added tests

---
 libc/test/src/math/smoke/CMakeLists.txt       | 60 +++++++++++++++++++
 libc/test/src/math/smoke/CanonicalizeTest.h   | 54 +++++++++++++++++
 libc/test/src/math/smoke/canonicalizeTest.h   |  0
 .../test/src/math/smoke/canonicalize_test.cpp | 13 ++++
 .../src/math/smoke/canonicalizef128_test.cpp  | 13 ++++
 .../src/math/smoke/canonicalizef_test.cpp     | 13 ++++
 .../src/math/smoke/canonicalizel_test.cpp     | 13 ++++
 7 files changed, 166 insertions(+)
 create mode 100644 libc/test/src/math/smoke/CanonicalizeTest.h
 delete mode 100644 libc/test/src/math/smoke/canonicalizeTest.h
 create mode 100644 libc/test/src/math/smoke/canonicalize_test.cpp
 create mode 100644 libc/test/src/math/smoke/canonicalizef128_test.cpp
 create mode 100644 libc/test/src/math/smoke/canonicalizef_test.cpp
 create mode 100644 libc/test/src/math/smoke/canonicalizel_test.cpp

diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt
index 85dacce3b21dca..65d3477639b4c1 100644
--- a/libc/test/src/math/smoke/CMakeLists.txt
+++ b/libc/test/src/math/smoke/CMakeLists.txt
@@ -165,6 +165,66 @@ add_fp_unittest(
     libc.src.__support.FPUtil.fp_bits
 )
 
+add_fp_unittest(
+  canonicalize_test
+  SUITE
+    libc-math-smoke-tests
+  SRCS
+    canonicalize_test.cpp
+  HDRS
+    CanonicalizeTest.h
+  DEPENDS
+    libc.include.math
+    libc.src.math.canonicalize
+    libc.src.__support.FPUtil.fp_bits
+    libc.src.__support.FPUtil.fenv_impl
+)
+
+add_fp_unittest(
+  canonicalizef_test
+  SUITE
+    libc-math-smoke-tests
+  SRCS
+    canonicalizef_test.cpp
+  HDRS
+    CanonicalizeTest.h
+  DEPENDS
+    libc.include.math
+    libc.src.math.canonicalizef
+    libc.src.__support.FPUtil.fp_bits
+    libc.src.__support.FPUtil.fenv_impl
+)
+
+add_fp_unittest(
+  canonicalizef128_test
+  SUITE
+    libc-math-smoke-tests
+  SRCS
+    canonicalizef128_test.cpp
+  HDRS
+    CanonicalizeTest.h
+  DEPENDS
+    libc.include.math
+    libc.src.math.canonicalizef128
+    libc.src.__support.FPUtil.fp_bits
+    libc.src.__support.FPUtil.fenv_impl
+)
+
+add_fp_unittest(
+  canonicalizel_test
+  SUITE
+    libc-math-smoke-tests
+  SRCS
+    canonicalizel_test.cpp
+  HDRS
+    CanonicalizeTest.h
+  DEPENDS
+    libc.include.math
+    libc.src.math.canonicalizel
+    libc.src.__support.FPUtil.fp_bits
+    libc.src.__support.FPUtil.fenv_impl
+)
+
 add_fp_unittest(
   ceil_test
   SUITE
diff --git a/libc/test/src/math/smoke/CanonicalizeTest.h b/libc/test/src/math/smoke/CanonicalizeTest.h
new file mode 100644
index 00000000000000..2fa097626d1824
--- /dev/null
+++ b/libc/test/src/math/smoke/CanonicalizeTest.h
@@ -0,0 +1,54 @@
+//===-- Utility class to test canonicalize[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_CANONICALIZETEST_H
+#define LLVM_LIBC_TEST_SRC_MATH_SMOKE_CANONICALIZETEST_H
+
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+#include <math.h>
+
+template <typename T>
+class CanonicalizeTest : public LIBC_NAMESPACE::testing::Test {
+
+  DECLARE_SPECIAL_CONSTANTS(T)
+
+public:
+  typedef T (*CanonicalizeFunc)(T);
+
+  void testSpecialNumbers(CanonicalizeFunc func) {
+    EXPECT_FP_EQ(zero, func(zero));
+    EXPECT_FP_EQ(neg_zero, func(neg_zero));
+
+    EXPECT_FP_EQ(inf, func(inf));
+    EXPECT_FP_EQ(neg_inf, func(neg_inf));
+
+    EXPECT_FP_EQ(aNaN, func(aNaN));
+  }
+
+  void testRoundedNumbers(CanonicalizeFunc func) {
+    EXPECT_FP_EQ(T(1.0), func(T(1.0)));
+    EXPECT_FP_EQ(T(-1.0), func(T(-1.0)));
+    EXPECT_FP_EQ(T(10.0), func(T(10.0)));
+    EXPECT_FP_EQ(T(-10.0), func(T(-10.0)));
+    EXPECT_FP_EQ(T(1234.0), func(T(1234.0)));
+    EXPECT_FP_EQ(T(-1234.0), func(T(-1234.0)));
+  }
+};
+
+#define LIST_CANONICALIZE_TESTS(T, func)                                       \
+  using LlvmLibcCanonicalizeTest = CanonicalizeTest<T>;                        \
+  TEST_F(LlvmLibcCanonicalizeTest, SpecialNumbers) {                           \
+    testSpecialNumbers(&func);                                                 \
+  }                                                                            \
+  TEST_F(LlvmLibcCanonicalizeTest, RoundedNubmers) {                           \
+    testRoundedNumbers(&func);                                                 \
+  }
+
+#endif // LLVM_LIBC_TEST_SRC_MATH_SMOKE_CANONICALIZETEST_H
diff --git a/libc/test/src/math/smoke/canonicalizeTest.h b/libc/test/src/math/smoke/canonicalizeTest.h
deleted file mode 100644
index e69de29bb2d1d6..00000000000000
diff --git a/libc/test/src/math/smoke/canonicalize_test.cpp b/libc/test/src/math/smoke/canonicalize_test.cpp
new file mode 100644
index 00000000000000..54a1ddd49ca4ba
--- /dev/null
+++ b/libc/test/src/math/smoke/canonicalize_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for canonicalize ----------------------------------------===//
+//
+// 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 "CanonicalizeTest.h"
+
+#include "src/math/canonicalize.h"
+
+LIST_CANONICALIZE_TESTS(double, LIBC_NAMESPACE::canonicalize)
diff --git a/libc/test/src/math/smoke/canonicalizef128_test.cpp b/libc/test/src/math/smoke/canonicalizef128_test.cpp
new file mode 100644
index 00000000000000..242e2331a29eac
--- /dev/null
+++ b/libc/test/src/math/smoke/canonicalizef128_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for canonicalizef128 ------------------------------------===//
+//
+// 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 "CanonicalizeTest.h"
+
+#include "src/math/canonicalizef128.h"
+
+LIST_CANONICALIZE_TESTS(float128, LIBC_NAMESPACE::canonicalizef128)
diff --git a/libc/test/src/math/smoke/canonicalizef_test.cpp b/libc/test/src/math/smoke/canonicalizef_test.cpp
new file mode 100644
index 00000000000000..17cf3c3639a4aa
--- /dev/null
+++ b/libc/test/src/math/smoke/canonicalizef_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for canonicalizef ---------------------------------------===//
+//
+// 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 "CanonicalizeTest.h"
+
+#include "src/math/canonicalizef.h"
+
+LIST_CANONICALIZE_TESTS(float, LIBC_NAMESPACE::canonicalizef)
diff --git a/libc/test/src/math/smoke/canonicalizel_test.cpp b/libc/test/src/math/smoke/canonicalizel_test.cpp
new file mode 100644
index 00000000000000..a085948a56f047
--- /dev/null
+++ b/libc/test/src/math/smoke/canonicalizel_test.cpp
@@ -0,0 +1,13 @@
+//===-- Unittests for canonicalizel ---------------------------------------===//
+//
+// 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 "CanonicalizeTest.h"
+
+#include "src/math/canonicalizel.h"
+
+LIST_CANONICALIZE_TESTS(long double, LIBC_NAMESPACE::canonicalizel)

>From 6e19b200a6a2f76866fbea0a25588d0724a63827 Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Fri, 22 Mar 2024 02:23:46 +0530
Subject: [PATCH 21/24] Bug fixes

---
 libc/src/__support/FPUtil/BasicOperations.h | 10 ++++++----
 libc/src/__support/FPUtil/CMakeLists.txt    |  1 +
 libc/src/__support/FPUtil/FPBits.h          |  4 ++++
 3 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/libc/src/__support/FPUtil/BasicOperations.h b/libc/src/__support/FPUtil/BasicOperations.h
index 760958acaac636..42511cda3c4f59 100644
--- a/libc/src/__support/FPUtil/BasicOperations.h
+++ b/libc/src/__support/FPUtil/BasicOperations.h
@@ -13,6 +13,7 @@
 #include "FPBits.h"
 
 #include "src/__support/CPP/type_traits.h"
+#include "src/__support/UInt128.h"
 #include "src/__support/common.h"
 #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
 
@@ -76,11 +77,12 @@ LIBC_INLINE T fdim(T x, T y) {
 }
 
 template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
-LIBC_INLINE T canonicalize(T &cx, const T &x) {
+LIBC_INLINE int canonicalize(T &cx, const T &x) {
   FPBits<T> sx(x);
   if (LIBC_UNLIKELY(sx.is_signaling_nan())) {
     cx = FPBits<T>::quiet_nan(sx.sign(), sx.get_explicit_mantissa()).get_val();
     raise_except_if_required(FE_INVALID);
+    return 1;
   } else if constexpr (get_fp_type<T>() == FPType::X86_Binary80) {
     // All the pseudo and unnormal numbers are not canonical.
     // More precisely :
@@ -95,7 +97,7 @@ LIBC_INLINE T canonicalize(T &cx, const T &x) {
     // All Other  |   Zero     | Anything  | Unnormal, Value =
     //  Values    |            |           | (−1)**s × m × 2**−16382
     bool bit63 = sx.get_implicit_bit();
-    FPBits<T>::StorageType mantissa = sx.get_explicit_mantissa();
+    UInt128 mantissa = sx.get_explicit_mantissa();
     bool bit62 = mantissa & (1ULL << 62);
     bool bit61 = mantissa & (1ULL << 61);
     int exponent = sx.get_biased_exponent();
@@ -110,9 +112,9 @@ LIBC_INLINE T canonicalize(T &cx, const T &x) {
         cx = FPBits<T>::signaling_nan().get_val();
       }
     } else if (exponent == 0 && bit63) {
-      cx = FPBits<T>::encode(sx.sign(), Exponent::min(), mantissa).get_val();
+      cx = FPBits<T>::get_canonical_val(sx.sign(), mantissa).get_val();
     } else if (!bit63) {
-      cx = FPBits<T>::encode(sx.sign(), Exponent::min(), mantissa).get_val();
+      cx = FPBits<T>::get_canonical_val(sx.sign(), mantissa).get_val();
     } else {
       cx = x;
     }
diff --git a/libc/src/__support/FPUtil/CMakeLists.txt b/libc/src/__support/FPUtil/CMakeLists.txt
index eb646c8d00dc22..4e5ec022f36fc1 100644
--- a/libc/src/__support/FPUtil/CMakeLists.txt
+++ b/libc/src/__support/FPUtil/CMakeLists.txt
@@ -83,6 +83,7 @@ add_header_library(
     .fp_bits
     .fenv_impl
     libc.src.__support.CPP.type_traits
+    libc.src.__support.uint128
     libc.src.__support.common
     libc.src.__support.macros.optimization.h
 )
diff --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h
index b06b3f7b73959a..2e737eb8115247 100644
--- a/libc/src/__support/FPUtil/FPBits.h
+++ b/libc/src/__support/FPUtil/FPBits.h
@@ -526,6 +526,10 @@ struct FPRepSem<FPType::X86_Binary80, RetT>
                        Significand::msb() | (Significand::msb() >> 1) |
                            Significand(v)));
   }
+  LIBC_INLINE static constexpr RetT get_canonical_val(Sign sign = Sign::POS,
+                                                      StorageType v = 0) {
+    return RetT(encode(sign, Exponent::min(), Significand(v)));
+  }
 
   // Observers
   LIBC_INLINE constexpr bool is_zero() const { return exp_sig_bits() == 0; }

>From 5c9c494a66e0d8d0f3cfafcb82114ad58090427b Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Fri, 22 Mar 2024 16:18:08 +0530
Subject: [PATCH 22/24] minor changes

---
 libc/src/__support/FPUtil/BasicOperations.h | 41 +++++++++++----------
 libc/src/__support/FPUtil/FPBits.h          |  4 --
 2 files changed, 21 insertions(+), 24 deletions(-)

diff --git a/libc/src/__support/FPUtil/BasicOperations.h b/libc/src/__support/FPUtil/BasicOperations.h
index 42511cda3c4f59..e247ad3ef172db 100644
--- a/libc/src/__support/FPUtil/BasicOperations.h
+++ b/libc/src/__support/FPUtil/BasicOperations.h
@@ -79,11 +79,7 @@ LIBC_INLINE T fdim(T x, T y) {
 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);
-  if (LIBC_UNLIKELY(sx.is_signaling_nan())) {
-    cx = FPBits<T>::quiet_nan(sx.sign(), sx.get_explicit_mantissa()).get_val();
-    raise_except_if_required(FE_INVALID);
-    return 1;
-  } else if constexpr (get_fp_type<T>() == FPType::X86_Binary80) {
+  if constexpr (get_fp_type<T>() == FPType::X86_Binary80) {
     // All the pseudo and unnormal numbers are not canonical.
     // More precisely :
     // Exponent   |       Significand      | Meaning
@@ -103,26 +99,31 @@ LIBC_INLINE int canonicalize(T &cx, const T &x) {
     int exponent = sx.get_biased_exponent();
     if (exponent == 0x7FFF) {
       if (!bit63 && !bit62) {
-        if (!bit61) {
+        if (!bit61)
           cx = FPBits<T>::inf().get_val();
-        } else {
-          cx = FPBits<T>::signaling_nan().get_val();
+        else {
+          cx = FPBits<T>::quiet_nan(sx.sign(), mantissa).get_val();
+          raise_except_if_required(FE_INVALID);
+          return 1;
         }
       } else if (!bit63 && bit62) {
-        cx = FPBits<T>::signaling_nan().get_val();
-      }
-    } else if (exponent == 0 && bit63) {
-      cx = FPBits<T>::get_canonical_val(sx.sign(), mantissa).get_val();
-    } else if (!bit63) {
-      cx = FPBits<T>::get_canonical_val(sx.sign(), mantissa).get_val();
-    } else {
+        cx = FPBits<T>::quiet_nan(sx.sign(), mantissa).get_val();
+        raise_except_if_required(FE_INVALID);
+        return 1;
+      } else if (exponent == 0 && bit63)
+        cx = FPBits<T>::make_value(mantissa, 1).get_val();
+      else if (!bit63)
+        cx = FPBits<T>::make_value(mantissa, 1).get_val();
+      else
+        cx = x;
+    } else if (LIBC_UNLIKELY(sx.is_signaling_nan())) {
+      cx = FPBits<T>::quiet_nan(sx.sign(), mantissa).get_val();
+      raise_except_if_required(FE_INVALID);
+      return 1;
+    } else
       cx = x;
-    }
-  } else {
-    cx = x;
+    return 0;
   }
-  return 0;
-}
 
 } // namespace fputil
 } // namespace LIBC_NAMESPACE
diff --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h
index fa034880d385c6..155bff2f558102 100644
--- a/libc/src/__support/FPUtil/FPBits.h
+++ b/libc/src/__support/FPUtil/FPBits.h
@@ -501,10 +501,6 @@ struct FPRepSem<FPType::X86_Binary80, RetT>
                        Significand::msb() | (Significand::msb() >> 1) |
                            Significand(v)));
   }
-  LIBC_INLINE static constexpr RetT get_canonical_val(Sign sign = Sign::POS,
-                                                      StorageType v = 0) {
-    return RetT(encode(sign, Exponent::min(), Significand(v)));
-  }
 
   // Observers
   LIBC_INLINE constexpr bool is_zero() const { return exp_sig_bits() == 0; }

>From 920b574d761e23108ab0a8cb9dd6fa21457cbd00 Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Fri, 22 Mar 2024 16:23:16 +0530
Subject: [PATCH 23/24] minor bug fix

---
 libc/src/__support/FPUtil/BasicOperations.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libc/src/__support/FPUtil/BasicOperations.h b/libc/src/__support/FPUtil/BasicOperations.h
index e247ad3ef172db..ea75a5247aef22 100644
--- a/libc/src/__support/FPUtil/BasicOperations.h
+++ b/libc/src/__support/FPUtil/BasicOperations.h
@@ -124,7 +124,7 @@ LIBC_INLINE int canonicalize(T &cx, const T &x) {
       cx = x;
     return 0;
   }
-
+}
 } // namespace fputil
 } // namespace LIBC_NAMESPACE
 

>From 9567307d9332a8ba4ee20e49c86445f11a4cd7ab Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Fri, 22 Mar 2024 16:23:53 +0530
Subject: [PATCH 24/24] Added tests

---
 libc/test/src/math/smoke/CanonicalizeTest.h | 58 ++++++++++++++-------
 1 file changed, 39 insertions(+), 19 deletions(-)

diff --git a/libc/test/src/math/smoke/CanonicalizeTest.h b/libc/test/src/math/smoke/CanonicalizeTest.h
index 2fa097626d1824..6fbc789781fbe9 100644
--- a/libc/test/src/math/smoke/CanonicalizeTest.h
+++ b/libc/test/src/math/smoke/CanonicalizeTest.h
@@ -12,7 +12,14 @@
 #include "test/UnitTest/FPMatcher.h"
 #include "test/UnitTest/Test.h"
 
-#include <math.h>
+#include "include/llvm-libc-macros/math-macros.h"
+
+#define TEST_SPECIAL(x, y, expected, expected_exception)                       \
+  EXPECT_FP_EQ(expected, f(&x, &y));                                           \
+  EXPECT_FP_EXCEPTION(expected_exception);                                     \
+  LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT)
+
+#define TEST_REGULAR(x, y, expected) TEST_SPECIAL(x, y, expected, 0)
 
 template <typename T>
 class CanonicalizeTest : public LIBC_NAMESPACE::testing::Test {
@@ -20,25 +27,38 @@ class CanonicalizeTest : public LIBC_NAMESPACE::testing::Test {
   DECLARE_SPECIAL_CONSTANTS(T)
 
 public:
-  typedef T (*CanonicalizeFunc)(T);
-
-  void testSpecialNumbers(CanonicalizeFunc func) {
-    EXPECT_FP_EQ(zero, func(zero));
-    EXPECT_FP_EQ(neg_zero, func(neg_zero));
-
-    EXPECT_FP_EQ(inf, func(inf));
-    EXPECT_FP_EQ(neg_inf, func(neg_inf));
+  typedef T (*CanonicalizeFunc)(T *, T *);
 
-    EXPECT_FP_EQ(aNaN, func(aNaN));
+  void testSpecialNumbers(CanonicalizeFunc f) {
+    T cx;
+    TEST_SPECIAL(cx, zero, 0, 0);
+    EXPECT_EQ(cx, T(0.0));
+    TEST_SPECIAL(cx, neg_zero, 0, 0);
+    EXPECT_EQ(cx, T(-0.0));
+    TEST_SPECIAL(cx, inf, 0, 0);
+    EXPECT_EQ(cx, inf);
+    TEST_SPECIAL(cx, neg_inf, 0, 0);
+    EXPECT_EQ(cx, neg_inf);
+    TEST_SPECIAL(cx, sNaN, 1, FE_INVALID);
+    EXPECT_EQ(cx, aNaN);
+    TEST_SPECIAL(cx, -sNaN, 1, FE_INVALID);
+    EXPECT_EQ(cx, -aNaN);
   }
 
-  void testRoundedNumbers(CanonicalizeFunc func) {
-    EXPECT_FP_EQ(T(1.0), func(T(1.0)));
-    EXPECT_FP_EQ(T(-1.0), func(T(-1.0)));
-    EXPECT_FP_EQ(T(10.0), func(T(10.0)));
-    EXPECT_FP_EQ(T(-10.0), func(T(-10.0)));
-    EXPECT_FP_EQ(T(1234.0), func(T(1234.0)));
-    EXPECT_FP_EQ(T(-1234.0), func(T(-1234.0)));
+  void testRegularNumbers(CanonicalizeFunc func) {
+    T cx;
+    TEST_REGULAR(cx, T(1.0), 0);
+    EXPECT_EQ(cx, T(1.0));
+    TEST_REGULAR(cx, T(-1.0), 0);
+    EXPECT_EQ(cx, T(-1.0));
+    TEST_REGULAR(cx, T(10.0), 0);
+    EXPECT_EQ(cx, T(10.0));
+    TEST_REGULAR(cx, T(-10.0), 0);
+    EXPECT_EQ(cx, T(-10.0));
+    TEST_REGULAR(cx, T(1234.0), 0);
+    EXPECT_EQ(cx, T(1234.0));
+    TEST_REGULAR(cx, T(-1234.0), 0);
+    EXPECT_EQ(cx, T(-1234.0));
   }
 };
 
@@ -47,8 +67,8 @@ class CanonicalizeTest : public LIBC_NAMESPACE::testing::Test {
   TEST_F(LlvmLibcCanonicalizeTest, SpecialNumbers) {                           \
     testSpecialNumbers(&func);                                                 \
   }                                                                            \
-  TEST_F(LlvmLibcCanonicalizeTest, RoundedNubmers) {                           \
-    testRoundedNumbers(&func);                                                 \
+  TEST_F(LlvmLibcCanonicalizeTest, RegularNubmers) {                           \
+    testRegularNumbers(&func);                                                 \
   }
 
 #endif // LLVM_LIBC_TEST_SRC_MATH_SMOKE_CANONICALIZETEST_H



More information about the libc-commits mailing list