Skip to content

fix(libc): keep lgamma finite for subnormal arguments on Windows - #5775

Merged
adriadam10 merged 1 commit into
boykopovar:mainfrom
wachi35676:fix/libc-lgamma-tiny-arguments
Oct 15, 2026
Merged

adriadam10 merged 1 commit into
boykopovar:mainfrom
wachi35676:fix/libc-lgamma-tiny-arguments

Conversation

@wachi35676

Copy link
Copy Markdown
Contributor

What

lgamma_nid_postfix (core/libs/prx/libc/src/Math.cpp) forwards to the host std::lgamma. The MinGW-w64 lgamma returns +inf and raises FE_OVERFLOW for nonzero |x| at or below 2^-1024 (e.g. lgamma(0x1p-1074)), where the value is finite: -log(2^-1074) ≈ 744.44.

FreeBSD's msun handles this range explicitly before its general path (lib/msun/src/e_lgamma_r.c, releng/11.4):

if(ix<0x3c700000) {	/* |x|<2**-56, return -log(|x|) */
    if((ix|lx)==0) return one/vzero;
    return -__ieee754_log(fabs(x));
}

lgamma_nid_postfix now takes the same branch for nonzero |x| < 2^-56 and otherwise still calls the host. Zero, infinities, NaN and every |x| ≥ 2^-56 are unchanged. Compared with an unmodified FreeBSD 11.4 msun build, lgamma(±0x1p-1074) now returns the same bits (0x40874385446d71c3); for 2^-60 … 2^-1000 the host already agreed with -log|x| to the last digit.

Tested

Windows 11 26200, WinLibs GCC 15.2.0 UCRT, full build with BUILD_TESTING=ON on main eecf90953.

  • New checks in core/libs/tests/GuestMath.cpp (guest_math) for ±denorm_min, ±2^-1025, ±2^-1022 and ±2^-57, and that no FE_OVERFLOW, FE_DIVBYZERO or FE_INVALID is raised. Fails on main, passes with this change.
  • The other libc formatting, math, wide and string tests (10) pass.
  • python tools/check_conventions.py --base origin/main passes.

The new check fails on main only on Windows; glibc's lgamma already returns the finite value, so on Linux it passes before and after. Not tested: Linux and macOS builds.

Checklist

  • Based on current main; no other open PR implements the same functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw (NotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • Unblocks: none
  • GPUs tested: n/a
  • AI-assisted: yes

🤖 Generated with Claude Code

The MinGW-w64 lgamma overflows to infinity for nonzero |x| at or below 2^-1024. FreeBSD msun e_lgamma_r.c returns -log(|x|) for every nonzero |x| below 2^-56, so take that branch before the host function.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added the libc label Oct 14, 2026
@github-actions

github-actions Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.

Pull request Conflicting files (lines on main) Same exports Same new files
PR 6157 core/libs/prx/libc/src/Math.cpp L304-305
PR 6158 core/libs/prx/libc/src/Math.cpp L305
core/libs/tests/GuestMath.cpp L926
PR 6318 core/libs/prx/libc/src/Math.cpp L305
core/libs/tests/GuestMath.cpp L926
lgamma_nid_postfix

Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.

Pull request Shared files not compared
PR 6044 core/libs/tests/GuestMath.cpp

@adriadam10

Copy link
Copy Markdown
Collaborator

Checked the threshold (0x3c70000000000000 = 2^-56) and the -log|x| branch against FreeBSD e_lgamma_r.c; zero, inf, NaN and |x| ≥ 2^-56 still go to the host. Build and ctest (incl. guest_math) pass on Linux; the new rows only fail on MinGW, so the Windows job of the full Build is the evidence. Merging once it is green.

@adriadam10
adriadam10 merged commit ec1193d into boykopovar:main Oct 15, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants