On Wed, Dec 07, 2022 at 04:21:09PM +0100, Aldy Hernandez wrote: > On 12/7/22 13:10, Jakub Jelinek wrote: > > + switch (code) > > + { > > + case PLUS_EXPR: > > + case MINUS_EXPR: > > + // ibm-ldouble-format documents 1ulp for + and -. > > + frange_nextafter (DFmode, tmp, inf); > > + break; > > + case MULT_EXPR: > > + // ibm-ldouble-format documents 2ulps for *. > > + frange_nextafter (DFmode, tmp, inf); > > + frange_nextafter (DFmode, tmp, inf); > > + break; > > + case RDIV_EXPR: > > + // ibm-ldouble-format documents 3ulps for /. > > + frange_nextafter (DFmode, tmp, inf); > > + frange_nextafter (DFmode, tmp, inf); > > + frange_nextafter (DFmode, tmp, inf); > > + break; > > + default: > > + if (!inexact) > > + return; > > + break; > > It looks like this chunk... > > > > + switch (code) > > + { > > + case PLUS_EXPR: > > + case MINUS_EXPR: > > + // ibm-ldouble-format documents 1ulp for + and -. > > + frange_nextafter (mode, result, inf); > > + break; > > + case MULT_EXPR: > > + // ibm-ldouble-format documents 2ulps for *. > > + frange_nextafter (mode, result, inf); > > + frange_nextafter (mode, result, inf); > > + break; > > + case RDIV_EXPR: > > + // ibm-ldouble-format documents 3ulps for /. > > + frange_nextafter (mode, result, inf); > > + frange_nextafter (mode, result, inf); > > + frange_nextafter (mode, result, inf); > > + break; > > + default: > > + break; > > + } > > ...is the same as this chunk. Plus, all this mode composite stuff is
It is not the same, there is the DFmode, tmp vs. mode, result difference. But sure, we could either add an inline function which for (code, mode, result, inf) set of options (or (code, DFmode, tmp, inf)) do those 0, 1, 2, 3 frange_nextafter calls (and return bool if it did any - there is also the if (!inexact) return; case), or as you suggest perhaps change frange_nextafter to handle MODE_COMPOSITE_P differently and do there if (mode_composite && (real_isdenormal (&result, mode) || real_iszero (&result))) { // IBM extended denormals only have DFmode precision. REAL_VALUE_TYPE tmp; real_convert (&tmp, DFmode, &result); frange_nextafter (DFmode, tmp, inf); real_convert (&result, mode, &tmp); } else frange_nextafter (mode, result, inf); Though, that somewhat changes behavior, it will convert to DFmode and back for every nextafter rather than just once (just slower compile time), but also right now we start from value rather than result. So, perhaps a combination of that, change frange_nextafter to do the above and change frange_arithmetic for the initial inexact rounding only to do it by hand using range_nextafter and starting from value. Anyway, this patch is far less important than the previous one... Jakub