On 12/7/22 16:31, Jakub Jelinek wrote:
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.

Either way is fine.  Whatever is cleaner.

Aldy


Anyway, this patch is far less important than the previous one...

        Jakub


Reply via email to