|
5 | 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | 6 | // |
7 | 7 | //===----------------------------------------------------------------------===// |
8 | | - |
| 8 | +#include "src/__support/CPP/bit.h" |
9 | 9 | #include "src/math/powf16.h" |
10 | 10 | #include "test/UnitTest/FPMatcher.h" |
11 | 11 | #include "test/UnitTest/Test.h" |
12 | 12 | #include "utils/MPFRWrapper/MPFRUtils.h" |
13 | 13 |
|
14 | 14 | using LlvmLibcPowF16Test = LIBC_NAMESPACE::testing::FPTest<float16>; |
| 15 | +using FPBits = LIBC_NAMESPACE::fputil::FPBits<float16>; |
15 | 16 |
|
16 | 17 | namespace mpfr = LIBC_NAMESPACE::testing::mpfr; |
17 | 18 |
|
18 | 19 | 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}; |
31 | 62 | 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); |
33 | 64 | } |
34 | 65 | } |
35 | 66 | } |
36 | 67 |
|
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}; |
45 | 109 | 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); |
47 | 111 | } |
48 | 112 | } |
49 | 113 | } |
0 commit comments