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).