https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88074
--- Comment #20 from rguenther at suse dot de <rguenther at suse dot de> --- On Tue, 20 Nov 2018, joseph at codesourcery dot com wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88074 > > --- Comment #19 from joseph at codesourcery dot com <joseph at codesourcery > dot com> --- > On Tue, 20 Nov 2018, rguenth at gcc dot gnu.org wrote: > > > if (fmt->emin < min_exp) > > min_exp = fmt->emin - fmt->p + 1; > > > so somehow the formula fmt->emin - fmt->p + 1 isn't sufficient (that's > > No, it's sufficient. long double and float128 have the same emin but > different precision; you need to use fmt->emin - fmt->p + 1 < min_exp > above, or else you'll get the wrong results if the loop looks at the long > double format before float128. Doh, stupid error indeed. Still that isn't enough and real_to_decimal_for_mode ICEs. min_exp above is now correctly -16493 and the real-value we pass in to real_to_decimal_for_mode has exp -16493 but the result is zero. That's possibly because /* Nonzero value, possibly overflowing or underflowing. */ mpfr_init2 (m, SIGNIFICAND_BITS); inexact = mpfr_strtofr (m, str, NULL, 10, GMP_RNDZ); we return true and the rounding mode is GMP_RNDZ? Indeed when changing the above to use GMP_RNDN it works OK. The whole thing is also a bit awkward IMHO since we go back and forth in real_from_string, using mpfr to format a base-10 float to a base-16 float string and then use real_from_string ... Anyway, a workaround is to elide the "+ 1" in the emin computation, giving mpfr an extra bit to offset the rounding issues. So I'll re-test and will post a patch following this.