Skip to content

Commit 80f9c72

Browse files
authored
[libc][math][c23] Add rsqrtf16() function (llvm#137545)
Addresses llvm#132818 Part of llvm#95250
1 parent 562fe41 commit 80f9c72

File tree

24 files changed

+330
-2
lines changed

24 files changed

+330
-2
lines changed

libc/config/linux/aarch64/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -735,6 +735,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
735735
libc.src.math.rintf16
736736
libc.src.math.roundevenf16
737737
libc.src.math.roundf16
738+
libc.src.math.rsqrtf16
738739
libc.src.math.scalblnf16
739740
libc.src.math.scalbnf16
740741
libc.src.math.setpayloadf16

libc/config/linux/riscv/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
749749
libc.src.math.rintf16
750750
libc.src.math.roundevenf16
751751
libc.src.math.roundf16
752+
libc.src.math.rsqrtf16
752753
libc.src.math.scalblnf16
753754
libc.src.math.scalbnf16
754755
libc.src.math.setpayloadf16

libc/config/linux/x86_64/entrypoints.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -784,6 +784,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
784784
libc.src.math.rintf16
785785
libc.src.math.roundevenf16
786786
libc.src.math.roundf16
787+
libc.src.math.rsqrtf16
787788
libc.src.math.scalblnf16
788789
libc.src.math.scalbnf16
789790
libc.src.math.setpayloadf16

libc/docs/headers/math/index.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ Basic Operations
255255
Higher Math Functions
256256
=====================
257257

258+
258259
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+----------++------------+------------------------+----------------------------+
259260
| <Func> | <Func_f> (float) | <Func> (double) | <Func_l> (long double) | <Func_f16> (float16) | <Func_f128> (float128) | <Func_bf16> (bfloat16) | C23 Definition Section | C23 Error Handling Section |
260261
+===========+==================+=================+========================+======================+========================+========================+========================+============================+
@@ -342,7 +343,7 @@ Higher Math Functions
342343
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
343344
| rootn | | | | | | | 7.12.7.8 | F.10.4.8 |
344345
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
345-
| rsqrt | | | | | | | 7.12.7.9 | F.10.4.9 |
346+
| rsqrt | | | | |check| | | | 7.12.7.9 | F.10.4.9 |
346347
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
347348
| sin | |check| | |check| | | |check| | | | 7.12.4.6 | F.10.1.6 |
348349
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
@@ -363,6 +364,7 @@ Higher Math Functions
363364
| tgamma | | | | | | | 7.12.8.4 | F.10.5.4 |
364365
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+------------------------+----------------------------+
365366

367+
366368
Legends:
367369

368370
* |check| : correctly rounded for all 4 rounding modes.

libc/include/math.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2349,6 +2349,13 @@ functions:
23492349
return_type: long double
23502350
arguments:
23512351
- type: long double
2352+
- name: rsqrtf16
2353+
standards:
2354+
- stdc
2355+
return_type: _Float16
2356+
arguments:
2357+
- type: _Float16
2358+
guard: LIBC_TYPES_HAS_FLOAT16
23522359
- name: scalbln
23532360
standards:
23542361
- stdc

libc/shared/math.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,6 @@
5353
#include "math/ldexpf128.h"
5454
#include "math/ldexpf16.h"
5555

56+
#include "math/rsqrtf16.h"
57+
5658
#endif // LLVM_LIBC_SHARED_MATH_H

libc/shared/math/rsqrtf16.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//===-- Shared rsqrtf16 function -------------------------------*- 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_SHARED_MATH_RSQRTF16_H
10+
#define LLVM_LIBC_SHARED_MATH_RSQRTF16_H
11+
12+
#include "include/llvm-libc-macros/float16-macros.h"
13+
14+
#ifdef LIBC_TYPES_HAS_FLOAT16
15+
16+
#include "shared/libc_common.h"
17+
#include "src/__support/math/rsqrtf16.h"
18+
19+
namespace LIBC_NAMESPACE_DECL {
20+
namespace shared {
21+
22+
using math::rsqrtf16;
23+
24+
} // namespace shared
25+
} // namespace LIBC_NAMESPACE_DECL
26+
27+
#endif // LIBC_TYPES_HAS_FLOAT16
28+
29+
#endif // LLVM_LIBC_SHARED_MATH_RSQRTF16_H

libc/src/__support/math/CMakeLists.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,22 @@ add_header_library(
109109
libc.src.__support.macros.properties.types
110110
)
111111

112+
113+
add_header_library(
114+
rsqrtf16
115+
HDRS
116+
rsqrtf16.h
117+
DEPENDS
118+
libc.src.__support.FPUtil.cast
119+
libc.src.__support.FPUtil.fenv_impl
120+
libc.src.__support.FPUtil.fp_bits
121+
libc.src.__support.FPUtil.multiply_add
122+
libc.src.__support.FPUtil.polyeval
123+
libc.src.__support.FPUtil.manipulation_functions
124+
libc.src.__support.macros.optimization
125+
libc.src.__support.macros.properties.types
126+
)
127+
112128
add_header_library(
113129
asin_utils
114130
HDRS

libc/src/__support/math/rsqrtf16.h

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
//===-- Implementation header for rsqrtf16 ----------------------*- 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___SUPPORT_MATH_RSQRTF16_H
10+
#define LLVM_LIBC_SRC___SUPPORT_MATH_RSQRTF16_H
11+
12+
#include "include/llvm-libc-macros/float16-macros.h"
13+
14+
#ifdef LIBC_TYPES_HAS_FLOAT16
15+
16+
#include "src/__support/FPUtil/FEnvImpl.h"
17+
#include "src/__support/FPUtil/FPBits.h"
18+
#include "src/__support/FPUtil/ManipulationFunctions.h"
19+
#include "src/__support/FPUtil/cast.h"
20+
#include "src/__support/FPUtil/multiply_add.h"
21+
#include "src/__support/FPUtil/sqrt.h"
22+
#include "src/__support/macros/optimization.h"
23+
24+
namespace LIBC_NAMESPACE_DECL {
25+
namespace math {
26+
27+
LIBC_INLINE static constexpr float16 rsqrtf16(float16 x) {
28+
using FPBits = fputil::FPBits<float16>;
29+
FPBits xbits(x);
30+
31+
const uint16_t x_u = xbits.uintval();
32+
const uint16_t x_abs = x_u & 0x7fff;
33+
const uint16_t x_sign = x_u >> 15;
34+
35+
// x is NaN
36+
if (LIBC_UNLIKELY(xbits.is_nan())) {
37+
if (xbits.is_signaling_nan()) {
38+
fputil::raise_except_if_required(FE_INVALID);
39+
return FPBits::quiet_nan().get_val();
40+
}
41+
return x;
42+
}
43+
44+
// |x| = 0
45+
if (LIBC_UNLIKELY(x_abs == 0x0)) {
46+
fputil::raise_except_if_required(FE_DIVBYZERO);
47+
fputil::set_errno_if_required(ERANGE);
48+
return FPBits::inf(Sign::POS).get_val();
49+
}
50+
51+
// -inf <= x < 0
52+
if (LIBC_UNLIKELY(x_sign == 1)) {
53+
fputil::raise_except_if_required(FE_INVALID);
54+
fputil::set_errno_if_required(EDOM);
55+
return FPBits::quiet_nan().get_val();
56+
}
57+
58+
// x = +inf => rsqrt(x) = 0
59+
if (LIBC_UNLIKELY(xbits.is_inf()))
60+
return FPBits::zero().get_val();
61+
62+
// TODO: add integer based implementation when LIBC_TARGET_CPU_HAS_FPU_FLOAT
63+
// is not defined
64+
float result = 1.0f / fputil::sqrt<float>(fputil::cast<float>(x));
65+
66+
// Targeted post-corrections to ensure correct rounding in half for specific
67+
// mantissa patterns
68+
const uint16_t half_mantissa = x_abs & 0x3ff;
69+
if (LIBC_UNLIKELY(half_mantissa == 0x011F)) {
70+
result = fputil::multiply_add(result, 0x1.0p-21f, result);
71+
} else if (LIBC_UNLIKELY(half_mantissa == 0x0313)) {
72+
result = fputil::multiply_add(result, -0x1.0p-21f, result);
73+
}
74+
75+
return fputil::cast<float16>(result);
76+
}
77+
78+
} // namespace math
79+
} // namespace LIBC_NAMESPACE_DECL
80+
81+
#endif // LIBC_TYPES_HAS_FLOAT16
82+
83+
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_RSQRTF16_H

libc/src/math/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,8 @@ add_math_entrypoint_object(roundevenf16)
516516
add_math_entrypoint_object(roundevenf128)
517517
add_math_entrypoint_object(roundevenbf16)
518518

519+
add_math_entrypoint_object(rsqrtf16)
520+
519521
add_math_entrypoint_object(scalbln)
520522
add_math_entrypoint_object(scalblnf)
521523
add_math_entrypoint_object(scalblnl)

0 commit comments

Comments
 (0)