[libc-commits] [libc] [libc][complex] Enable cabs and cabsf in libc (PR #206677)

via libc-commits libc-commits at lists.llvm.org
Tue Jun 30 01:30:42 PDT 2026


https://github.com/jinge90 updated https://github.com/llvm/llvm-project/pull/206677

>From f4cd3d16cde0ccfcf11bcc2dc93405572f9260a7 Mon Sep 17 00:00:00 2001
From: jinge90 <ge.jin at intel.com>
Date: Tue, 30 Jun 2026 15:44:39 +0800
Subject: [PATCH 1/3] add implementation for cabs and cabsf

Signed-off-by: jinge90 <ge.jin at intel.com>
---
 libc/config/baremetal/aarch64/entrypoints.txt |  2 ++
 libc/config/baremetal/arm/entrypoints.txt     |  2 ++
 libc/config/baremetal/riscv/entrypoints.txt   |  2 ++
 libc/config/darwin/aarch64/entrypoints.txt    |  2 ++
 libc/config/linux/aarch64/entrypoints.txt     |  2 ++
 libc/config/linux/arm/entrypoints.txt         |  2 ++
 libc/config/linux/riscv/entrypoints.txt       |  2 ++
 libc/config/linux/x86_64/entrypoints.txt      |  2 ++
 libc/include/complex.yaml                     | 12 +++++++++
 libc/src/complex/CMakeLists.txt               |  2 ++
 libc/src/complex/cabs.h                       | 25 +++++++++++++++++
 libc/src/complex/cabsf.h                      | 25 +++++++++++++++++
 libc/src/complex/generic/CMakeLists.txt       | 26 ++++++++++++++++++
 libc/src/complex/generic/cabs.cpp             | 27 +++++++++++++++++++
 libc/src/complex/generic/cabsf.cpp            | 27 +++++++++++++++++++
 15 files changed, 160 insertions(+)
 create mode 100644 libc/src/complex/cabs.h
 create mode 100644 libc/src/complex/cabsf.h
 create mode 100644 libc/src/complex/generic/cabs.cpp
 create mode 100644 libc/src/complex/generic/cabsf.cpp

diff --git a/libc/config/baremetal/aarch64/entrypoints.txt b/libc/config/baremetal/aarch64/entrypoints.txt
index d446532ec0ab2..149c790bb2448 100644
--- a/libc/config/baremetal/aarch64/entrypoints.txt
+++ b/libc/config/baremetal/aarch64/entrypoints.txt
@@ -311,6 +311,8 @@ set(TARGET_LIBC_ENTRYPOINTS
 
 set(TARGET_LIBM_ENTRYPOINTS
     # complex.h entrypoints
+    libc.src.complex.cabs
+    libc.src.complex.cabsf
     libc.src.complex.carg
     libc.src.complex.cargf
     libc.src.complex.creal
diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt
index 4bd3c314dc203..8a8ab3d6a78fd 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -323,6 +323,8 @@ set(TARGET_LIBC_ENTRYPOINTS
 
 set(TARGET_LIBM_ENTRYPOINTS
     # complex.h entrypoints
+    libc.src.complex.cabs
+    libc.src.complex.cabsf
     libc.src.complex.carg
     libc.src.complex.cargf
     libc.src.complex.creal
diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt
index 54e2c1ba01e35..d0b8f091cd6e2 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -321,6 +321,8 @@ set(TARGET_LIBC_ENTRYPOINTS
 
 set(TARGET_LIBM_ENTRYPOINTS
     # complex.h entrypoints
+    libc.src.complex.cabs
+    libc.src.complex.cabsf
     libc.src.complex.carg
     libc.src.complex.cargf
     libc.src.complex.creal
diff --git a/libc/config/darwin/aarch64/entrypoints.txt b/libc/config/darwin/aarch64/entrypoints.txt
index 7906905654802..eeb9ec244b415 100644
--- a/libc/config/darwin/aarch64/entrypoints.txt
+++ b/libc/config/darwin/aarch64/entrypoints.txt
@@ -132,6 +132,8 @@ endif()
 
 set(TARGET_LIBM_ENTRYPOINTS
     # complex.h entrypoints
+    libc.src.complex.cabs
+    libc.src.complex.cabsf
     libc.src.complex.carg
     libc.src.complex.cargf
     libc.src.complex.creal
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index d6e627fdea421..2268f9418a9ae 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -444,6 +444,8 @@ endif()
 
 set(TARGET_LIBM_ENTRYPOINTS
     # complex.h entrypoints
+    libc.src.complex.cabs
+    libc.src.complex.cabsf
     libc.src.complex.carg
     libc.src.complex.cargf
     libc.src.complex.creal
diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt
index 1b586fe90f91a..bf0897868989c 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -240,6 +240,8 @@ endif()
 
 set(TARGET_LIBM_ENTRYPOINTS
     # complex.h entrypoints
+    libc.src.complex.cabs
+    libc.src.complex.cabsf
     libc.src.complex.carg
     libc.src.complex.cargf
     libc.src.complex.creal
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 3bb12384633a5..77e5bec86fa9a 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -448,6 +448,8 @@ endif()
 
 set(TARGET_LIBM_ENTRYPOINTS
     # complex.h entrypoints
+    libc.src.complex.cabs
+    libc.src.complex.cabsf
     libc.src.complex.carg
     libc.src.complex.cargf
     libc.src.complex.creal
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 81301fb5c4d65..d3fd6c6d814d0 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -514,6 +514,8 @@ endif()
 
 set(TARGET_LIBM_ENTRYPOINTS
     # complex.h entrypoints
+    libc.src.complex.cabs
+    libc.src.complex.cabsf
     libc.src.complex.carg
     libc.src.complex.cargf
     libc.src.complex.creal
diff --git a/libc/include/complex.yaml b/libc/include/complex.yaml
index 29799799d2e6b..dc67973a02406 100644
--- a/libc/include/complex.yaml
+++ b/libc/include/complex.yaml
@@ -21,6 +21,18 @@ types:
 enums: []
 objects: []
 functions:
+  - name: cabs
+    standards:
+      - stdc
+    return_type: double
+    arguments:
+      - type: _Complex double
+  - name: cabsf
+    standards:
+      - stdc
+    return_type: float
+    arguments:
+      - type: _Complex float
   - name: carg
     standards:
       - stdc
diff --git a/libc/src/complex/CMakeLists.txt b/libc/src/complex/CMakeLists.txt
index 1ebc1e8ac6141..5f334dd0be462 100644
--- a/libc/src/complex/CMakeLists.txt
+++ b/libc/src/complex/CMakeLists.txt
@@ -37,6 +37,8 @@ add_complex_entrypoint_object(cprojl)
 add_complex_entrypoint_object(cprojf16)
 add_complex_entrypoint_object(cprojf128)
 
+add_complex_entrypoint_object(cabs)
+add_complex_entrypoint_object(cabsf)
 add_complex_entrypoint_object(carg)
 add_complex_entrypoint_object(cargf)
 
diff --git a/libc/src/complex/cabs.h b/libc/src/complex/cabs.h
new file mode 100644
index 0000000000000..7e8134c806d57
--- /dev/null
+++ b/libc/src/complex/cabs.h
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains the declaration of cabs.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_COMPLEX_CABS_H
+#define LLVM_LIBC_SRC_COMPLEX_CABS_H
+
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+double cabs(_Complex double x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_COMPLEX_CABS_H
diff --git a/libc/src/complex/cabsf.h b/libc/src/complex/cabsf.h
new file mode 100644
index 0000000000000..202fceceb5e9d
--- /dev/null
+++ b/libc/src/complex/cabsf.h
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains the declaration of cabsf.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_COMPLEX_CABSF_H
+#define LLVM_LIBC_SRC_COMPLEX_CABSF_H
+
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+float cabsf(_Complex float x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_COMPLEX_CABSF_H
diff --git a/libc/src/complex/generic/CMakeLists.txt b/libc/src/complex/generic/CMakeLists.txt
index 159118182384e..a972129b0be8c 100644
--- a/libc/src/complex/generic/CMakeLists.txt
+++ b/libc/src/complex/generic/CMakeLists.txt
@@ -1,3 +1,29 @@
+add_entrypoint_object(
+  cabs
+  SRCS
+    cabs.cpp
+  HDRS
+    ../cabs.h
+  DEPENDS
+    libc.src.__support.CPP.bit
+    libc.src.__support.common
+    libc.src.__support.complex_type
+    libc.src.__support.math.hypot
+)
+
+add_entrypoint_object(
+  cabsf
+  SRCS
+    cabsf.cpp
+  HDRS
+    ../cabsf.h
+  DEPENDS
+    libc.src.__support.CPP.bit
+    libc.src.__support.common
+    libc.src.__support.complex_type
+    libc.src.__support.math.hypotf
+)
+
 add_entrypoint_object(
   carg
   SRCS
diff --git a/libc/src/complex/generic/cabs.cpp b/libc/src/complex/generic/cabs.cpp
new file mode 100644
index 0000000000000..fb4afff4f37b9
--- /dev/null
+++ b/libc/src/complex/generic/cabs.cpp
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains the implementation of cabs.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/complex/cabs.h"
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+#include "src/__support/complex_type.h"
+#include "src/__support/math/hypot.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(double, cabs, (_Complex double x)) {
+  Complex<double> x_c = cpp::bit_cast<Complex<double>>(x);
+  return math::hypot(x_c.imag, x_c.real);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/complex/generic/cabsf.cpp b/libc/src/complex/generic/cabsf.cpp
new file mode 100644
index 0000000000000..77c6386082b5d
--- /dev/null
+++ b/libc/src/complex/generic/cabsf.cpp
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains the implementation of cabsf.
+///
+//===----------------------------------------------------------------------===//
+
+#include "src/complex/cabsf.h"
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+#include "src/__support/complex_type.h"
+#include "src/__support/math/hypotf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(float, cabsf, (_Complex float x)) {
+  Complex<float> x_c = cpp::bit_cast<Complex<float>>(x);
+  return math::hypotf(x_c.imag, x_c.real);
+}
+
+} // namespace LIBC_NAMESPACE_DECL

>From 05a21701796bfd4940fd93ae25d859d16a7d12fb Mon Sep 17 00:00:00 2001
From: jinge90 <ge.jin at intel.com>
Date: Tue, 30 Jun 2026 16:52:58 +0800
Subject: [PATCH 2/3] Add test for cabs and cabsf

Signed-off-by: jinge90 <ge.jin at intel.com>
---
 libc/docs/headers/complex.rst        |   2 +-
 libc/test/src/complex/CAbsTest.h     | 119 +++++++++++++++++++++++++++
 libc/test/src/complex/CMakeLists.txt |  26 ++++++
 libc/test/src/complex/cabs_test.cpp  |  36 ++++++++
 libc/test/src/complex/cabsf_test.cpp |  37 +++++++++
 libc/utils/MPCWrapper/MPCUtils.cpp   |  16 ++++
 6 files changed, 235 insertions(+), 1 deletion(-)
 create mode 100644 libc/test/src/complex/CAbsTest.h
 create mode 100644 libc/test/src/complex/cabs_test.cpp
 create mode 100644 libc/test/src/complex/cabsf_test.cpp

diff --git a/libc/docs/headers/complex.rst b/libc/docs/headers/complex.rst
index 1a0137d6dea51..0db591977349d 100644
--- a/libc/docs/headers/complex.rst
+++ b/libc/docs/headers/complex.rst
@@ -45,7 +45,7 @@ Functions
 +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
 | clog      |                  |                 |                        |                      |                        | 7.3.7.2                | G.6.4.2                    |
 +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
-| cabs      |                  |                 |                        |                      |                        | 7.3.8.1                | N/A                        |
+| cabs      | |check|          | |check|         |                        |                      |                        | 7.3.8.1                | N/A                        |
 +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
 | cpow      |                  |                 |                        |                      |                        | 7.3.8.2                | G.6.5.1                    |
 +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
diff --git a/libc/test/src/complex/CAbsTest.h b/libc/test/src/complex/CAbsTest.h
new file mode 100644
index 0000000000000..08bf9c1729dd5
--- /dev/null
+++ b/libc/test/src/complex/CAbsTest.h
@@ -0,0 +1,119 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains utility class to test different flavors of cabs.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_TEST_SRC_COMPLEX_CABSTEST_H
+#define LLVM_LIBC_TEST_SRC_COMPLEX_CABSTEST_H
+
+#include "test/UnitTest/FEnvSafeTest.h"
+#include "test/UnitTest/FPMatcher.h"
+#include "test/UnitTest/Test.h"
+
+#include "hdr/math_macros.h"
+
+template <typename CFPT, typename FPT>
+class CAbsTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
+
+  DECLARE_SPECIAL_CONSTANTS(FPT)
+
+public:
+  using CAbsFunc = FPT (*)(CFPT);
+
+  void testZeroValues(CAbsFunc func) {
+    // cabs(+0 + 0i) = +0
+    EXPECT_FP_EQ(zero, func(CFPT{0.0, 0.0}));
+    // cabs(-0 + 0i) = +0
+    EXPECT_FP_EQ(zero, func(CFPT{-0.0, 0.0}));
+    // cabs(+0 - 0i) = +0
+    EXPECT_FP_EQ(zero, func(CFPT{0.0, -0.0}));
+    // cabs(-0 - 0i) = +0
+    EXPECT_FP_EQ(zero, func(CFPT{-0.0, -0.0}));
+  }
+
+  void testBasicValues(CAbsFunc func) {
+    // cabs(3 + 4i) = 5
+    EXPECT_FP_EQ(FPT(5.0), func(CFPT{3.0, 4.0}));
+    // cabs(-3 + 4i) = 5
+    EXPECT_FP_EQ(FPT(5.0), func(CFPT{-3.0, 4.0}));
+    // cabs(3 - 4i) = 5
+    EXPECT_FP_EQ(FPT(5.0), func(CFPT{3.0, -4.0}));
+    // cabs(-3 - 4i) = 5
+    EXPECT_FP_EQ(FPT(5.0), func(CFPT{-3.0, -4.0}));
+    // cabs(1 + 0i) = 1
+    EXPECT_FP_EQ(FPT(1.0), func(CFPT{1.0, 0.0}));
+    // cabs(0 + 1i) = 1
+    EXPECT_FP_EQ(FPT(1.0), func(CFPT{0.0, 1.0}));
+    // cabs(5 + 12i) = 13
+    EXPECT_FP_EQ(FPT(13.0), func(CFPT{5.0, 12.0}));
+  }
+
+  void testInfinityValues(CAbsFunc func) {
+    // cabs(+inf + yi) = +inf for finite y
+    EXPECT_FP_EQ(inf, func(CFPT{inf, 0.0}));
+    EXPECT_FP_EQ(inf, func(CFPT{inf, 1.0}));
+    EXPECT_FP_EQ(inf, func(CFPT{inf, -1.0}));
+    EXPECT_FP_EQ(inf, func(CFPT{inf, 256.0}));
+    // cabs(-inf + yi) = +inf for finite y
+    EXPECT_FP_EQ(inf, func(CFPT{neg_inf, 0.0}));
+    EXPECT_FP_EQ(inf, func(CFPT{neg_inf, 1.0}));
+    EXPECT_FP_EQ(inf, func(CFPT{neg_inf, -1.0}));
+    EXPECT_FP_EQ(inf, func(CFPT{neg_inf, 512.0}));
+    // cabs(x + inf*i) = +inf for finite x
+    EXPECT_FP_EQ(inf, func(CFPT{0.0, inf}));
+    EXPECT_FP_EQ(inf, func(CFPT{1.0, inf}));
+    EXPECT_FP_EQ(inf, func(CFPT{-1.0, inf}));
+    EXPECT_FP_EQ(inf, func(CFPT{4.0, inf}));
+    // cabs(x - inf*i) = +inf for finite x
+    EXPECT_FP_EQ(inf, func(CFPT{0.0, neg_inf}));
+    EXPECT_FP_EQ(inf, func(CFPT{1.0, neg_inf}));
+    EXPECT_FP_EQ(inf, func(CFPT{-1.0, neg_inf}));
+    EXPECT_FP_EQ(inf, func(CFPT{4.0, neg_inf}));
+    // cabs(+inf + inf*i) = +inf
+    EXPECT_FP_EQ(inf, func(CFPT{inf, inf}));
+    // cabs(-inf + inf*i) = +inf
+    EXPECT_FP_EQ(inf, func(CFPT{neg_inf, inf}));
+    // cabs(+inf + NaN*i) = +inf
+    EXPECT_FP_EQ(inf, func(CFPT{inf, aNaN}));
+    // cabs(-inf + NaN*i) = +inf
+    EXPECT_FP_EQ(inf, func(CFPT{neg_inf, aNaN}));
+    // cabs(NaN + inf*i) = +inf
+    EXPECT_FP_EQ(inf, func(CFPT{aNaN, inf}));
+    // cabs(NaN - inf*i) = +inf
+    EXPECT_FP_EQ(inf, func(CFPT{aNaN, neg_inf}));
+  }
+
+  void testNaNValues(CAbsFunc func) {
+    // cabs(NaN + yi) = NaN for finite y
+    EXPECT_FP_IS_NAN(func(CFPT{aNaN, 0.0}));
+    EXPECT_FP_IS_NAN(func(CFPT{aNaN, 1.0}));
+    EXPECT_FP_IS_NAN(func(CFPT{aNaN, -1.0}));
+    EXPECT_FP_IS_NAN(func(CFPT{aNaN, 512.0}));
+
+    // cabs(x + NaN*i) = NaN for finite x
+    EXPECT_FP_IS_NAN(func(CFPT{0.0, aNaN}));
+    EXPECT_FP_IS_NAN(func(CFPT{1.0, aNaN}));
+    EXPECT_FP_IS_NAN(func(CFPT{-1.0, aNaN}));
+    EXPECT_FP_IS_NAN(func(CFPT{4.0, aNaN}));
+
+    // cabs(NaN + NaN*i) = NaN
+    EXPECT_FP_IS_NAN(func(CFPT{aNaN, aNaN}));
+  }
+};
+
+#define LIST_CABS_TESTS(U, T, func)                                            \
+  using LlvmLibcCAbsTest = CAbsTest<U, T>;                                    \
+  TEST_F(LlvmLibcCAbsTest, ZeroValues) { testZeroValues(&func); }             \
+  TEST_F(LlvmLibcCAbsTest, BasicValues) { testBasicValues(&func); }           \
+  TEST_F(LlvmLibcCAbsTest, InfinityValues) { testInfinityValues(&func); }     \
+  TEST_F(LlvmLibcCAbsTest, NaNValues) { testNaNValues(&func); }
+
+#endif // LLVM_LIBC_TEST_SRC_COMPLEX_CABSTEST_H
diff --git a/libc/test/src/complex/CMakeLists.txt b/libc/test/src/complex/CMakeLists.txt
index fc16cf0d92ea2..e88416cf13ae1 100644
--- a/libc/test/src/complex/CMakeLists.txt
+++ b/libc/test/src/complex/CMakeLists.txt
@@ -1,5 +1,31 @@
 add_custom_target(libc-complex-unittests)
 
+add_fp_unittest(
+  cabs_test
+  NEED_MPC
+  SUITE
+    libc-complex-unittests
+  SRCS
+    cabs_test.cpp
+  HDRS
+    CAbsTest.h
+  DEPENDS
+    libc.src.complex.cabs
+)
+
+add_fp_unittest(
+  cabsf_test
+  NEED_MPC
+  SUITE
+    libc-complex-unittests
+  SRCS
+    cabsf_test.cpp
+  HDRS
+    CAbsTest.h
+  DEPENDS
+    libc.src.complex.cabsf
+)
+
 add_fp_unittest(
   carg_test
   NEED_MPC
diff --git a/libc/test/src/complex/cabs_test.cpp b/libc/test/src/complex/cabs_test.cpp
new file mode 100644
index 0000000000000..26852963eb93b
--- /dev/null
+++ b/libc/test/src/complex/cabs_test.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains unittest for cabs.
+///
+//===----------------------------------------------------------------------===//
+
+#include "CAbsTest.h"
+
+#include "src/complex/cabs.h"
+#include "utils/MPCWrapper/MPCUtils.h"
+
+using LlvmLibcCabsMPCTest = LIBC_NAMESPACE::testing::FPTest<double>;
+
+namespace mpc = LIBC_NAMESPACE::testing::mpc;
+
+TEST_F(LlvmLibcCabsMPCTest, BasicForRounding) {
+  _Complex double test_values[] = {
+      1.0 + 1.0i,  -1.0 + 1.0i, 1.0 - 1.0i,   -1.0 - 1.0i,     3.0 + 4.0i,
+      -3.0 + 4.0i, 3.0 - 4.0i,  -3.0 - 4.0i,  0.5 + 0.5i,      -0.5 + 0.5i,
+      0.5 - 0.5i,  -0.5 - 0.5i, 1.0 + 0.0i,   -1.0 + 0.0i,     0.0 + 1.0i,
+      0.0 - 1.0i,  5.0 + 12.0i, 100.0 + 1.0i, 0.001 + 1000.0i,
+  };
+  for (_Complex double val : test_values) {
+    EXPECT_MPC_MATCH_ALL_ROUNDING(mpc::Operation::Cabs, val,
+                                  LIBC_NAMESPACE::cabs(val), 0.5);
+  }
+}
+
+LIST_CABS_TESTS(_Complex double, double, LIBC_NAMESPACE::cabs)
diff --git a/libc/test/src/complex/cabsf_test.cpp b/libc/test/src/complex/cabsf_test.cpp
new file mode 100644
index 0000000000000..d2f12046b9182
--- /dev/null
+++ b/libc/test/src/complex/cabsf_test.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file contains unittest for cabsf.
+///
+//===----------------------------------------------------------------------===//
+
+#include "CAbsTest.h"
+
+#include "src/complex/cabsf.h"
+#include "utils/MPCWrapper/MPCUtils.h"
+
+using LlvmLibcCabsfMPCTest = LIBC_NAMESPACE::testing::FPTest<float>;
+
+namespace mpc = LIBC_NAMESPACE::testing::mpc;
+
+TEST_F(LlvmLibcCabsfMPCTest, BasicForRounding) {
+  _Complex float test_values[] = {
+      1.0f + 1.0fi,  -1.0f + 1.0fi,  1.0f - 1.0fi,      -1.0f - 1.0fi,
+      3.0f + 4.0fi,  -3.0f + 4.0fi,  3.0f - 4.0fi,      -3.0f - 4.0fi,
+      0.5f + 0.5fi,  -0.5f + 0.5fi,  0.5f - 0.5fi,      -0.5f - 0.5fi,
+      1.0f + 0.0fi,  -1.0f + 0.0fi,  0.0f + 1.0fi,      0.0f - 1.0fi,
+      5.0f + 12.0fi, 100.0f + 1.0fi, 0.001f + 1000.0fi,
+  };
+  for (_Complex float val : test_values) {
+    EXPECT_MPC_MATCH_ALL_ROUNDING(mpc::Operation::Cabs, val,
+                                  LIBC_NAMESPACE::cabsf(val), 0.5);
+  }
+}
+
+LIST_CABS_TESTS(_Complex float, float, LIBC_NAMESPACE::cabsf)
diff --git a/libc/utils/MPCWrapper/MPCUtils.cpp b/libc/utils/MPCWrapper/MPCUtils.cpp
index 11e93ec5cb894..20e2637912ee0 100644
--- a/libc/utils/MPCWrapper/MPCUtils.cpp
+++ b/libc/utils/MPCWrapper/MPCUtils.cpp
@@ -105,6 +105,20 @@ class MPCNumber {
 
   mpc_t &getValue() { return value; }
 
+  MPCNumber cabs() const {
+    mpfr_t res;
+    MPCNumber result(precision, mpc_rounding);
+
+    mpfr_init2(res, precision);
+
+    mpc_abs(res, value, MPC_RND_RE(mpc_rounding));
+    mpc_set_fr(result.value, res, mpc_rounding);
+
+    mpfr_clear(res);
+
+    return result;
+  }
+
   MPCNumber carg() const {
     mpfr_t res;
     MPCNumber result(precision, mpc_rounding);
@@ -134,6 +148,8 @@ unary_operation(Operation op, InputType input, unsigned int precision,
                 RoundingMode rounding) {
   MPCNumber mpcInput(input, precision, rounding);
   switch (op) {
+  case Operation::Cabs:
+    return mpcInput.cabs();
   case Operation::Carg:
     return mpcInput.carg();
   case Operation::Cproj:

>From 6a3737f046e106d1c2196802f85ad41319f6e0f4 Mon Sep 17 00:00:00 2001
From: jinge90 <ge.jin at intel.com>
Date: Tue, 30 Jun 2026 17:03:02 +0800
Subject: [PATCH 3/3] fix clang format

Signed-off-by: jinge90 <ge.jin at intel.com>
---
 libc/test/src/complex/CAbsTest.h | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/libc/test/src/complex/CAbsTest.h b/libc/test/src/complex/CAbsTest.h
index 08bf9c1729dd5..5007671142e05 100644
--- a/libc/test/src/complex/CAbsTest.h
+++ b/libc/test/src/complex/CAbsTest.h
@@ -110,10 +110,10 @@ class CAbsTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
 };
 
 #define LIST_CABS_TESTS(U, T, func)                                            \
-  using LlvmLibcCAbsTest = CAbsTest<U, T>;                                    \
-  TEST_F(LlvmLibcCAbsTest, ZeroValues) { testZeroValues(&func); }             \
-  TEST_F(LlvmLibcCAbsTest, BasicValues) { testBasicValues(&func); }           \
-  TEST_F(LlvmLibcCAbsTest, InfinityValues) { testInfinityValues(&func); }     \
+  using LlvmLibcCAbsTest = CAbsTest<U, T>;                                     \
+  TEST_F(LlvmLibcCAbsTest, ZeroValues) { testZeroValues(&func); }              \
+  TEST_F(LlvmLibcCAbsTest, BasicValues) { testBasicValues(&func); }            \
+  TEST_F(LlvmLibcCAbsTest, InfinityValues) { testInfinityValues(&func); }      \
   TEST_F(LlvmLibcCAbsTest, NaNValues) { testNaNValues(&func); }
 
 #endif // LLVM_LIBC_TEST_SRC_COMPLEX_CABSTEST_H



More information about the libc-commits mailing list