-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[libc][math][c23] Add hypotf16 function #131991
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 9 commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
08792d3
Add hypotf16() function
meltq 483ce41
Formatting changes
meltq 67d93c8
Temp removed exhaustive
meltq 3395a6f
Formatting changes
meltq 916c5ec
Add normal and subnormal tests
meltq 55d58c1
Add 1 to round up STEP for subnormal
meltq c6970d6
Added hard to round, formatting
meltq 66514de
Formatting changes
meltq 862e069
Added increment, cleanup
meltq 0677b19
Added perf test
meltq 22dc48f
formatting changes
meltq 399e5ff
Replace fputil::cast with static_cast
meltq 24c5d78
Removed hard to round cases
meltq ec505e5
Added negative exhaustive test
meltq a83e0b1
Add explicit casts in Hypot
meltq d4a6b4f
Add back fputil::cast
meltq ee41748
Add comments regarding potential slow down
meltq f72c7f2
Formatting changes
meltq 97a05b0
Formatting changes
meltq 0f694e1
Use static_cast
meltq 668199d
Formatting changes
meltq File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
//===-- Implementation of hypotf16 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/hypotf16.h" | ||
#include "src/__support/FPUtil/FEnvImpl.h" | ||
#include "src/__support/FPUtil/FPBits.h" | ||
#include "src/__support/FPUtil/cast.h" | ||
#include "src/__support/FPUtil/multiply_add.h" | ||
#include "src/__support/FPUtil/sqrt.h" | ||
#include "src/__support/common.h" | ||
#include "src/__support/macros/optimization.h" | ||
#include "src/__support/macros/properties/types.h" | ||
|
||
namespace LIBC_NAMESPACE_DECL { | ||
|
||
LLVM_LIBC_FUNCTION(float16, hypotf16, (float16 x, float16 y)) { | ||
using FloatBits = fputil::FPBits<float>; | ||
using FPBits = fputil::FPBits<float16>; | ||
|
||
FPBits x_abs = FPBits(x).abs(); | ||
FPBits y_abs = FPBits(y).abs(); | ||
|
||
bool x_abs_larger = x_abs.uintval() >= y_abs.uintval(); | ||
|
||
FPBits a_bits = x_abs_larger ? x_abs : y_abs; | ||
FPBits b_bits = x_abs_larger ? y_abs : x_abs; | ||
|
||
uint16_t a_u = a_bits.uintval(); | ||
uint16_t b_u = b_bits.uintval(); | ||
|
||
// Note: replacing `a_u >= FPBits::EXP_MASK` with `a_bits.is_inf_or_nan()` | ||
// generates extra exponent bit masking instructions on x86-64. | ||
if (LIBC_UNLIKELY(a_u >= FPBits::EXP_MASK)) { | ||
// x or y is inf or nan | ||
if (a_bits.is_signaling_nan() || b_bits.is_signaling_nan()) { | ||
fputil::raise_except_if_required(FE_INVALID); | ||
return FPBits::quiet_nan().get_val(); | ||
} | ||
if (a_bits.is_inf() || b_bits.is_inf()) | ||
return FPBits::inf().get_val(); | ||
return a_bits.get_val(); | ||
} | ||
|
||
if (LIBC_UNLIKELY(a_u - b_u >= | ||
static_cast<uint16_t>((FPBits::FRACTION_LEN + 2) | ||
<< FPBits::FRACTION_LEN))) | ||
return x_abs.get_val() + y_abs.get_val(); | ||
|
||
float af = fputil::cast<float>(a_bits.get_val()); | ||
float bf = fputil::cast<float>(b_bits.get_val()); | ||
|
||
// These squares are exact. | ||
float a_sq = af * af; | ||
float sum_sq = fputil::multiply_add(bf, bf, a_sq); | ||
|
||
FloatBits result(fputil::sqrt<float>(sum_sq)); | ||
uint32_t r_u = result.uintval(); | ||
|
||
// If any of the sticky bits of the result are non-zero, except the LSB, then | ||
// the rounded result is correct. | ||
if (LIBC_UNLIKELY(((r_u + 1) & 0x0000'0FFE) == 0)) { | ||
float r_d = result.get_val(); | ||
|
||
// Perform rounding correction. | ||
float sum_sq_lo = fputil::multiply_add(bf, bf, a_sq - sum_sq); | ||
float err = sum_sq_lo - fputil::multiply_add(r_d, r_d, -sum_sq); | ||
|
||
if (err > 0) { | ||
r_u |= 1; | ||
} else if ((err < 0) && (r_u & 1) == 0) { | ||
r_u -= 1; | ||
} else if ((r_u & 0x0000'1FFF) == 0) { | ||
// The rounded result is exact. | ||
fputil::clear_except_if_required(FE_INEXACT); | ||
} | ||
return fputil::cast<float16>(FloatBits(r_u).get_val()); | ||
} | ||
|
||
return fputil::cast<float16>(result.get_val()); | ||
} | ||
|
||
} // namespace LIBC_NAMESPACE_DECL |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
//===-- Implementation header for hypotf16 ----------------------*- 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_HYPOTF16_H | ||
#define LLVM_LIBC_SRC_MATH_HYPOTF16_H | ||
|
||
#include "src/__support/macros/config.h" | ||
#include "src/__support/macros/properties/types.h" | ||
|
||
namespace LIBC_NAMESPACE_DECL { | ||
|
||
float16 hypotf16(float16 x, float16 y); | ||
|
||
} // namespace LIBC_NAMESPACE_DECL | ||
|
||
#endif // LLVM_LIBC_SRC_MATH_HYPOTF16_H |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
//===-- Exhaustive test for hypotf16 --------------------------------------===// | ||
// | ||
// 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 "exhaustive_test.h" | ||
#include "src/__support/FPUtil/FPBits.h" | ||
#include "src/__support/FPUtil/Hypot.h" | ||
#include "src/math/hypotf16.h" | ||
#include "test/UnitTest/FPMatcher.h" | ||
#include "utils/MPFRWrapper/MPFRUtils.h" | ||
|
||
namespace mpfr = LIBC_NAMESPACE::testing::mpfr; | ||
|
||
// Range of both inputs: [0, inf] | ||
static constexpr uint16_t START = 0x0000U; | ||
static constexpr uint16_t STOP = 0x7C00U; | ||
|
||
struct Hypotf16Checker : public virtual LIBC_NAMESPACE::testing::Test { | ||
using FloatType = float16; | ||
using FPBits = LIBC_NAMESPACE::fputil::FPBits<float16>; | ||
using StorageType = typename FPBits::StorageType; | ||
|
||
uint64_t check(uint16_t start, uint16_t stop, mpfr::RoundingMode rounding) { | ||
mpfr::ForceRoundingMode r(rounding); | ||
if (!r.success) | ||
return true; | ||
uint16_t xbits = start; | ||
uint64_t failed = 0; | ||
do { | ||
float16 x = FPBits(xbits).get_val(); | ||
uint16_t ybits = xbits; | ||
do { | ||
float16 y = FPBits(ybits).get_val(); | ||
bool correct = TEST_FP_EQ(LIBC_NAMESPACE::fputil::hypot(x, y), | ||
meltq marked this conversation as resolved.
Show resolved
Hide resolved
|
||
LIBC_NAMESPACE::hypotf16(x, y)); | ||
// Using MPFR will be much slower. | ||
meltq marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// mpfr::BinaryInput<float16> input{x, y}; | ||
// bool correct = TEST_MPFR_MATCH_ROUNDING_SILENTLY( | ||
// mpfr::Operation::Hypot, input, LIBC_NAMESPACE::hypotf16(x, y), | ||
// 0.5, | ||
// rounding); | ||
failed += (!correct); | ||
} while (ybits++ < STOP); | ||
} while (xbits++ < stop); | ||
return failed; | ||
} | ||
}; | ||
|
||
using LlvmLibcHypotf16ExhaustiveTest = | ||
LlvmLibcExhaustiveMathTest<Hypotf16Checker, 1 << 2>; | ||
|
||
TEST_F(LlvmLibcHypotf16ExhaustiveTest, PositiveRange) { | ||
test_full_range_all_roundings(START, STOP); | ||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.