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