[3/4] math: signal underflow for fmaf results that are tiny before rounding
Checks
| Context |
Check |
Description |
| redhat-pt-bot/TryBot-apply_patch |
success
|
Patch applied to master at the time it was sent
|
| linaro-tcwg-bot/tcwg_glibc_build--master-arm |
success
|
Build passed
|
| linaro-tcwg-bot/tcwg_glibc_build--master-aarch64 |
success
|
Build passed
|
| linaro-tcwg-bot/tcwg_glibc_check--master-arm |
success
|
Test passed
|
| linaro-tcwg-bot/tcwg_glibc_check--master-aarch64 |
success
|
Test passed
|
Commit Message
fmaf computes the exact result as a double and lets the return convert
it to float, so that conversion is the operation's single rounding and
is what has to signal underflow. Where the exact result is tiny but
rounds up to the smallest normal float, architectures determining
tininess after rounding do not signal it, because the value they examine
is no longer tiny.
Route the returns through a helper that applies CHECK_NARROW_TINY, which
already decides this by rounding with an unbounded exponent range. The
raise is redundant on architectures that signal such results themselves.
---
sysdeps/ieee754/dbl-64/s_fmaf.c | 23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
Comments
On Mon, 3 Aug 2026, Matt Turner wrote:
> fmaf computes the exact result as a double and lets the return convert
> it to float, so that conversion is the operation's single rounding and
> is what has to signal underflow. Where the exact result is tiny but
> rounds up to the smallest normal float, architectures determining
> tininess after rounding do not signal it, because the value they examine
> is no longer tiny.
As with the previous patch, is this general for after-rounding
architectures, or specific to an Alpha hardware bug? In either case, I'd
expect changes to be appropriately conditional to avoid executing
unnecessary code on unaffected targets.
On Tue, 4 Aug 2026, Joseph Myers wrote:
> As with the previous patch, is this general for after-rounding
> architectures, or specific to an Alpha hardware bug?
Specific to Alpha. On x86_64 without this patch
fmaf (-0x8p-152, 0x8.8p-4, -0x3.fffff8p-128) -> -0x1p-126
raises underflow already. I answered this at more length on 2/4, which
has the worked example.
Please drop this one too. It will come back conditional, along with 2/4.
Matt
@@ -20,9 +20,24 @@
#include <math.h>
#include <fenv.h>
#include <libm-alias-float.h>
+#include <math-narrow.h>
#include <math-use-builtins.h>
#include "math_config.h"
+#if !USE_FMAF_BUILTIN
+/* Narrow the double result to float. The exact result of the fma is
+ representable as a double, so the conversion is the operation's single
+ rounding and it is what must signal underflow; help it where the
+ architecture does not. */
+static inline float
+narrow_fmaf_result (double d)
+{
+ float ret = (float) d;
+ CHECK_NARROW_TINY (ret, d, __FLT_MIN__);
+ return ret;
+}
+#endif
+
float
__fmaf (float x, float y, float z)
{
@@ -37,17 +52,17 @@ __fmaf (float x, float y, float z)
/* If not exact or at round to even boundary, the result is correct in
all rounding modes. */
if (__glibc_likely ((u & 0xfffffff) != 0))
- return result;
+ return narrow_fmaf_result (result);
/* Also check if the double result appears exact when it might not be and
thus it will not set the underflow flag if denormal. */
if ((u & 0x10000000) == 0
&& ((u >> MANTISSA_WIDTH) & 0x7ff) > EXPONENT_BIAS - 126)
- return result;
+ return narrow_fmaf_result (result);
/* Return if result is exact in all rounding modes. */
if (result - xy == z && result - z == xy)
- return result;
+ return narrow_fmaf_result (result);
/* This is where 'double-rouding' might return a wrong value, and thus
needs adjusting the low-order bits in the direction of the error. */
@@ -62,7 +77,7 @@ __fmaf (float x, float y, float z)
u++;
else
u--;
- return asdouble (u);
+ return narrow_fmaf_result (asdouble (u));
#endif /* ! USE_FMAF_BUILTIN */
}
#ifndef __fmaf