Skip to content

Commit 232b431

Browse files
committed
Merge branch 'libc-math-f16sqrt-variants' into libc-math-f16sqrtf-mpfr-test
2 parents e697943 + 6e21b9d commit 232b431

File tree

23 files changed

+356
-122
lines changed

23 files changed

+356
-122
lines changed

libc/config/linux/aarch64/entrypoints.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,9 @@ if(LIBC_TYPES_HAS_FLOAT16)
509509
libc.src.math.copysignf16
510510
libc.src.math.f16divf
511511
libc.src.math.f16fmaf
512+
libc.src.math.f16sqrt
512513
libc.src.math.f16sqrtf
514+
libc.src.math.f16sqrtl
513515
libc.src.math.fabsf16
514516
libc.src.math.fdimf16
515517
libc.src.math.floorf16
@@ -560,6 +562,13 @@ if(LIBC_TYPES_HAS_FLOAT16)
560562
libc.src.math.ufromfpf16
561563
libc.src.math.ufromfpxf16
562564
)
565+
566+
if(LIBC_TYPES_HAS_FLOAT128)
567+
list(APPEND TARGET_LIBM_ENTRYPOINTS
568+
# math.h C23 mixed _Float16 and _Float128 entrypoints
569+
libc.src.math.f16sqrtf128
570+
)
571+
endif()
563572
endif()
564573

565574
if(LIBC_TYPES_HAS_FLOAT128)

libc/config/linux/x86_64/entrypoints.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,7 +541,9 @@ if(LIBC_TYPES_HAS_FLOAT16)
541541
libc.src.math.f16fma
542542
libc.src.math.f16fmaf
543543
libc.src.math.f16fmal
544+
libc.src.math.f16sqrt
544545
libc.src.math.f16sqrtf
546+
libc.src.math.f16sqrtl
545547
libc.src.math.fabsf16
546548
libc.src.math.fdimf16
547549
libc.src.math.floorf16
@@ -595,6 +597,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
595597
list(APPEND TARGET_LIBM_ENTRYPOINTS
596598
# math.h C23 mixed _Float16 and _Float128 entrypoints
597599
libc.src.math.f16fmaf128
600+
libc.src.math.f16sqrtf128
598601
)
599602
endif()
600603
endif()

libc/docs/math/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ Higher Math Functions
292292
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
293293
| fma | |check| | |check| | | | | 7.12.13.1 | F.10.10.1 |
294294
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
295-
| f16sqrt | |check| | | | N/A | | 7.12.14.6 | F.10.11 |
295+
| f16sqrt | |check| | |check| | |check| | N/A | |check| | 7.12.14.6 | F.10.11 |
296296
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
297297
| fsqrt | N/A | | | N/A | | 7.12.14.6 | F.10.11 |
298298
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+

libc/spec/stdc.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -731,7 +731,10 @@ def StdC : StandardSpec<"stdc"> {
731731

732732
GuardedFunctionSpec<"f16divf", RetValSpec<Float16Type>, [ArgSpec<FloatType>, ArgSpec<FloatType>], "LIBC_TYPES_HAS_FLOAT16">,
733733

734+
GuardedFunctionSpec<"f16sqrt", RetValSpec<Float16Type>, [ArgSpec<DoubleType>], "LIBC_TYPES_HAS_FLOAT16">,
734735
GuardedFunctionSpec<"f16sqrtf", RetValSpec<Float16Type>, [ArgSpec<FloatType>], "LIBC_TYPES_HAS_FLOAT16">,
736+
GuardedFunctionSpec<"f16sqrtl", RetValSpec<Float16Type>, [ArgSpec<LongDoubleType>], "LIBC_TYPES_HAS_FLOAT16">,
737+
GuardedFunctionSpec<"f16sqrtf128", RetValSpec<Float16Type>, [ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT16_AND_FLOAT128">,
735738
]
736739
>;
737740

libc/src/__support/FPUtil/generic/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ add_header_library(
88
libc.src.__support.common
99
libc.src.__support.CPP.bit
1010
libc.src.__support.CPP.type_traits
11+
libc.src.__support.FPUtil.dyadic_float
1112
libc.src.__support.FPUtil.fenv_impl
1213
libc.src.__support.FPUtil.fp_bits
1314
libc.src.__support.FPUtil.rounding_mode

libc/src/__support/FPUtil/generic/sqrt.h

Lines changed: 14 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
#include "src/__support/CPP/type_traits.h"
1515
#include "src/__support/FPUtil/FEnvImpl.h"
1616
#include "src/__support/FPUtil/FPBits.h"
17-
#include "src/__support/FPUtil/rounding_mode.h"
17+
#include "src/__support/FPUtil/dyadic_float.h"
1818
#include "src/__support/common.h"
1919
#include "src/__support/uint128.h"
2020

@@ -78,16 +78,14 @@ sqrt(InType x) {
7878
return x86::sqrt(x);
7979
} else {
8080
// IEEE floating points formats.
81-
using OutFPBits = typename fputil::FPBits<OutType>;
82-
using OutStorageType = typename OutFPBits::StorageType;
83-
using InFPBits = typename fputil::FPBits<InType>;
81+
using OutFPBits = FPBits<OutType>;
82+
using InFPBits = FPBits<InType>;
8483
using InStorageType = typename InFPBits::StorageType;
84+
using DyadicFloat =
85+
DyadicFloat<cpp::bit_ceil(static_cast<size_t>(InFPBits::STORAGE_LEN))>;
86+
8587
constexpr InStorageType ONE = InStorageType(1) << InFPBits::FRACTION_LEN;
8688
constexpr auto FLT_NAN = OutFPBits::quiet_nan().get_val();
87-
constexpr int EXTRA_FRACTION_LEN =
88-
InFPBits::FRACTION_LEN - OutFPBits::FRACTION_LEN;
89-
constexpr InStorageType EXTRA_FRACTION_MASK =
90-
(InStorageType(1) << EXTRA_FRACTION_LEN) - 1;
9189

9290
InFPBits bits(x);
9391

@@ -146,91 +144,19 @@ sqrt(InType x) {
146144
}
147145

148146
// We compute one more iteration in order to round correctly.
149-
bool lsb = (y & (InStorageType(1) << EXTRA_FRACTION_LEN)) !=
150-
0; // Least significant bit
151-
bool rb = false; // Round bit
152147
r <<= 2;
153-
InStorageType tmp = (y << 2) + 1;
148+
y <<= 2;
149+
InStorageType tmp = y + 1;
154150
if (r >= tmp) {
155151
r -= tmp;
156-
rb = true;
157-
}
158-
159-
bool sticky = false;
160-
161-
if constexpr (EXTRA_FRACTION_LEN > 0) {
162-
sticky = rb || (y & EXTRA_FRACTION_MASK) != 0;
163-
rb = (y & (InStorageType(1) << (EXTRA_FRACTION_LEN - 1))) != 0;
164-
}
165-
166-
// Remove hidden bit and append the exponent field.
167-
x_exp = ((x_exp >> 1) + OutFPBits::EXP_BIAS);
168-
169-
OutStorageType y_out = static_cast<OutStorageType>(
170-
((y - ONE) >> EXTRA_FRACTION_LEN) |
171-
(static_cast<OutStorageType>(x_exp) << OutFPBits::FRACTION_LEN));
172-
173-
if constexpr (EXTRA_FRACTION_LEN > 0) {
174-
if (x_exp >= OutFPBits::MAX_BIASED_EXPONENT) {
175-
switch (quick_get_round()) {
176-
case FE_TONEAREST:
177-
case FE_UPWARD:
178-
return OutFPBits::inf().get_val();
179-
default:
180-
return OutFPBits::max_normal().get_val();
181-
}
182-
}
183-
184-
if (x_exp <
185-
-OutFPBits::EXP_BIAS - OutFPBits::SIG_LEN + EXTRA_FRACTION_LEN) {
186-
switch (quick_get_round()) {
187-
case FE_UPWARD:
188-
return OutFPBits::min_subnormal().get_val();
189-
default:
190-
return OutType(0.0);
191-
}
192-
}
193-
194-
if (x_exp <= 0) {
195-
int underflow_extra_fraction_len = EXTRA_FRACTION_LEN - x_exp + 1;
196-
InStorageType underflow_extra_fraction_mask =
197-
(InStorageType(1) << underflow_extra_fraction_len) - 1;
198-
199-
rb = (y & (InStorageType(1) << (underflow_extra_fraction_len - 1))) !=
200-
0;
201-
OutStorageType subnormal_mant =
202-
static_cast<OutStorageType>(y >> underflow_extra_fraction_len);
203-
lsb = (subnormal_mant & 1) != 0;
204-
sticky = sticky || (y & underflow_extra_fraction_mask) != 0;
205-
206-
switch (quick_get_round()) {
207-
case FE_TONEAREST:
208-
if (rb && (lsb || sticky))
209-
++subnormal_mant;
210-
break;
211-
case FE_UPWARD:
212-
if (rb || sticky)
213-
++subnormal_mant;
214-
break;
215-
}
216-
217-
return cpp::bit_cast<OutType>(subnormal_mant);
218-
}
219-
}
220-
221-
switch (quick_get_round()) {
222-
case FE_TONEAREST:
223-
// Round to nearest, ties to even
224-
if (rb && (lsb || (r != 0)))
225-
++y_out;
226-
break;
227-
case FE_UPWARD:
228-
if (rb || (r != 0) || sticky)
229-
++y_out;
230-
break;
152+
// Rounding bit.
153+
y |= 1 << 1;
231154
}
155+
// Sticky bit.
156+
y |= static_cast<unsigned int>(r != 0);
232157

233-
return cpp::bit_cast<OutType>(y_out);
158+
DyadicFloat yd(Sign::POS, (x_exp >> 1) - 2 - InFPBits::FRACTION_LEN, y);
159+
return yd.template as<OutType, /*ShouldSignalExceptions=*/true>();
234160
}
235161
}
236162
}

libc/src/math/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,10 @@ add_math_entrypoint_object(f16fmaf)
106106
add_math_entrypoint_object(f16fmal)
107107
add_math_entrypoint_object(f16fmaf128)
108108

109+
add_math_entrypoint_object(f16sqrt)
109110
add_math_entrypoint_object(f16sqrtf)
111+
add_math_entrypoint_object(f16sqrtl)
112+
add_math_entrypoint_object(f16sqrtf128)
110113

111114
add_math_entrypoint_object(fabs)
112115
add_math_entrypoint_object(fabsf)

libc/src/math/f16sqrt.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//===-- Implementation header for f16sqrt -----------------------*- C++ -*-===//
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+
#ifndef LLVM_LIBC_SRC_MATH_F16SQRT_H
10+
#define LLVM_LIBC_SRC_MATH_F16SQRT_H
11+
12+
#include "src/__support/macros/properties/types.h"
13+
14+
namespace LIBC_NAMESPACE {
15+
16+
float16 f16sqrt(double x);
17+
18+
} // namespace LIBC_NAMESPACE
19+
20+
#endif // LLVM_LIBC_SRC_MATH_F16SQRT_H

libc/src/math/f16sqrtf128.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//===-- Implementation header for f16sqrtf128 -------------------*- C++ -*-===//
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+
#ifndef LLVM_LIBC_SRC_MATH_F16SQRTF128_H
10+
#define LLVM_LIBC_SRC_MATH_F16SQRTF128_H
11+
12+
#include "src/__support/macros/properties/types.h"
13+
14+
namespace LIBC_NAMESPACE {
15+
16+
float16 f16sqrtf128(float128 x);
17+
18+
} // namespace LIBC_NAMESPACE
19+
20+
#endif // LLVM_LIBC_SRC_MATH_F16SQRTF128_H

libc/src/math/f16sqrtl.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//===-- Implementation header for f16sqrtl ----------------------*- C++ -*-===//
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+
#ifndef LLVM_LIBC_SRC_MATH_F16SQRTL_H
10+
#define LLVM_LIBC_SRC_MATH_F16SQRTL_H
11+
12+
#include "src/__support/macros/properties/types.h"
13+
14+
namespace LIBC_NAMESPACE {
15+
16+
float16 f16sqrtl(long double x);
17+
18+
} // namespace LIBC_NAMESPACE
19+
20+
#endif // LLVM_LIBC_SRC_MATH_F16SQRTL_H

0 commit comments

Comments
 (0)