On Fri, 14 Dec 2012, Michael Zolotukhin wrote:

> Currently, I think the problem could be tackled in the following way:
> In gimple we'll need to add a pass that would a) find regions with
> constant, compile-time known rounding mode, b) replace operations with
> subcodes like plus/minus/div/etc. with the corresponding operations
> with rounding (plus_ru, plus_rd etc.), c) remove fesetround calls if
> the region doesn't contain instructions that could depend on rounding
> mode.

I'd say constant rounding mode optimization is pretty much a corner case - 
yes, constant rounding modes for particular code are useful in practice, 
but the bigger problem is making -frounding-math work reliably - stopping 
optimizations that are invalid when the rounding mode might change 
dynamically (and any call to an external function might happen to call 
fesetround) and, similarly, optimizations that are invalid when exceptions 
might be tested (you can't optimize away ((void) (a + b)) for 
floating-point when exceptions might be tested, for example, as it might 
raise an exception flag - again, any external function might test 
exceptions, or they might be tested after return from the function 
containing that expression).  Then there are probably bugs with libgcc 
functions not raising the right exceptions / handling rounding modes 
correctly, and lots of other issues of detail to address to get these 
things right (including a lot of testsuite work).

Although constant rounding modes are probably more often useful in 
practice than dynamic modes, processor support for them is much more 
limited (although I think IA64 may have support for multiple rounding 
direction registers and specifying which is used in an instruction, which 
is the sort of thing that would help for constant modes).  And C99 / C11 
don't have C bindings for constant rounding modes - proposed bindings can 
be found in WG14 N1664, the current draft of the first part of a five-part 
Technical Specification for C bindings to IEEE 754-2008.

As suggested above, GCC doesn't really have support for even the IEEE 
754-1985 bindings in C99 / C11 Annex F - no support for the FENV_ACCESS 
pragma, and the -frounding-math -ftrapping-math options don't have all the 
desired effects.  When I've thought about implementation approaches I've 
largely thought about them from the initial correctness standpoint - how 
to add thorough testcases for all the various cases that need to be 
covered, and disabling optimizations fairly crudely for -frounding-math / 
-ftrapping-math as needed, before later trying to optimize.  There's the 
open question of whether the default set of options (which includes 
-ftrapping-math) would need to change to avoid default-options performance 
being unduly affected by making -ftrapping-math actually do everything it 
should for code testing exceptions.

Although the 754-2008 draft bindings include constant rounding directions, 
most of those bindings are new library functions and macros.  I've thought 
a bit about what would be involved in implementing them properly in glibc 
(where you have the usual issues of everything needing implementing for 
five different floating-point types, and thorough testing for all those 
different types) - but given the size of such a project, have no immediate 
plans to work on it - there is a lot to be done on glibc libm as-is just 
to improve correctness for the existing functions (and a lot already done 
for glibc 2.16 and 2.17 in that regard).  (I'd guess each of (proper Annex 
F support in GCC; fixing the remaining correctness issues in glibc libm 
for return values and exceptions; and implementing the N1664 bindings) 
would likely be months of work.)

-- 
Joseph S. Myers
jos...@codesourcery.com

Reply via email to