Skip to content

fix(libc): store the sign of gamma in an exported signgam from lgamma - #6318

Merged
oneandonlydean merged 1 commit into
boykopovar:mainfrom
hypermoist:fix/libc-lgamma-signgam
Oct 17, 2026
Merged

oneandonlydean merged 1 commit into
boykopovar:mainfrom
hypermoist:fix/libc-lgamma-signgam

Conversation

@hypermoist

Copy link
Copy Markdown
Contributor

What

lgamma returned the host's value but never stored the sign of Γ(x), because libc exported no signgam. The debt entry in docs/dev/debt/libc.md recorded this.

libc now exports signgam (NID 5gOOC0kzW0c, from the aerolib symbol list), starting at 0 as in FreeBSD 11's s_signgam.c. lgamma sets it by the rules of FreeBSD 11's e_lgamma_r.c:

  • ±0 gives the sign of the zero;
  • infinities and NaN give 1;
  • negative integers (poles) give 1. glibc differs here and reports a parity-based sign;
  • a negative non-integer gives -1 when its floor is odd (the sign of sin_pi(x)), 1 otherwise.

The returned value is unchanged; it is still the host's lgamma.

Overlap: #5775 rewrites the same lgamma line, to handle subnormal arguments on Windows. Whichever merges second needs a trivial rebase that keeps both the subnormal branch and the signgam store.

Tested

CachyOS Linux (kernel 7.2.9), GCC 16.2.1, Release, on main 8856f18.

  • guest_math checks the stored sign for positive values, ±0, -0.5, -1.5, -2.5, a tiny negative, negative integers including -2^60, a value just above -2^52, ±inf and NaN.
  • A separate host program compared the rule with glibc's lgamma_r over 2,000,000 values in [-200, 200], including integers and values scaled by 2^-70. There were 0 mismatches outside the negative-integer poles, where glibc and FreeBSD intentionally differ.
  • Pass: guest_math. tools/check_conventions.py --base origin/main passes.
  • Windows: not built or tested.

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

@github-actions

github-actions Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

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 5021 docs/dev/debt/libc.md
PR 5303 docs/dev/debt/libc.md
PR 6044 core/libs/tests/GuestMath.cpp
PR 6061 docs/dev/debt/libc.md
PR 6154 core/libs/prx/libc/src/Math.cpp
core/libs/tests/GuestMath.cpp
PR 6157 core/libs/prx/libc/src/Math.cpp
core/libs/tests/GuestMath.cpp
PR 6158 core/libs/prx/libc/src/Math.cpp
core/libs/tests/GuestMath.cpp
PR 6161 core/libs/prx/libc/src/Math.cpp
core/libs/tests/GuestMath.cpp
PR 6163 core/libs/prx/libc/src/Math.cpp
core/libs/tests/GuestMath.cpp
PR 6222 docs/dev/debt/libc.md
PR 6414 core/libs/prx/libc/src/Math.cpp
PR 6565 docs/dev/debt/libc.md

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@hypermoist
hypermoist force-pushed the fix/libc-lgamma-signgam branch from 0a53092 to 20edd07 Compare October 16, 2026 03:15
@hypermoist

Copy link
Copy Markdown
Contributor Author

Rebased onto current main (5d9dcc4). The conflict was with the new tiny-argument path in lgamma (-log|x| below 2^-56): signgam is now set first and that path is kept unchanged, and both the new subnormal tests and the signgam tests stay in GuestMath.cpp. guest_math passes and check_conventions.py is clean.

🤖 Generated with Claude Code

@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 16, 2026
@harmsluis

Copy link
Copy Markdown

Windows run (Windows 11 build 26300, non-elevated, WinLibs MinGW-w64 GCC 15.2.0 r7, Ninja, Release, BUILD_TESTING=ON), built target guest_math_tests:

  • main c84249186 (baseline): guest_math passes.
  • This PR (20edd079e) merged onto c84249186 without conflicts: builds with no new warnings, and guest_math passes 5/5 repeated runs (ctest --repeat until-fail:5).
  • The unpatched libc.prx exports signgam_nid_postfix as data (objdump -p). The test sets the variable to 7 before each lgamma call and reads it through that import, so the sign checks exercise the DLL's variable rather than a local copy.

Not covered: the full build, and the patched/NID-renamed libc.prx.

@oneandonlydean oneandonlydean self-assigned this Oct 17, 2026
@oneandonlydean
oneandonlydean merged commit df92748 into boykopovar:main Oct 17, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants