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