@@ -127,15 +127,6 @@ LLVM_LIBC_FUNCTION(float, erff, (float x)) {
127
127
uint32_t x_u = xbits.uintval ();
128
128
uint32_t x_abs = x_u & 0x7fff'ffffU ;
129
129
130
- // Exceptional values
131
- if (LIBC_UNLIKELY (x_abs == 0x3f65'9229U )) // |x| = 0x1.cb2452p-1f
132
- return x < 0 .0f ? fputil::round_result_slightly_down (-0x1 .972ea8p-1f )
133
- : fputil::round_result_slightly_up (0x1 .972ea8p-1f );
134
- if (LIBC_UNLIKELY (x_abs == 0x4004'1e6aU )) // |x| = 0x1.083cd4p+1f
135
- return x < 0 .0f ? fputil::round_result_slightly_down (-0x1 .fe3462p -1f )
136
- : fputil::round_result_slightly_up (0x1 .fe3462p -1f );
137
-
138
- // if (LIBC_UNLIKELY(x_abs > 0x407a'd444U)) {
139
130
if (LIBC_UNLIKELY (x_abs >= 0x4080'0000U )) {
140
131
const float ONE[2 ] = {1 .0f , -1 .0f };
141
132
const float SMALL[2 ] = {-0x1 .0p-25f , 0x1 .0p-25f };
@@ -149,6 +140,21 @@ LLVM_LIBC_FUNCTION(float, erff, (float x)) {
149
140
return ONE[sign] + SMALL[sign];
150
141
}
151
142
143
+ // Exceptional mask = common 0 bits of 2 exceptional values.
144
+ constexpr uint32_t EXCEPT_MASK = 0x809a'6184U ;
145
+
146
+ if (LIBC_UNLIKELY ((x_abs & EXCEPT_MASK) == 0 )) {
147
+ // Exceptional values
148
+ if (LIBC_UNLIKELY (x_abs == 0x3f65'9229U )) // |x| = 0x1.cb2452p-1f
149
+ return x < 0 .0f ? fputil::round_result_slightly_down (-0x1 .972ea8p-1f )
150
+ : fputil::round_result_slightly_up (0x1 .972ea8p-1f );
151
+ if (LIBC_UNLIKELY (x_abs == 0x4004'1e6aU )) // |x| = 0x1.083cd4p+1f
152
+ return x < 0 .0f ? fputil::round_result_slightly_down (-0x1 .fe3462p -1f )
153
+ : fputil::round_result_slightly_up (0x1 .fe3462p -1f );
154
+ if (x_abs == 0U )
155
+ return x;
156
+ }
157
+
152
158
// Polynomial approximation:
153
159
// erf(x) ~ x * (c0 + c1 * x^2 + c2 * x^4 + ... + c7 * x^14)
154
160
double xd = static_cast <double >(x);
0 commit comments