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

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

> > 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).
> 
> Exactly why?  The multiplication result has excess precision here.
> Do you say an extra rounding step to double precision cannot change
> the conversion to integer result or do you say such extra rounding step
> isn't allowed here?  IMHO this is exactly the "issue" pointed out by
> the testcase.

The extra rounding step isn't allowed by the language semantics as I 
understand them.  The result of the double multiplication is represented 
with the range and precision of long double and must be converted directly 
to int, not to double and then to int.

> Note the frontend _does_ originally emit (int) (double) ((long double) log (p)
> * (long double) inv_log_of_base) but the conversion to double is elided

The front end should not be emitting such a conversion to double.  An 
EXCESS_PRECISION_EXPR is not a conversion (and convert_for_assignment 
removes an EXCESS_PRECISION_EXPR very early, before converting to the 
desired type).

> by convert_to_real in the code piece I qouted.

The truncation to double should not be removed because it should fail the 
real_can_shorten_arithmetic test, as well as failing the 
!excess_precision_type (newtype) test (the former is testing whether 
removing such a truncation is valid in the sense of not affecting the 
result, the latter is testing whether the change of type for arithmetic 
would run into the back end not actually having proper arithmetic 
operations for the narrower type).

Reply via email to