Skip to content

Commit d578148

Browse files
authored
[libc][math] Skip checking for exceptional values when LIBC_MATH_SKIP_ACCURATE_PASS is set. (#130811)
1 parent c337e2d commit d578148

34 files changed

+158
-7
lines changed

libc/src/math/generic/acosf.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
namespace LIBC_NAMESPACE_DECL {
2222

23+
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
2324
static constexpr size_t N_EXCEPTS = 4;
2425

2526
// Exceptional values when |x| <= 0.5
@@ -34,6 +35,7 @@ static constexpr fputil::ExceptValues<float, N_EXCEPTS> ACOSF_EXCEPTS = {{
3435
// x = -0x1.04c444p-12, acosf(x) = 0x1.923p0 (RZ)
3536
{0xb9826222, 0x3fc91800, 1, 0, 1},
3637
}};
38+
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
3739

3840
LLVM_LIBC_FUNCTION(float, acosf, (float x)) {
3941
using FPBits = typename fputil::FPBits<float>;
@@ -51,9 +53,11 @@ LLVM_LIBC_FUNCTION(float, acosf, (float x)) {
5153
// acos(x) = pi/2 - asin(x)
5254
// ~ pi/2 - x - x^3 / 6
5355

56+
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
5457
// Check for exceptional values
5558
if (auto r = ACOSF_EXCEPTS.lookup(x_uint); LIBC_UNLIKELY(r.has_value()))
5659
return r.value();
60+
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
5761

5862
double xd = static_cast<double>(x);
5963
return static_cast<float>(fputil::multiply_add(

libc/src/math/generic/acosf16.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,15 @@ namespace LIBC_NAMESPACE_DECL {
2727
static constexpr float PI_OVER_2 = 0x1.921fb6p0f;
2828
static constexpr float PI = 0x1.921fb6p1f;
2929

30+
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
3031
static constexpr size_t N_EXCEPTS = 2;
3132

3233
static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSF16_EXCEPTS{{
3334
// (input, RZ output, RU offset, RD offset, RN offset)
3435
{0xacaf, 0x3e93, 1, 0, 0},
3536
{0xb874, 0x4052, 1, 0, 1},
3637
}};
38+
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
3739

3840
LLVM_LIBC_FUNCTION(float16, acosf16, (float16 x)) {
3941
using FPBits = fputil::FPBits<float16>;
@@ -64,9 +66,11 @@ LLVM_LIBC_FUNCTION(float16, acosf16, (float16 x)) {
6466

6567
float xf = x;
6668

69+
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
6770
// Handle exceptional values
6871
if (auto r = ACOSF16_EXCEPTS.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
6972
return r.value();
73+
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
7074

7175
// |x| == 0x1p0, x is 1 or -1
7276
// if x is (-)1, return pi, else

libc/src/math/generic/acoshf.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ namespace LIBC_NAMESPACE_DECL {
2222
LLVM_LIBC_FUNCTION(float, acoshf, (float x)) {
2323
using FPBits_t = typename fputil::FPBits<float>;
2424
FPBits_t xbits(x);
25-
uint32_t x_u = xbits.uintval();
2625

2726
if (LIBC_UNLIKELY(x <= 1.0f)) {
2827
if (x == 1.0f)
@@ -33,6 +32,8 @@ LLVM_LIBC_FUNCTION(float, acoshf, (float x)) {
3332
return FPBits_t::quiet_nan().get_val();
3433
}
3534

35+
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
36+
uint32_t x_u = xbits.uintval();
3637
if (LIBC_UNLIKELY(x_u >= 0x4f8ffb03)) {
3738
if (LIBC_UNLIKELY(xbits.is_inf_or_nan()))
3839
return x;
@@ -64,6 +65,10 @@ LLVM_LIBC_FUNCTION(float, acoshf, (float x)) {
6465
return round_result_slightly_up(0x1.451436p6f);
6566
}
6667
}
68+
#else
69+
if (LIBC_UNLIKELY(xbits.is_inf_or_nan()))
70+
return x;
71+
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
6772

6873
double x_d = static_cast<double>(x);
6974
// acosh(x) = log(x + sqrt(x^2 - 1))

libc/src/math/generic/asinf.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
namespace LIBC_NAMESPACE_DECL {
2323

24+
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
2425
static constexpr size_t N_EXCEPTS = 2;
2526

2627
// Exceptional values when |x| <= 0.5
@@ -40,6 +41,7 @@ static constexpr fputil::ExceptValues<float, N_EXCEPTS> ASINF_EXCEPTS_HI = {{
4041
// x = 0x1.ee836cp-1, asinf(x) = 0x1.4f0654p0 (RZ)
4142
{0x3f7741b6, 0x3fa7832a, 1, 0, 0},
4243
}};
44+
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
4345

4446
LLVM_LIBC_FUNCTION(float, asinf, (float x)) {
4547
using FPBits = typename fputil::FPBits<float>;
@@ -82,10 +84,12 @@ LLVM_LIBC_FUNCTION(float, asinf, (float x)) {
8284
#endif // LIBC_TARGET_CPU_HAS_FMA_FLOAT
8385
}
8486

87+
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
8588
// Check for exceptional values
8689
if (auto r = ASINF_EXCEPTS_LO.lookup_odd(x_abs, x_sign);
8790
LIBC_UNLIKELY(r.has_value()))
8891
return r.value();
92+
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
8993

9094
// For |x| <= 0.5, we approximate asinf(x) by:
9195
// asin(x) = x * P(x^2)
@@ -111,10 +115,12 @@ LLVM_LIBC_FUNCTION(float, asinf, (float x)) {
111115
return FPBits::quiet_nan().get_val();
112116
}
113117

118+
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
114119
// Check for exceptional values
115120
if (auto r = ASINF_EXCEPTS_HI.lookup_odd(x_abs, x_sign);
116121
LIBC_UNLIKELY(r.has_value()))
117122
return r.value();
123+
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
118124

119125
// When |x| > 0.5, we perform range reduction as follow:
120126
//

libc/src/math/generic/asinhf.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ LLVM_LIBC_FUNCTION(float, asinhf, (float x)) {
4949
double x_sign = SIGN[x_u >> 31];
5050
double x_d = x;
5151

52+
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
5253
// Helper functions to set results for exceptional cases.
5354
auto round_result_slightly_down = [x_sign](float r) -> float {
5455
return fputil::multiply_add(static_cast<float>(x_sign), r,
@@ -95,6 +96,10 @@ LLVM_LIBC_FUNCTION(float, asinhf, (float x)) {
9596
return round_result_slightly_down(0x1.e1b92p3f);
9697
}
9798
}
99+
#else
100+
if (LIBC_UNLIKELY(xbits.is_inf_or_nan()))
101+
return x;
102+
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
98103

99104
// asinh(x) = log(x + sqrt(x^2 + 1))
100105
return static_cast<float>(

libc/src/math/generic/cosf.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
namespace LIBC_NAMESPACE_DECL {
2222

23+
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
2324
// Exceptional cases for cosf.
2425
static constexpr size_t N_EXCEPTS = 6;
2526

@@ -38,6 +39,7 @@ static constexpr fputil::ExceptValues<float, N_EXCEPTS> COSF_EXCEPTS{{
3839
// x = 0x1.ddebdep120, cos(x) = 0x1.114438p-1 (RZ)
3940
{0x7beef5ef, 0x3f08a21c, 1, 0, 0},
4041
}};
42+
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
4143

4244
LLVM_LIBC_FUNCTION(float, cosf, (float x)) {
4345
using FPBits = typename fputil::FPBits<float>;
@@ -108,8 +110,10 @@ LLVM_LIBC_FUNCTION(float, cosf, (float x)) {
108110
#endif // LIBC_TARGET_CPU_HAS_FMA_FLOAT
109111
}
110112

113+
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
111114
if (auto r = COSF_EXCEPTS.lookup(x_abs); LIBC_UNLIKELY(r.has_value()))
112115
return r.value();
116+
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
113117

114118
// x is inf or nan.
115119
if (LIBC_UNLIKELY(x_abs >= 0x7f80'0000U)) {

libc/src/math/generic/cosf16.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
namespace LIBC_NAMESPACE_DECL {
2121

22+
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
2223
constexpr size_t N_EXCEPTS = 4;
2324

2425
constexpr fputil::ExceptValues<float16, N_EXCEPTS> COSF16_EXCEPTS{{
@@ -28,6 +29,7 @@ constexpr fputil::ExceptValues<float16, N_EXCEPTS> COSF16_EXCEPTS{{
2829
{0x5c49, 0xb8c6, 0, 1, 0},
2930
{0x7acc, 0xa474, 0, 1, 0},
3031
}};
32+
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
3133

3234
LLVM_LIBC_FUNCTION(float16, cosf16, (float16 x)) {
3335
using FPBits = fputil::FPBits<float16>;
@@ -53,9 +55,11 @@ LLVM_LIBC_FUNCTION(float16, cosf16, (float16 x)) {
5355
// = cos(k * pi/32) * cos(y * pi/32) -
5456
// sin(k * pi/32) * sin(y * pi/32)
5557

58+
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
5659
// Handle exceptional values
5760
if (auto r = COSF16_EXCEPTS.lookup(x_abs); LIBC_UNLIKELY(r.has_value()))
5861
return r.value();
62+
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
5963

6064
// cos(+/-0) = 1
6165
if (LIBC_UNLIKELY(x_abs == 0U))

libc/src/math/generic/coshf16.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
namespace LIBC_NAMESPACE_DECL {
2222

23+
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
2324
static constexpr fputil::ExceptValues<float16, 9> COSHF16_EXCEPTS_POS = {{
2425
// x = 0x1.6ap-5, coshf16(x) = 0x1p+0 (RZ)
2526
{0x29a8U, 0x3c00U, 1U, 0U, 1U},
@@ -51,6 +52,7 @@ static constexpr fputil::ExceptValues<float16, 4> COSHF16_EXCEPTS_NEG = {{
5152
// x = -0x1.5fp+3, coshf16(x) = 0x1.c54p+14 (RZ)
5253
{0xc97cU, 0x7715U, 1U, 0U, 1U},
5354
}};
55+
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
5456

5557
LLVM_LIBC_FUNCTION(float16, coshf16, (float16 x)) {
5658
using FPBits = fputil::FPBits<float16>;
@@ -89,13 +91,15 @@ LLVM_LIBC_FUNCTION(float16, coshf16, (float16 x)) {
8991
}
9092
}
9193

94+
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
9295
if (x_bits.is_pos()) {
9396
if (auto r = COSHF16_EXCEPTS_POS.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
9497
return r.value();
9598
} else {
9699
if (auto r = COSHF16_EXCEPTS_NEG.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
97100
return r.value();
98101
}
102+
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
99103

100104
return eval_sinh_or_cosh</*IsSinh=*/false>(x);
101105
}

libc/src/math/generic/erff.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ LLVM_LIBC_FUNCTION(float, erff, (float x)) {
141141
return ONE[sign] + SMALL[sign];
142142
}
143143

144+
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
144145
// Exceptional mask = common 0 bits of 2 exceptional values.
145146
constexpr uint32_t EXCEPT_MASK = 0x809a'6184U;
146147

@@ -155,6 +156,7 @@ LLVM_LIBC_FUNCTION(float, erff, (float x)) {
155156
if (x_abs == 0U)
156157
return x;
157158
}
159+
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
158160

159161
// Polynomial approximation:
160162
// erf(x) ~ x * (c0 + c1 * x^2 + c2 * x^4 + ... + c7 * x^14)

libc/src/math/generic/exp10f16.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
namespace LIBC_NAMESPACE_DECL {
2828

29+
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
2930
#ifdef LIBC_TARGET_CPU_HAS_FMA_FLOAT
3031
static constexpr size_t N_EXP10F16_EXCEPTS = 5;
3132
#else
@@ -53,6 +54,7 @@ static constexpr fputil::ExceptValues<float16, N_EXP10F16_EXCEPTS>
5354
{0x446eU, 0x7690U, 1U, 0U, 1U},
5455
#endif
5556
}};
57+
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
5658

5759
LLVM_LIBC_FUNCTION(float16, exp10f16, (float16 x)) {
5860
using FPBits = fputil::FPBits<float16>;
@@ -119,8 +121,10 @@ LLVM_LIBC_FUNCTION(float16, exp10f16, (float16 x)) {
119121
}
120122
}
121123

124+
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
122125
if (auto r = EXP10F16_EXCEPTS.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
123126
return r.value();
127+
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
124128

125129
// 10^x = 2^((hi + mid) * log2(10)) * 10^lo
126130
auto [exp2_hi_mid, exp10_lo] = exp10_range_reduction(x);

libc/src/math/generic/exp10m1f.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
namespace LIBC_NAMESPACE_DECL {
2424

25+
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
2526
static constexpr size_t N_EXCEPTS_LO = 11;
2627

2728
static constexpr fputil::ExceptValues<float, N_EXCEPTS_LO> EXP10M1F_EXCEPTS_LO =
@@ -94,6 +95,7 @@ static constexpr fputil::ExceptValues<float, N_EXCEPTS_HI> EXP10M1F_EXCEPTS_HI =
9495
// x = -0x1.ca4322p-5, exp10m1f(x) = -0x1.ef073p-4 (RZ)
9596
{0xbd65'2191U, 0xbdf7'8398U, 0U, 1U, 1U},
9697
}};
98+
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
9799

98100
LLVM_LIBC_FUNCTION(float, exp10m1f, (float x)) {
99101
using FPBits = fputil::FPBits<float>;
@@ -119,8 +121,10 @@ LLVM_LIBC_FUNCTION(float, exp10m1f, (float x)) {
119121

120122
// When |x| <= log10(2) * 2^(-6)
121123
if (LIBC_UNLIKELY(x_abs <= 0x3b9a'209bU)) {
124+
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
122125
if (auto r = EXP10M1F_EXCEPTS_LO.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
123126
return r.value();
127+
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
124128

125129
double dx = x;
126130
double dx_sq = dx * dx;
@@ -192,8 +196,10 @@ LLVM_LIBC_FUNCTION(float, exp10m1f, (float x)) {
192196
}
193197
}
194198

199+
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
195200
if (auto r = EXP10M1F_EXCEPTS_HI.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
196201
return r.value();
202+
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
197203

198204
// Range reduction: 10^x = 2^(mid + hi) * 10^lo
199205
// rr = (2^(mid + hi), lo)

libc/src/math/generic/exp10m1f16.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
namespace LIBC_NAMESPACE_DECL {
2626

27+
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
2728
static constexpr fputil::ExceptValues<float16, 3> EXP10M1F16_EXCEPTS_LO = {{
2829
// (input, RZ output, RU offset, RD offset, RN offset)
2930
// x = 0x1.5c4p-4, exp10m1f16(x) = 0x1.bacp-3 (RZ)
@@ -58,6 +59,7 @@ static constexpr fputil::ExceptValues<float16, N_EXP10M1F16_EXCEPTS_HI>
5859
{0x44bdU, 0x7aaeU, 1U, 0U, 1U},
5960
#endif
6061
}};
62+
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
6163

6264
LLVM_LIBC_FUNCTION(float16, exp10m1f16, (float16 x)) {
6365
using FPBits = fputil::FPBits<float16>;
@@ -122,9 +124,11 @@ LLVM_LIBC_FUNCTION(float16, exp10m1f16, (float16 x)) {
122124
if (LIBC_UNLIKELY(x_abs == 0))
123125
return x;
124126

127+
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
125128
if (auto r = EXP10M1F16_EXCEPTS_LO.lookup(x_u);
126129
LIBC_UNLIKELY(r.has_value()))
127130
return r.value();
131+
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
128132

129133
float xf = x;
130134
// Degree-5 minimax polynomial generated by Sollya with the following
@@ -153,8 +157,10 @@ LLVM_LIBC_FUNCTION(float16, exp10m1f16, (float16 x)) {
153157
}
154158
}
155159

160+
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
156161
if (auto r = EXP10M1F16_EXCEPTS_HI.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
157162
return r.value();
163+
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
158164

159165
// exp10(x) = exp2((hi + mid) * log2(10)) * exp10(lo)
160166
auto [exp2_hi_mid, exp10_lo] = exp10_range_reduction(x);

libc/src/math/generic/exp2f16.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
namespace LIBC_NAMESPACE_DECL {
2323

24+
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
2425
static constexpr fputil::ExceptValues<float16, 3> EXP2F16_EXCEPTS = {{
2526
// (input, RZ output, RU offset, RD offset, RN offset)
2627
// x = 0x1.714p-11, exp2f16(x) = 0x1p+0 (RZ)
@@ -30,6 +31,7 @@ static constexpr fputil::ExceptValues<float16, 3> EXP2F16_EXCEPTS = {{
3031
// x = -0x1.d5cp-4, exp2f16(x) = 0x1.d8cp-1 (RZ)
3132
{0xaf57U, 0x3b63U, 1U, 0U, 0U},
3233
}};
34+
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
3335

3436
LLVM_LIBC_FUNCTION(float16, exp2f16, (float16 x)) {
3537
using FPBits = fputil::FPBits<float16>;
@@ -82,8 +84,10 @@ LLVM_LIBC_FUNCTION(float16, exp2f16, (float16 x)) {
8284
}
8385
}
8486

87+
#ifndef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
8588
if (auto r = EXP2F16_EXCEPTS.lookup(x_u); LIBC_UNLIKELY(r.has_value()))
8689
return r.value();
90+
#endif // !LIBC_MATH_HAS_SKIP_ACCURATE_PASS
8791

8892
// exp2(x) = exp2(hi + mid) * exp2(lo)
8993
auto [exp2_hi_mid, exp2_lo] = exp2_range_reduction(x);

0 commit comments

Comments
 (0)