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