Skip to content

Commit 4b87063

Browse files
committed
update tests
1 parent 6212824 commit 4b87063

File tree

3 files changed

+174
-23
lines changed

3 files changed

+174
-23
lines changed

libc/test/src/math/exhaustive/CMakeLists.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,21 @@ add_fp_unittest(
312312
-lpthread
313313
)
314314

315+
add_fp_unittest(
316+
powf16_test
317+
NO_RUN_POSTBUILD
318+
NEED_MPFR
319+
SUITE
320+
libc_math_exhaustive_tests
321+
SRCS
322+
powf16_test.cpp
323+
DEPENDS
324+
.exhaustive_test
325+
libc.src.math.powf16
326+
libc.src.__support.FPUtil.fp_bits
327+
LINK_LIBRARIES
328+
-lpthread
329+
)
315330
add_fp_unittest(
316331
hypotf_test
317332
NO_RUN_POSTBUILD
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
//===-- Exhaustive test for powf16 ----------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "exhaustive_test.h"
10+
#include "src/__support/FPUtil/FPBits.h"
11+
#include "src/math/powf16.h"
12+
#include "test/UnitTest/FPMatcher.h"
13+
#include "utils/MPFRWrapper/MPFRUtils.h"
14+
15+
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
16+
17+
struct Powf16Checker : public virtual LIBC_NAMESPACE::testing::Test {
18+
using FloatType = float16;
19+
using FPBits = LIBC_NAMESPACE::fputil::FPBits<float16>;
20+
using StorageType = typename FPBits::StorageType;
21+
22+
uint64_t check(uint16_t x_start, uint16_t x_stop, uint16_t y_start,
23+
uint16_t y_stop, mpfr::RoundingMode rounding) {
24+
mpfr::ForceRoundingMode r(rounding);
25+
if (!r.success)
26+
return true;
27+
uint16_t xbits = x_start;
28+
uint64_t failed = 0;
29+
do {
30+
float16 x = FPBits(xbits).get_val();
31+
uint16_t ybits = y_start;
32+
do {
33+
float16 y = FPBits(ybits).get_val();
34+
mpfr::BinaryInput<float16> input{x, y};
35+
bool correct = TEST_MPFR_MATCH_ROUNDING_SILENTLY(
36+
mpfr::Operation::Pow, input, LIBC_NAMESPACE::powf16(x, y), 0.5,
37+
rounding);
38+
failed += (!correct);
39+
} while (ybits++ < y_stop);
40+
} while (xbits++ < x_stop);
41+
return failed;
42+
}
43+
};
44+
45+
using LlvmLibcPowf16ExhaustiveTest =
46+
LlvmLibcExhaustiveMathTest<Powf16Checker, 1 << 8>;
47+
48+
// Range: x in [0, inf], y in [0, inf]
49+
static constexpr uint16_t POS_START = 0x0000U;
50+
static constexpr uint16_t POS_STOP = 0x7C00U;
51+
52+
TEST_F(LlvmLibcPowf16ExhaustiveTest, PositiveRange) {
53+
test_full_range_all_roundings(POS_START, POS_STOP, POS_START, POS_STOP);
54+
}
55+
56+
// Range: x in [-0, -inf], y in [0, inf]
57+
static constexpr uint16_t NEG_START = 0x8000U;
58+
static constexpr uint16_t NEG_STOP = 0xFC00U;
59+
60+
TEST_F(LlvmLibcPowf16ExhaustiveTest, NegativeBasePositiveExponent) {
61+
test_full_range_all_roundings(NEG_START, NEG_STOP, POS_START, POS_STOP);
62+
}
63+
64+
// Range: x in [0, inf], y in [-0, -inf]
65+
TEST_F(LlvmLibcPowf16ExhaustiveTest, PositiveBaseNegativeExponent) {
66+
test_full_range_all_roundings(POS_START, POS_STOP, NEG_START, NEG_STOP);
67+
}
68+
69+
// Range: x in [-0, -inf], y in [-0, -inf]
70+
TEST_F(LlvmLibcPowf16ExhaustiveTest, NegativeRange) {
71+
test_full_range_all_roundings(NEG_START, NEG_STOP, NEG_START, NEG_STOP);
72+
}

libc/test/src/math/powf16_test.cpp

Lines changed: 87 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,45 +5,109 @@
55
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66
//
77
//===----------------------------------------------------------------------===//
8-
8+
#include "src/__support/CPP/bit.h"
99
#include "src/math/powf16.h"
1010
#include "test/UnitTest/FPMatcher.h"
1111
#include "test/UnitTest/Test.h"
1212
#include "utils/MPFRWrapper/MPFRUtils.h"
1313

1414
using LlvmLibcPowF16Test = LIBC_NAMESPACE::testing::FPTest<float16>;
15+
using FPBits = LIBC_NAMESPACE::fputil::FPBits<float16>;
1516

1617
namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
1718

1819
static constexpr float16 SELECTED_VALS[] = {
19-
0.5f16, 0.83984375f16, 1.0f16, 2.0f16, 3.0f16, 3.140625f16, 15.5f16,
20-
};
21-
22-
// Test selected x values against all possible y values.
23-
TEST_F(LlvmLibcPowF16Test, SelectedX_AllY) {
24-
for (size_t i = 0; i < sizeof(SELECTED_VALS) / sizeof(SELECTED_VALS[0]);
25-
++i) {
26-
float16 x = SELECTED_VALS[i];
27-
for (uint16_t y_u = 0; y_u <= 0x7c00U; ++y_u) {
28-
float16 y = FPBits(y_u).get_val();
29-
30-
mpfr::BinaryInput<float16> input{x, y};
20+
0.83984375f16, 1.414f16, 0.0625f16, 2.5f16,
21+
3.140625f16, 15.5f16, 2.f16, 3.25f16};
22+
23+
// Test tricky inputs for selected x values against all possible y values.
24+
TEST_F(LlvmLibcPowF16Test, TrickyInput_SelectedX_AllY) {
25+
for (float16 x_base : SELECTED_VALS) {
26+
// Only test non-negative x_base
27+
if (FPBits(x_base).is_neg())
28+
continue;
29+
30+
// Loop through normal and subnormal values only (0x0001 to 0x7BFF)
31+
for (uint16_t y_u = 1; y_u <= 0x7BFFU; ++y_u) {
32+
float16 y_base = FPBits(y_u).get_val();
33+
34+
// Case 1: (+x, +y) - Standard positive case
35+
mpfr::BinaryInput<float16> input1{x_base, y_base};
36+
EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Pow, input1,
37+
LIBC_NAMESPACE::powf16(x_base, y_base),
38+
0.5);
39+
40+
// Case 2: (+x, -y) - Always valid for positive x
41+
float16 y_neg = -y_base;
42+
mpfr::BinaryInput<float16> input2{x_base, y_neg};
43+
EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Pow, input2,
44+
LIBC_NAMESPACE::powf16(x_base, y_neg),
45+
0.5);
46+
}
47+
48+
// Case 3: (-x, +y) - Only test with positive integer y values
49+
for (int y_int = 1; y_int <= 2048; ++y_int) {
50+
float16 y_val = static_cast<float16>(y_int);
51+
float16 x_neg = -x_base;
52+
mpfr::BinaryInput<float16> input{x_neg, y_val};
53+
EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Pow, input,
54+
LIBC_NAMESPACE::powf16(x_neg, y_val), 0.5);
55+
}
56+
57+
// Case 4: (-x, -y) - Only test with negative integer y values
58+
for (int y_int = -2048; y_int < 0; ++y_int) {
59+
float16 y_val = static_cast<float16>(y_int);
60+
float16 x_neg = -x_base;
61+
mpfr::BinaryInput<float16> input{x_neg, y_val};
3162
EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Pow, input,
32-
LIBC_NAMESPACE::powf16(x, y), 0.5);
63+
LIBC_NAMESPACE::powf16(x_neg, y_val), 0.5);
3364
}
3465
}
3566
}
3667

37-
// Test selected y values against all possible x values.
38-
TEST_F(LlvmLibcPowF16Test, SelectedY_AllX) {
39-
for (size_t i = 0; i < sizeof(SELECTED_VALS) / sizeof(SELECTED_VALS[0]);
40-
++i) {
41-
float16 y = SELECTED_VALS[i];
42-
for (uint16_t x_u = 0; x_u <= 0x7c00U; ++x_u) {
43-
float16 x = FPBits(x_u).get_val();
44-
mpfr::BinaryInput<float16> input{x, y};
68+
// Test tricky inputs for selected y values against all possible x values.
69+
TEST_F(LlvmLibcPowF16Test, TrickyInput_SelectedY_AllX) {
70+
for (float16 y_base : SELECTED_VALS) {
71+
// Only test non-negative y_base
72+
if (FPBits(y_base).is_neg())
73+
continue;
74+
75+
// Loop through normal and subnormal values only (0x0001 to 0x7BFF)
76+
for (uint16_t x_u = 1; x_u <= 0x7BFFU; ++x_u) {
77+
float16 x_base = FPBits(x_u).get_val();
78+
79+
// Case 1: (+x, +y) - Standard positive case
80+
mpfr::BinaryInput<float16> input1{x_base, y_base};
81+
EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Pow, input1,
82+
LIBC_NAMESPACE::powf16(x_base, y_base),
83+
0.5);
84+
85+
// Case 2: (+x, -y) - Always valid for positive x
86+
float16 y_neg = -y_base;
87+
mpfr::BinaryInput<float16> input2{x_base, y_neg};
88+
EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Pow, input2,
89+
LIBC_NAMESPACE::powf16(x_base, y_neg),
90+
0.5);
91+
}
92+
93+
// Case 3: (-x, +y) - Only test with positive integer x values
94+
for (int x_int = 1; x_int <= 2048; ++x_int) {
95+
float16 x_val = static_cast<float16>(x_int);
96+
float16 x_neg = -x_val;
97+
mpfr::BinaryInput<float16> input{x_neg, y_base};
98+
EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Pow, input,
99+
LIBC_NAMESPACE::powf16(x_neg, y_base),
100+
0.5);
101+
}
102+
103+
// Case 4: (-x, -y) - Only test with negative integer x values
104+
for (int x_int = 1; x_int <= 2048; ++x_int) {
105+
float16 x_val = static_cast<float16>(x_int);
106+
float16 x_neg = -x_val;
107+
float16 y_neg = -y_base;
108+
mpfr::BinaryInput<float16> input{x_neg, y_neg};
45109
EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Pow, input,
46-
LIBC_NAMESPACE::powf16(x, y), 0.5);
110+
LIBC_NAMESPACE::powf16(x_neg, y_neg), 0.5);
47111
}
48112
}
49113
}

0 commit comments

Comments
 (0)