On Fri, Nov 4, 2022 at 8:53 PM Jakub Jelinek <ja...@redhat.com> wrote:
>
> On Fri, Nov 04, 2022 at 08:14:23PM +0100, Jakub Jelinek via Gcc-patches wrote:
> > One thing that is clear is that real_isdenormal is never true for these
> > (but then a question is if flush_denormals_to_zero actually works).
>
> So, after some more investigation, I think that is actually the case,
> real_isdenormal is only meaningful (will ever return true) right after
> round_for_format.
> The uses inside of real.cc are fine, real_to_target first calls
> round_for_format and then calls fmt->encode in which the real_isdenormal
> calls are done.  And, round_for_format is what transforms the
> normalized way of expressing the number into the denormal form:
>   /* Check the range of the exponent.  If we're out of range,
>      either underflow or overflow.  */
>   if (REAL_EXP (r) > emax2)
>     goto overflow;
>   else if (REAL_EXP (r) <= emin2m1)
>     {
>       int diff;
>
>       if (!fmt->has_denorm)
>         {
>           /* Don't underflow completely until we've had a chance to round.  */
>           if (REAL_EXP (r) < emin2m1)
>             goto underflow;
>         }
>       else
>         {
>           diff = emin2m1 - REAL_EXP (r) + 1;
>           if (diff > p2)
>             goto underflow;
>
>           /* De-normalize the significand.  */
>           r->sig[0] |= sticky_rshift_significand (r, r, diff);
>           SET_REAL_EXP (r, REAL_EXP (r) + diff);
>         }
>     }
> But, real_to_target is one of the 4 callers of static round_for_format,
> another one is real_convert, but that one undoes that immediately:
>   round_for_format (fmt, r);
>
>   /* Make resulting NaN value to be qNaN. The caller has the
>      responsibility to avoid the operation if flag_signaling_nans
>      is on.  */
>   if (r->cl == rvc_nan)
>     r->signalling = 0;
>
>   /* round_for_format de-normalizes denormals.  Undo just that part.  */
>   if (r->cl == rvc_normal)
>     normalize (r);
> and the last two are inside of encoding the IBM double double composite.
> So, I think everywhere in the frange you'll see normalized REAL_VALUE_TYPE
> and so real_isdenormal will always be false there.
> You need to check for REAL_EXP (r) < fmt->emin or so (and ideally only on
> REAL_VALUE_TYPE already real_converted to the right mode (your
> frange_arithmetics does that already, which is good, but say conversions
> and other unary ops might need it too).

Let me see if I understand you correctly...

real_isdenormal is always returning false for our uses in frange?  So
instead of using real_isdenormal in flush_denormals_to_zero, perhaps
we should be using:

REAL_EXP (r) < REAL_MODE_FORMAT (mode)->emin

??

Could we perhaps make real_isdenormal always work for all values?  Is
that possible?

Aldy

Reply via email to