https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89573

--- Comment #2 from joseph at codesourcery dot com <joseph at codesourcery dot 
com> ---
On Mon, 4 Mar 2019, rguenth at gcc dot gnu.org wrote:

> where the first result is off.  The IL looks like
> 
>     int r = (int) ((long double) log (p) * (long double) inv_log_of_base);
> 
> where possibly the missing cast to (double) is elided by bogus optimization
> (didn't try to track down the issue yet).

What missing cast to double?

I wouldn't expect such a cast to be generated on the result of the 
multiplication; I'd expect long double to be converted directly to int.  
There is, indeed, a test of that (see test_cast in 
gcc.target/i386/excess-precision-1.c).

You could argue about whether the result of log should be converted to 
double (the GCC IR is unable to represent that a function might return a 
result with excess range and precision, as far as it's concerned the 
return value of log is always representable in double) - but if the issue 
is with the return value of log, that would be a glibc issue, where maybe 
glibc should avoid excess precision in return values (currently it only 
does so for functions with exactly determined IEEE results, and otherwise 
acts to avoid excess range but not excess precision in return values).  In 
the presence of Annex F a function defined by the user cannot return with 
excess range or precision, but that may not apply to standard library 
functions which don't need to behave as if written in standard C.

convert_to_real_1 has a detailed check for when conversions can be removed 
(see the "Sometimes this transformation is safe" comment), but that 
shouldn't be relevant here (it's cases like (float)((double)float * 
(double)float) where removing conversions is safe).

Reply via email to