Skip to content

Commit b576429

Browse files
authored
[libc][math] Refactor tanpif to header only (llvm#181525)
Part of llvm#147386
1 parent 1cb8645 commit b576429

9 files changed

Lines changed: 177 additions & 104 deletions

File tree

libc/shared/math.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,5 +137,6 @@
137137
#include "math/tanf16.h"
138138
#include "math/tanhf.h"
139139
#include "math/tanhf16.h"
140+
#include "math/tanpif.h"
140141

141142
#endif // LLVM_LIBC_SHARED_MATH_H

libc/shared/math/tanpif.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//===-- Shared tanpif 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_TANPIF_H
10+
#define LLVM_LIBC_SHARED_MATH_TANPIF_H
11+
12+
#include "shared/libc_common.h"
13+
#include "src/__support/math/tanpif.h"
14+
15+
namespace LIBC_NAMESPACE_DECL {
16+
namespace shared {
17+
18+
using math::tanpif;
19+
20+
} // namespace shared
21+
} // namespace LIBC_NAMESPACE_DECL
22+
23+
#endif // LLVM_LIBC_SHARED_MATH_TANPIF_H

libc/src/__support/math/CMakeLists.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1941,3 +1941,19 @@ add_header_library(
19411941
libc.src.__support.macros.optimization
19421942
libc.include.llvm-libc-macros.float16_macros
19431943
)
1944+
1945+
add_header_library(
1946+
tanpif
1947+
HDRS
1948+
tanpif.h
1949+
DEPENDS
1950+
.sincosf16_utils
1951+
libc.src.__support.FPUtil.fenv_impl
1952+
libc.src.__support.FPUtil.fp_bits
1953+
libc.src.__support.FPUtil.cast
1954+
libc.src.__support.FPUtil.except_value_utils
1955+
libc.src.__support.FPUtil.multiply_add
1956+
libc.src.__support.common
1957+
libc.src.__support.macros.config
1958+
libc.src.__support.macros.optimization
1959+
)

libc/src/__support/math/tanpif.h

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
//===-- Single-precision tanpi function -----------------------------------===//
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_TANPIF_H
10+
#define LLVM_LIBC_SRC___SUPPORT_MATH_TANPIF_H
11+
12+
#include "sincosf_utils.h"
13+
#include "src/__support/FPUtil/FEnvImpl.h"
14+
#include "src/__support/FPUtil/FPBits.h"
15+
#include "src/__support/FPUtil/cast.h"
16+
#include "src/__support/FPUtil/except_value_utils.h"
17+
#include "src/__support/FPUtil/multiply_add.h"
18+
#include "src/__support/common.h"
19+
#include "src/__support/macros/config.h"
20+
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
21+
22+
namespace LIBC_NAMESPACE_DECL {
23+
24+
namespace math {
25+
26+
LIBC_INLINE float tanpif(float x) {
27+
using namespace sincosf_utils_internal;
28+
29+
using FPBits = typename fputil::FPBits<float>;
30+
FPBits xbits(x);
31+
32+
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
33+
constexpr size_t N_EXCEPTS = 3;
34+
constexpr fputil::ExceptValues<float, N_EXCEPTS> TANPIF_EXCEPTS{{
35+
// (input, RZ output, RU offset, RD offset, RN offset)
36+
{0x38F26685, 0x39BE6182, 1, 0, 0},
37+
{0x3E933802, 0x3FA267DD, 1, 0, 0},
38+
{0x3F3663FF, 0xBFA267DD, 0, 1, 0},
39+
}};
40+
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
41+
42+
uint32_t x_u = xbits.uintval();
43+
uint32_t x_abs = x_u & 0x7fff'ffffU;
44+
double xd = static_cast<double>(xbits.get_val());
45+
46+
// Handle exceptional values
47+
if (LIBC_UNLIKELY(x_abs <= 0x3F3663FF)) {
48+
if (LIBC_UNLIKELY(x_abs == 0U))
49+
return x;
50+
51+
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
52+
bool x_sign = x_u >> 31;
53+
54+
if (auto r = TANPIF_EXCEPTS.lookup_odd(x_abs, x_sign);
55+
LIBC_UNLIKELY(r.has_value()))
56+
return r.value();
57+
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
58+
}
59+
60+
// Numbers greater or equal to 2^23 are always integers, or infinity, or NaN
61+
if (LIBC_UNLIKELY(x_abs >= 0x4B00'0000)) {
62+
// x is inf or NaN.
63+
if (LIBC_UNLIKELY(x_abs >= 0x7f80'0000U)) {
64+
if (xbits.is_signaling_nan()) {
65+
fputil::raise_except_if_required(FE_INVALID);
66+
return FPBits::quiet_nan().get_val();
67+
}
68+
69+
if (x_abs == 0x7f80'0000U) {
70+
fputil::set_errno_if_required(EDOM);
71+
fputil::raise_except_if_required(FE_INVALID);
72+
}
73+
74+
return x + FPBits::quiet_nan().get_val();
75+
}
76+
77+
return FPBits::zero(xbits.sign()).get_val();
78+
}
79+
80+
// Range reduction:
81+
// For |x| > 1/32, we perform range reduction as follows:
82+
// Find k and y such that:
83+
// x = (k + y) * 1/32
84+
// k is an integer
85+
// |y| < 0.5
86+
//
87+
// This is done by performing:
88+
// k = round(x * 32)
89+
// y = x * 32 - k
90+
//
91+
// Once k and y are computed, we then deduce the answer by the formula:
92+
// tan(x) = sin(x) / cos(x)
93+
// = (sin_y * cos_k + cos_y * sin_k) / (cos_y * cos_k - sin_y * sin_k)
94+
double sin_k, cos_k, sin_y, cosm1_y;
95+
sincospif_eval(xd, sin_k, cos_k, sin_y, cosm1_y);
96+
97+
if (LIBC_UNLIKELY(sin_y == 0 && cos_k == 0)) {
98+
fputil::set_errno_if_required(EDOM);
99+
fputil::raise_except_if_required(FE_DIVBYZERO);
100+
101+
int32_t x_mp5_i = static_cast<int32_t>(xd - 0.5);
102+
return FPBits::inf((x_mp5_i & 0x1) ? Sign::NEG : Sign::POS).get_val();
103+
}
104+
105+
using fputil::multiply_add;
106+
return fputil::cast<float>(
107+
multiply_add(sin_y, cos_k, multiply_add(cosm1_y, sin_k, sin_k)) /
108+
multiply_add(sin_y, -sin_k, multiply_add(cosm1_y, cos_k, cos_k)));
109+
}
110+
111+
} // namespace math
112+
113+
} // namespace LIBC_NAMESPACE_DECL
114+
115+
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_TANPIF_H

libc/src/math/generic/CMakeLists.txt

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -463,12 +463,7 @@ add_entrypoint_object(
463463
HDRS
464464
../tanpif.h
465465
DEPENDS
466-
libc.src.__support.math.sincosf_utils
467-
libc.src.__support.FPUtil.except_value_utils
468-
libc.src.__support.FPUtil.fenv_impl
469-
libc.src.__support.FPUtil.fp_bits
470-
libc.src.__support.FPUtil.multiply_add
471-
libc.src.__support.macros.optimization
466+
libc.src.__support.math.tanpif
472467
)
473468

474469
add_entrypoint_object(

libc/src/math/generic/tanpif.cpp

Lines changed: 2 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -7,101 +7,10 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "src/math/tanpif.h"
10-
#include "src/__support/FPUtil/FEnvImpl.h"
11-
#include "src/__support/FPUtil/FPBits.h"
12-
#include "src/__support/FPUtil/cast.h"
13-
#include "src/__support/FPUtil/except_value_utils.h"
14-
#include "src/__support/FPUtil/multiply_add.h"
15-
#include "src/__support/common.h"
16-
#include "src/__support/macros/config.h"
17-
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
18-
#include "src/__support/math/sincosf_utils.h"
10+
#include "src/__support/math/tanpif.h"
1911

2012
namespace LIBC_NAMESPACE_DECL {
2113

22-
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
23-
constexpr size_t N_EXCEPTS = 3;
24-
25-
constexpr fputil::ExceptValues<float, N_EXCEPTS> TANPIF_EXCEPTS{{
26-
// (input, RZ output, RU offset, RD offset, RN offset)
27-
{0x38F26685, 0x39BE6182, 1, 0, 0},
28-
{0x3E933802, 0x3FA267DD, 1, 0, 0},
29-
{0x3F3663FF, 0xBFA267DD, 0, 1, 0},
30-
}};
31-
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
32-
33-
LLVM_LIBC_FUNCTION(float, tanpif, (float x)) {
34-
using namespace math::sincosf_utils_internal;
35-
using FPBits = typename fputil::FPBits<float>;
36-
FPBits xbits(x);
37-
38-
uint32_t x_u = xbits.uintval();
39-
uint32_t x_abs = x_u & 0x7fff'ffffU;
40-
double xd = static_cast<double>(xbits.get_val());
41-
42-
// Handle exceptional values
43-
if (LIBC_UNLIKELY(x_abs <= 0x3F3663FF)) {
44-
if (LIBC_UNLIKELY(x_abs == 0U))
45-
return x;
46-
47-
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
48-
bool x_sign = x_u >> 31;
49-
50-
if (auto r = TANPIF_EXCEPTS.lookup_odd(x_abs, x_sign);
51-
LIBC_UNLIKELY(r.has_value()))
52-
return r.value();
53-
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
54-
}
55-
56-
// Numbers greater or equal to 2^23 are always integers, or infinity, or NaN
57-
if (LIBC_UNLIKELY(x_abs >= 0x4B00'0000)) {
58-
// x is inf or NaN.
59-
if (LIBC_UNLIKELY(x_abs >= 0x7f80'0000U)) {
60-
if (xbits.is_signaling_nan()) {
61-
fputil::raise_except_if_required(FE_INVALID);
62-
return FPBits::quiet_nan().get_val();
63-
}
64-
65-
if (x_abs == 0x7f80'0000U) {
66-
fputil::set_errno_if_required(EDOM);
67-
fputil::raise_except_if_required(FE_INVALID);
68-
}
69-
70-
return x + FPBits::quiet_nan().get_val();
71-
}
72-
73-
return FPBits::zero(xbits.sign()).get_val();
74-
}
75-
76-
// Range reduction:
77-
// For |x| > 1/32, we perform range reduction as follows:
78-
// Find k and y such that:
79-
// x = (k + y) * 1/32
80-
// k is an integer
81-
// |y| < 0.5
82-
//
83-
// This is done by performing:
84-
// k = round(x * 32)
85-
// y = x * 32 - k
86-
//
87-
// Once k and y are computed, we then deduce the answer by the formula:
88-
// tan(x) = sin(x) / cos(x)
89-
// = (sin_y * cos_k + cos_y * sin_k) / (cos_y * cos_k - sin_y * sin_k)
90-
double sin_k, cos_k, sin_y, cosm1_y;
91-
sincospif_eval(xd, sin_k, cos_k, sin_y, cosm1_y);
92-
93-
if (LIBC_UNLIKELY(sin_y == 0 && cos_k == 0)) {
94-
fputil::set_errno_if_required(EDOM);
95-
fputil::raise_except_if_required(FE_DIVBYZERO);
96-
97-
int32_t x_mp5_i = static_cast<int32_t>(xd - 0.5);
98-
return FPBits::inf((x_mp5_i & 0x1) ? Sign::NEG : Sign::POS).get_val();
99-
}
100-
101-
using fputil::multiply_add;
102-
return fputil::cast<float>(
103-
multiply_add(sin_y, cos_k, multiply_add(cosm1_y, sin_k, sin_k)) /
104-
multiply_add(sin_y, -sin_k, multiply_add(cosm1_y, cos_k, cos_k)));
105-
}
14+
LLVM_LIBC_FUNCTION(float, tanpif, (float x)) { return math::tanpif(x); }
10615

10716
} // namespace LIBC_NAMESPACE_DECL

libc/test/shared/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,4 +134,5 @@ add_fp_unittest(
134134
libc.src.__support.math.tanf16
135135
libc.src.__support.math.tanhf
136136
libc.src.__support.math.tanhf16
137+
libc.src.__support.math.tanpif
137138
)

libc/test/shared/shared_math_test.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ TEST(LlvmLibcSharedMathTest, AllFloat) {
137137
EXPECT_FP_EQ(0.0f, LIBC_NAMESPACE::shared::sqrtf(0.0f));
138138
EXPECT_FP_EQ(0.0f, LIBC_NAMESPACE::shared::tanf(0.0f));
139139
EXPECT_FP_EQ(0.0f, LIBC_NAMESPACE::shared::tanhf(0.0f));
140+
EXPECT_FP_EQ(0.0f, LIBC_NAMESPACE::shared::tanpif(0.0f));
140141

141142
float canonicalizef_cx = 0.0f;
142143
float canonicalizef_x = 0.0f;

utils/bazel/llvm-project-overlay/libc/BUILD.bazel

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4137,6 +4137,22 @@ libc_support_library(
41374137
],
41384138
)
41394139

4140+
libc_support_library(
4141+
name = "__support_math_tanpif",
4142+
hdrs = ["src/__support/math/tanpif.h"],
4143+
deps = [
4144+
":__support_common",
4145+
":__support_fputil_cast",
4146+
":__support_fputil_except_value_utils",
4147+
":__support_fputil_fenv_impl",
4148+
":__support_fputil_fp_bits",
4149+
":__support_fputil_multiply_add",
4150+
":__support_macros_config",
4151+
":__support_macros_optimization",
4152+
":__support_sincosf_utils",
4153+
],
4154+
)
4155+
41404156
############################### complex targets ################################
41414157

41424158
libc_function(
@@ -5690,11 +5706,7 @@ libc_math_function(
56905706
libc_math_function(
56915707
name = "tanpif",
56925708
additional_deps = [
5693-
":__support_sincosf_utils",
5694-
":hdr_fenv_macros",
5695-
":__support_macros_config",
5696-
":__support_macros_optimization",
5697-
":__support_fputil_multiply_add",
5709+
":__support_math_tanpif",
56985710
],
56995711
)
57005712

0 commit comments

Comments
 (0)