Repository navigation
fix(libc): honour the rounding mode in rint and rintf - #8211
Conversation
MathExact.cpp was built without -frounding-math, so GCC compiled std::rint as an add and subtract of 2^52 on the magnitude, which is exact only when rounding to nearest: under FE_DOWNWARD rint(-1.5) returned -1 and rintf(-1.5f) -1, where C and FreeBSD's libm give -2. lrint and llrint were right: they call the host libm's llrint, which honours the mode. MathExact.cpp now builds with -frounding-math. GuestMathExact checks rint, rintf, rintl, lrint and llrint of -1.5 and 1.5 in all four rounding modes and that the mode is unchanged. The failure was first caught by the rounding test of boykopovar#2235 (Привалов Александр Владимирович). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
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.
|
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011krDVCnnMQPaEFEqCDnKmA
|
Windows run of
For example, on
A side finding that this PR does not change: for a finite double outside the AI-assisted: yes (Claude Code); results above were run on this machine. |
What
rintandrintfgive wrong results under a directed rounding mode.MathExact.cppis built without-frounding-math, so GCC expandsstd::rintas an add and subtract of 2^52 (2^23 forrintf) on the magnitude and puts the sign back afterwards, which is exact only when rounding to nearest: underFE_DOWNWARD,rint(-1.5)returns -1 where C and FreeBSD's rint(3) give -2.lrintandllrintwere already right, because they call the host libm'sllrint, which honours the mode.MathExact.cppnow builds with-frounding-math.GuestMathExactchecksrint,rintf,rintl,lrintandllrintof -1.5 and 1.5 in all four rounding modes, and that the mode is unchanged afterwards.The exports landed in #6345 without the flag. #2235 (closed without merge) had specified
-frounding-mathfor this translation unit, and its rounding test first caught the failure (Привалов Александр Владимирович).Tested
Windows 11, MinGW-w64 GCC 15.2.0 (x86_64-ucrt-posix-seh r7), Release, on
main784f82b plus this commit:guest_math_exact,guest_math,guest_floating_point,guest_float_builtinsandguest_scan_countpass.main'slibc/CMakeLists.txt(no flag) and the new checks kept,guest_math_exactfails (exit 0xc0000409); with the flag it passes.gcc -O3 -Sof__builtin_rintwith this compiler: without the flag, the add and subtract of 2^52 (0x4330000000000000) is applied to|x|and the sign is restored afterwards; with it,copysign(2^52, x)is added to and subtracted fromxitself.Linux (GCC, Release): the new checks fail without the flag and pass with it; the same five tests pass.
Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)🤖 Generated with Claude Code