fix(libc): keep the acosf result and leave errno unchanged

The previous commit replaced the out-of-range result with the default
quiet NaN 0x7fc00000, but main and FreeBSD e_acosf.c return 0xffc00000.

acosf now calls the host and restores errno, so only errno differs from
main. The guest test pins the result bits for 2.0f and -2.0f and keeps
the in-range case acosf(0.5f).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Alex 2026-10-11 11:42:42 -04:00 committed by Adrià Franch
parent 64e244eb70
commit 988d304c5c
2 changed files with 7 additions and 10 deletions

View File

@ -183,11 +183,10 @@ float APS5_VABI asinf_nid_postfix(float x) {
return result;
}
float APS5_VABI acosf_nid_postfix(float x) {
if (x < -1.0f || x > 1.0f) {
std::feraiseexcept(FE_INVALID);
return std::numeric_limits<float>::quiet_NaN();
}
return std::acos(x);
const int saved_errno = errno;
const float result = std::acos(x);
errno = saved_errno;
return result;
}
float APS5_VABI atan2f_nid_postfix(float y, float x) { return std::atan2(y, x); }
float APS5_VABI hypotf_nid_postfix(float x, float y) { return static_cast<float>(std::hypot(static_cast<double>(x), static_cast<double>(y))); }

View File

@ -216,13 +216,11 @@ static void CheckPowfSpecialValue() {
static void CheckAcosfErrno() {
errno = 0;
(void)acosf_nid_postfix(2.0f);
Require(std::bit_cast<std::uint32_t>(acosf_nid_postfix(2.0f)) == 0xffc00000u);
Require(errno == 0);
errno = 0;
(void)acosf_nid_postfix(-2.0f);
Require(std::bit_cast<std::uint32_t>(acosf_nid_postfix(-2.0f)) == 0xffc00000u);
Require(errno == 0);
errno = 0;
(void)acosf_nid_postfix(0.5f);
Require(std::bit_cast<std::uint32_t>(acosf_nid_postfix(0.5f)) == 0x3f860a92u);
Require(errno == 0);
}