RISC-V round_away () handling of non canonical rounding modes

Joseph Myers josmyers@redhat.com
Thu Jan 16 19:14:16 GMT 2025


On Thu, 16 Jan 2025, Vineet Gupta wrote:

> With unrelated gcc changes, SPEC 2017 cam4 benchmark runs are hitting the abort
> because printf_dp_buffer_1 ()  just reads the last set rounding mode which
> happens to be the fifth one set by some FP insn.

Could you give more details of how it's getting set?

The typical expectation is that floating-point environment state not 
covered by the glibc library functions yields undefined, or at least 
unspecified, behavior.  For example, while on x86_64 or x86 glibc may 
*internally* sometimes set just whichever of the SSE and x87 rounding 
modes it knows is relevant for a particular computation, it's not 
supported for user code to enter glibc functions with those two rounding 
modes set to different values, and if you do call a glibc function in such 
a state, it's not predictable what rounding mode it will use.  So glibc 
functions might not produce predictable results when the 
FE_TONEARESTFROMZERO rounding mode is set on RISC-V, unless and until full 
FE_TONEARESTFROMZERO support is added throughout glibc.

> My question is what's the best approach to do this. Should we define this in
> RISC-V fenv.h and then add conditional ifdef in common round_away () . Or should
> we have arch specific over-ride of round_away () itself with fallback to common
> version. The latter might be cleaner but seems like an over kill for something
> which is only used sparingly in glibc codebase.

If you want to support FE_TONEARESTFROMZERO properly (which in principle 
is a good idea), you'd need to go through everything in glibc that has 
conditions on rounding modes or tries to test all supported rounding 
modes.  For example, the gen-auto-libm-tests / gen-libm-test.py / 
libm-test-driver.c machinery, and get-rounding-mode.h / rounding-mode.h, 
and gen-tst-strtod-round, and tst-printf-round (this is not an exhaustive 
list of places that handle or test different rounding modes).  And as 
discussed last month, there is some MPFR support via 
mpfr_round_nearest_away, but you can't just pass MPFR_RNDNA directly to 
most MPFR functions, so that complicates code that uses MPFR to generate 
expected results in each rounding mode.

Also note the remark in include/rounding-mode.h about defining unsupported 
rounding mode macros to arbitrary distinct values in get-rounding-mode.h, 
so that the switch statement in rounding-mode.h works without itself 
needing conditional compilation.  Either you do that for 
FE_TONEARESTFROMZERO across all non-RISC-V architectures (preferably in 
such a way that that case in the switch statement can get optimized away), 
or you use conditionals on FE_TONEARESTFROMZERO being defined.

The simple thing to do is to change sysdeps/riscv/rvf/get-rounding-mode.h 
so it only returns a supported value (so making code using 
get_rounding_mode treat FE_TONEARESTFROMZERO the same as FE_TONEAREST, 
effectively).  That doesn't give you actual support for this rounding 
mode, but should at least avoid aborts if it's set, in the absence of the 
larger changes discussed above to implement full FE_TONEARESTFROMZERO 
support.

-- 
Joseph S. Myers
josmyers@redhat.com


More information about the Libc-alpha mailing list