@@ -197,12 +197,26 @@ LLVM_LIBC_FUNCTION(double, asin, (double x)) {
197197 r0.lo - PI_OVER_TWO.lo );
198198 double r_lo = fputil::multiply_add (vh, -p, lo);
199199
200+ // Maintaining the sign:
201+ constexpr double SIGN[2 ] = {1.0 , -1.0 };
202+ double x_sign = SIGN[xbits.is_neg ()];
203+
200204#ifdef LIBC_MATH_HAS_SKIP_ACCURATE_PASS
205+ return fputil::multiply_add (x_sign, r.hi , x_sign * r.lo );
201206#else
202207 // Ziv's accuracy test.
203208
209+ #ifdef LIBC_TARGET_CPU_HAS_FMA_DOUBLE
210+ double r_upper = fputil::multiply_add (
211+ r.hi , x_sign, fputil::multiply_add (r_lo, x_sign, err));
212+ double r_lower = fputil::multiply_add (
213+ r.hi , x_sign, fputil::multiply_add (r_lo, x_sign, -err));
214+ #else
215+ r_lo *= x_sign;
216+ r.hi *= x_sign;
204217 double r_upper = r.hi + (r_lo + err);
205218 double r_lower = r.hi + (r_lo - err);
219+ #endif // LIBC_TARGET_CPU_HAS_FMA_DOUBLE
206220
207221 if (LIBC_LIKELY (r_upper == r_lower))
208222 return r_upper;
@@ -250,6 +264,9 @@ LLVM_LIBC_FUNCTION(double, asin, (double x)) {
250264 Float128 r0_f128 = fputil::quick_mul (m_v, p_f128);
251265 Float128 r_f128 = fputil::quick_add (PI_OVER_TWO_F128, r0_f128);
252266
267+ if (xbits.is_neg ())
268+ r_f128.sign = Sign::NEG;
269+
253270 return static_cast <double >(r_f128);
254271#endif // LIBC_MATH_HAS_SKIP_ACCURATE_PASS
255272}
0 commit comments