http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48139

--- Comment #5 from Jeffrey Yasskin <jyasskin at gcc dot gnu.org> 2011-03-16 
17:21:57 UTC ---
According to C99, lrint does not produce domain errors. It may only produce
range errors (and isn't required to):

"The lrint and llrint functions round their argument to the nearest integer
value, rounding according to the current rounding direction. If the rounded
value is outside the range of the return type, the numeric result is
unspecified. A range error may occur if the magnitude of x is too large."
—7.12.9.5

The C1x draft changes that to allow, but not require, domain errors:

"The lrint and llrint functions round their argument to the nearest integer
value, rounding according to the current rounding direction. If the rounded
value is outside the range of the return type, the numeric result is
unspecified and a domain error or range error may occur."

In the case of a range error, 7.12.1 (oddly) actually forbids these functions
from setting ERANGE:

"… Similarly, a range error occurs if the mathematical result of the function
cannot be represented in an object of the specified type, due to extreme
magnitude. … A floating result overflows … The result underflows if the
magnitude of the mathematical result is so small that the mathematical result
cannot be represented, without extraordinary roundoff error, in an object of
the specified type." (basically unchanged in C1x)

lrint does not return a floating result, and it can't underflow, so there's no
wording saying it can set ERANGE.


So, there's no glibc bug, but I don't think this makes a compelling case for
any particular gcc behavior. The "implementation" is gcc+glibc, so gcc could
say that its implementation of lrint never sets errno, and all would be
conforming. Or gcc could say that users will pick a libc based on whether they
want errno to be set, and so it should emit the call. Or gcc could optimize
lrint in C99 (where errno-setting is forbidden) but not in C1x (where it's
allowed).


One local workaround is to set __attribute__((optimize("no-math-errno"))) on
the functions whose assembly contains the undesired call, but that's a bit
fragile in the face of changing inlining decisions.

Reply via email to