16 changes: 16 additions & 0 deletions libc/test/src/math/smoke/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,22 @@ add_fp_unittest(
UNIT_TEST_ONLY
)

add_fp_unittest(
copysignf128_test
SUITE
libc-math-smoke-tests
SRCS
copysignf128_test.cpp
HDRS
CopySignTest.h
DEPENDS
libc.include.math
libc.src.math.copysignf128
libc.src.__support.FPUtil.fp_bits
# FIXME: Currently fails on the GPU build.
UNIT_TEST_ONLY
)

add_fp_unittest(
frexp_test
SUITE
Expand Down
21 changes: 11 additions & 10 deletions libc/test/src/math/smoke/CopySignTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,28 +20,29 @@ class CopySignTest : public LIBC_NAMESPACE::testing::Test {
typedef T (*CopySignFunc)(T, T);

void testSpecialNumbers(CopySignFunc func) {
EXPECT_FP_EQ(aNaN, func(aNaN, -1.0));
EXPECT_FP_EQ(aNaN, func(aNaN, 1.0));
EXPECT_FP_EQ(aNaN, func(aNaN, T(-1.0)));
EXPECT_FP_EQ(aNaN, func(aNaN, T(1.0)));

EXPECT_FP_EQ(neg_inf, func(inf, -1.0));
EXPECT_FP_EQ(inf, func(neg_inf, 1.0));
EXPECT_FP_EQ(neg_inf, func(inf, T(-1.0)));
EXPECT_FP_EQ(inf, func(neg_inf, T(1.0)));

EXPECT_FP_EQ(neg_zero, func(zero, -1.0));
EXPECT_FP_EQ(zero, func(neg_zero, 1.0));
EXPECT_FP_EQ(neg_zero, func(zero, T(-1.0)));
EXPECT_FP_EQ(zero, func(neg_zero, T(1.0)));
}

void testRange(CopySignFunc func) {
constexpr UIntType COUNT = 100'000;
constexpr UIntType STEP = UIntType(-1) / COUNT;
for (UIntType i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
T x = T(FPBits(v));
if (isnan(x) || isinf(x))
FPBits x_bits = FPBits(v);
T x = T(v);
if (x_bits.is_nan() || x_bits.is_inf())
continue;

double res1 = func(x, -x);
T res1 = func(x, -x);
ASSERT_FP_EQ(res1, -x);

double res2 = func(x, x);
T res2 = func(x, x);
ASSERT_FP_EQ(res2, x);
}
}
Expand Down
13 changes: 13 additions & 0 deletions libc/test/src/math/smoke/copysignf128_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//===-- Unittests for copysignf128 ----------------------------------------===//
//
// 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 "CopySignTest.h"

#include "src/math/copysignf128.h"

LIST_COPYSIGN_TESTS(float128, LIBC_NAMESPACE::copysignf128)
3 changes: 3 additions & 0 deletions utils/bazel/llvm-project-overlay/libc/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ libc_support_library(
deps = [
":__support_macros_attributes",
":__support_macros_config",
":__support_macros_properties_compiler",
],
)

Expand Down Expand Up @@ -1821,6 +1822,8 @@ libc_math_function(name = "copysignf")

libc_math_function(name = "copysignl")

libc_math_function(name = "copysignf128")

libc_math_function(name = "ilogb")

libc_math_function(name = "ilogbf")
Expand Down