[PATCH 2/4] math: signal underflow for narrowing results that are tiny before rounding
Matt Turner <[email protected]> Mon, 3 Aug 2026 19:55:07 -0400
| Newsgroups | gmane.comp.lib.glibc.alpha |
|---|---|
| Message-ID | <[email protected]> |
A narrowing arithmetic function rounds the exact result once to the
narrower type, so it underflows whenever that result is both tiny and
inexact. Two cases were not being signaled.
A result that rounds up to exactly the smallest normal value of the
narrower type is not tiny any more once rounded, so architectures
determining tininess after rounding do not raise underflow for it even
though the exact result was tiny. Whether underflow is due is decided
by rounding the round-to-odd value with an unbounded exponent range:
dividing by the smallest normal is exact and moves it into the normal
range, so the conversion that follows rounds only the significand.
A subnormal result is tiny by inspection, and an inexact narrowing to
one underflows. This is normally signaled by the narrowing conversion
itself, but is lost where that conversion is carried out in more than
one step: an intermediate type wide enough to keep the double rounding
harmless for the value can still round to a number the narrower type
represents exactly, leaving the final step exact. This happens on
alpha, where the compiler converts long double to float via double.
Both raises are redundant on architectures that already signal these,
and harmless there. The comparisons use the quiet relational macros
because the result is a NaN whenever an argument was, and the signaling
relational operators would raise a spurious invalid exception for it.
The macros take the smallest normal value of the narrower type as a new
argument, as only the callers know that type.
---
math/math-narrow.h | 130 ++++++++++++++++++-----
sysdeps/i386/fpu/s_f32xdivf64.c | 3 +-
sysdeps/i386/fpu/s_f32xmulf64.c | 3 +-
sysdeps/ieee754/dbl-64/s_fadd.c | 3 +-
sysdeps/ieee754/dbl-64/s_fdiv.c | 4 +-
sysdeps/ieee754/dbl-64/s_ffma.c | 4 +-
sysdeps/ieee754/dbl-64/s_fmul.c | 4 +-
sysdeps/ieee754/dbl-64/s_fsub.c | 3 +-
sysdeps/ieee754/ldbl-128/s_daddl.c | 4 +-
sysdeps/ieee754/ldbl-128/s_ddivl.c | 4 +-
sysdeps/ieee754/ldbl-128/s_dfmal.c | 4 +-
sysdeps/ieee754/ldbl-128/s_dmull.c | 4 +-
sysdeps/ieee754/ldbl-128/s_dsubl.c | 4 +-
sysdeps/ieee754/ldbl-128/s_f64xaddf128.c | 4 +-
sysdeps/ieee754/ldbl-128/s_f64xdivf128.c | 5 +-
sysdeps/ieee754/ldbl-128/s_f64xfmaf128.c | 5 +-
sysdeps/ieee754/ldbl-128/s_f64xmulf128.c | 5 +-
sysdeps/ieee754/ldbl-128/s_f64xsubf128.c | 4 +-
sysdeps/ieee754/ldbl-128/s_faddl.c | 4 +-
sysdeps/ieee754/ldbl-128/s_fdivl.c | 4 +-
sysdeps/ieee754/ldbl-128/s_ffmal.c | 4 +-
sysdeps/ieee754/ldbl-128/s_fmull.c | 4 +-
sysdeps/ieee754/ldbl-128/s_fsubl.c | 4 +-
sysdeps/ieee754/ldbl-96/s_daddl.c | 4 +-
sysdeps/ieee754/ldbl-96/s_ddivl.c | 4 +-
sysdeps/ieee754/ldbl-96/s_dfmal.c | 4 +-
sysdeps/ieee754/ldbl-96/s_dmull.c | 4 +-
sysdeps/ieee754/ldbl-96/s_dsubl.c | 4 +-
sysdeps/ieee754/ldbl-96/s_faddl.c | 4 +-
sysdeps/ieee754/ldbl-96/s_fdivl.c | 4 +-
sysdeps/ieee754/ldbl-96/s_ffmal.c | 4 +-
sysdeps/ieee754/ldbl-96/s_fmull.c | 4 +-
sysdeps/ieee754/ldbl-96/s_fsubl.c | 4 +-
sysdeps/x86/fpu/s_ffma.c | 4 +-
34 files changed, 172 insertions(+), 89 deletions(-)
diff --git ./math/math-narrow.h ./math/math-narrow.h
index bb319cc2ca..51a43cb92b 100644
--- ./math/math-narrow.h
+++ ./math/math-narrow.h
@@ -62,6 +62,57 @@
u.d; \
})
+/* Raise the underflow exception for a narrowing of the round-to-odd
+ value W to RET that is tiny and inexact but whose underflow the
+ architecture did not signal. A narrowing operation rounds the exact
+ result once to the narrower type, so it underflows whenever that
+ result is both tiny and inexact. MIN_NORMAL is the smallest positive
+ normal value of the narrower type. Two cases need help here, and on
+ architectures that already signal them the extra raise is redundant
+ but harmless.
+
+ A subnormal RET is tiny by inspection, so an inexact narrowing to one
+ underflows. This is normally signaled by the narrowing conversion,
+ but is lost where that conversion is performed in more than one step:
+ an intermediate type wide enough to make the double rounding harmless
+ for the value can still round to a number the narrower type
+ represents exactly, leaving the final step exact.
+
+ A RET of exactly MIN_NORMAL is not tiny after rounding, so
+ architectures detecting tininess after rounding do not signal it even
+ though the exact result was tiny. Rounding W with an unbounded
+ exponent range decides whether it is tiny under that rule too.
+
+ The comparisons use the quiet relational macros: RET is a NaN
+ whenever an argument was, and the signaling relational operators
+ would raise a spurious invalid exception for it. */
+#ifdef FE_UNDERFLOW
+# define CHECK_NARROW_TINY(RET, W, MIN_NORMAL) \
+ do \
+ { \
+ if (isless (RET, MIN_NORMAL) && isgreater (RET, -(MIN_NORMAL))) \
+ { \
+ if ((W) != (RET)) \
+ __feraiseexcept (FE_UNDERFLOW); \
+ } \
+ else if (((RET) == (MIN_NORMAL) || (RET) == -(MIN_NORMAL)) \
+ && isless (W, MIN_NORMAL) && isgreater (W, -(MIN_NORMAL))) \
+ { \
+ /* Dividing by MIN_NORMAL is exact and moves W into the \
+ normal range, so the conversion below rounds only the \
+ significand. Underflow is due only when the value is \
+ still tiny afterwards; when it rounds up to exactly \
+ MIN_NORMAL it is not tiny after rounding. */ \
+ __typeof (RET) __scaled = (__typeof (RET)) ((W) / (MIN_NORMAL)); \
+ if (__scaled > -1 && __scaled < 1) \
+ __feraiseexcept (FE_UNDERFLOW); \
+ } \
+ } \
+ while (0)
+#else
+# define CHECK_NARROW_TINY(RET, W, MIN_NORMAL) do { } while (0)
+#endif
+
/* Check for error conditions from a narrowing add function returning
RET with arguments X and Y and set errno as needed. Overflow and
underflow can occur for finite arguments and a domain error for
@@ -85,9 +136,11 @@
while (0)
/* Implement narrowing add using round-to-odd. The arguments are X
- and Y, the return type is TYPE and UNION, MANTISSA and SUFFIX are
- as for ROUND_TO_ODD. */
-#define NARROW_ADD_ROUND_TO_ODD(X, Y, TYPE, UNION, SUFFIX, MANTISSA) \
+ and Y, the return type is TYPE, MIN_NORMAL is the smallest positive
+ normal value of TYPE and UNION, MANTISSA and SUFFIX are as for
+ ROUND_TO_ODD. */
+#define NARROW_ADD_ROUND_TO_ODD(X, Y, TYPE, MIN_NORMAL, UNION, SUFFIX, \
+ MANTISSA) \
do \
{ \
TYPE ret; \
@@ -97,8 +150,13 @@
if ((X) == -(Y)) \
ret = (TYPE) ((X) + (Y)); \
else \
- ret = (TYPE) ROUND_TO_ODD (math_opt_barrier (X) + (Y), \
- UNION, SUFFIX, MANTISSA, false); \
+ { \
+ __typeof ((X) + (Y)) tmp \
+ = ROUND_TO_ODD (math_opt_barrier (X) + (Y), \
+ UNION, SUFFIX, MANTISSA, false); \
+ ret = (TYPE) tmp; \
+ CHECK_NARROW_TINY (ret, tmp, MIN_NORMAL); \
+ } \
\
CHECK_NARROW_ADD (ret, (X), (Y)); \
return ret; \
@@ -143,9 +201,11 @@
while (0)
/* Implement narrowing subtract using round-to-odd. The arguments are
- X and Y, the return type is TYPE and UNION, MANTISSA and SUFFIX are
- as for ROUND_TO_ODD. */
-#define NARROW_SUB_ROUND_TO_ODD(X, Y, TYPE, UNION, SUFFIX, MANTISSA) \
+ X and Y, the return type is TYPE, MIN_NORMAL is the smallest positive
+ normal value of TYPE and UNION, MANTISSA and SUFFIX are as for
+ ROUND_TO_ODD. */
+#define NARROW_SUB_ROUND_TO_ODD(X, Y, TYPE, MIN_NORMAL, UNION, SUFFIX, \
+ MANTISSA) \
do \
{ \
TYPE ret; \
@@ -155,8 +215,13 @@
if ((X) == (Y)) \
ret = (TYPE) ((X) - (Y)); \
else \
- ret = (TYPE) ROUND_TO_ODD (math_opt_barrier (X) - (Y), \
- UNION, SUFFIX, MANTISSA, false); \
+ { \
+ __typeof ((X) - (Y)) tmp \
+ = ROUND_TO_ODD (math_opt_barrier (X) - (Y), \
+ UNION, SUFFIX, MANTISSA, false); \
+ ret = (TYPE) tmp; \
+ CHECK_NARROW_TINY (ret, tmp, MIN_NORMAL); \
+ } \
\
CHECK_NARROW_SUB (ret, (X), (Y)); \
return ret; \
@@ -201,17 +266,21 @@
while (0)
/* Implement narrowing multiply using round-to-odd. The arguments are
- X and Y, the return type is TYPE and UNION, MANTISSA, SUFFIX and
- CLEAR_UNDERFLOW are as for ROUND_TO_ODD. */
-#define NARROW_MUL_ROUND_TO_ODD(X, Y, TYPE, UNION, SUFFIX, MANTISSA, \
- CLEAR_UNDERFLOW) \
+ X and Y, the return type is TYPE, MIN_NORMAL is the smallest positive
+ normal value of TYPE and UNION, MANTISSA, SUFFIX and CLEAR_UNDERFLOW
+ are as for ROUND_TO_ODD. */
+#define NARROW_MUL_ROUND_TO_ODD(X, Y, TYPE, MIN_NORMAL, UNION, SUFFIX, \
+ MANTISSA, CLEAR_UNDERFLOW) \
do \
{ \
TYPE ret; \
+ __typeof ((X) * (Y)) tmp; \
\
- ret = (TYPE) ROUND_TO_ODD (math_opt_barrier (X) * (Y), \
- UNION, SUFFIX, MANTISSA, \
- CLEAR_UNDERFLOW); \
+ tmp = ROUND_TO_ODD (math_opt_barrier (X) * (Y), \
+ UNION, SUFFIX, MANTISSA, \
+ CLEAR_UNDERFLOW); \
+ ret = (TYPE) tmp; \
+ CHECK_NARROW_TINY (ret, tmp, MIN_NORMAL); \
\
CHECK_NARROW_MUL (ret, (X), (Y)); \
return ret; \
@@ -256,17 +325,21 @@
while (0)
/* Implement narrowing divide using round-to-odd. The arguments are X
- and Y, the return type is TYPE and UNION, MANTISSA, SUFFIX and
- CLEAR_UNDERFLOW are as for ROUND_TO_ODD. */
-#define NARROW_DIV_ROUND_TO_ODD(X, Y, TYPE, UNION, SUFFIX, MANTISSA, \
- CLEAR_UNDERFLOW) \
+ and Y, the return type is TYPE, MIN_NORMAL is the smallest positive
+ normal value of TYPE and UNION, MANTISSA, SUFFIX and CLEAR_UNDERFLOW
+ are as for ROUND_TO_ODD. */
+#define NARROW_DIV_ROUND_TO_ODD(X, Y, TYPE, MIN_NORMAL, UNION, SUFFIX, \
+ MANTISSA, CLEAR_UNDERFLOW) \
do \
{ \
TYPE ret; \
+ __typeof ((X) / (Y)) tmp; \
\
- ret = (TYPE) ROUND_TO_ODD (math_opt_barrier (X) / (Y), \
- UNION, SUFFIX, MANTISSA, \
- CLEAR_UNDERFLOW); \
+ tmp = ROUND_TO_ODD (math_opt_barrier (X) / (Y), \
+ UNION, SUFFIX, MANTISSA, \
+ CLEAR_UNDERFLOW); \
+ ret = (TYPE) tmp; \
+ CHECK_NARROW_TINY (ret, tmp, MIN_NORMAL); \
\
CHECK_NARROW_DIV (ret, (X), (Y)); \
return ret; \
@@ -356,8 +429,8 @@
/* Implement narrowing fused multiply-add using round-to-odd. The
arguments are X, Y and Z, the return type is TYPE and UNION,
MANTISSA, SUFFIX and CLEAR_UNDERFLOW are as for ROUND_TO_ODD. */
-#define NARROW_FMA_ROUND_TO_ODD(X, Y, Z, TYPE, UNION, SUFFIX, MANTISSA, \
- CLEAR_UNDERFLOW) \
+#define NARROW_FMA_ROUND_TO_ODD(X, Y, Z, TYPE, MIN_NORMAL, UNION, \
+ SUFFIX, MANTISSA, CLEAR_UNDERFLOW) \
do \
{ \
typeof (X) tmp; \
@@ -371,7 +444,10 @@
if (tmp == 0) \
ret = (TYPE) (math_opt_barrier (X) * (Y) + (Z)); \
else \
- ret = (TYPE) tmp; \
+ { \
+ ret = (TYPE) tmp; \
+ CHECK_NARROW_TINY (ret, tmp, MIN_NORMAL); \
+ } \
\
CHECK_NARROW_FMA (ret, (X), (Y), (Z)); \
return ret; \
diff --git ./sysdeps/i386/fpu/s_f32xdivf64.c ./sysdeps/i386/fpu/s_f32xdivf64.c
index 9090844404..00e9a51676 100644
--- ./sysdeps/i386/fpu/s_f32xdivf64.c
+++ ./sysdeps/i386/fpu/s_f32xdivf64.c
@@ -24,6 +24,7 @@ __f32xdivf64 (_Float64 x, _Float64 y)
{
/* To avoid double rounding, use round-to-odd on long double. */
NARROW_DIV_ROUND_TO_ODD ((long double) x, (long double) y, double,
- union ieee854_long_double, l, mantissa1, false);
+ __DBL_MIN__, union ieee854_long_double, l,
+ mantissa1, false);
}
libm_alias_float32x_float64 (div)
diff --git ./sysdeps/i386/fpu/s_f32xmulf64.c ./sysdeps/i386/fpu/s_f32xmulf64.c
index 536ddd4d78..fc96096782 100644
--- ./sysdeps/i386/fpu/s_f32xmulf64.c
+++ ./sysdeps/i386/fpu/s_f32xmulf64.c
@@ -24,6 +24,7 @@ __f32xmulf64 (_Float64 x, _Float64 y)
{
/* To avoid double rounding, use round-to-odd on long double. */
NARROW_MUL_ROUND_TO_ODD ((long double) x, (long double) y, double,
- union ieee854_long_double, l, mantissa1, false);
+ __DBL_MIN__, union ieee854_long_double, l,
+ mantissa1, false);
}
libm_alias_float32x_float64 (mul)
diff --git ./sysdeps/ieee754/dbl-64/s_fadd.c ./sysdeps/ieee754/dbl-64/s_fadd.c
index 22bf2766df..7091ae1539 100644
--- ./sysdeps/ieee754/dbl-64/s_fadd.c
+++ ./sysdeps/ieee754/dbl-64/s_fadd.c
@@ -29,6 +29,7 @@
float
__fadd (double x, double y)
{
- NARROW_ADD_ROUND_TO_ODD (x, y, float, union ieee754_double, , mantissa1);
+ NARROW_ADD_ROUND_TO_ODD (x, y, float, __FLT_MIN__, union ieee754_double, ,
+ mantissa1);
}
libm_alias_float_double (add)
diff --git ./sysdeps/ieee754/dbl-64/s_fdiv.c ./sysdeps/ieee754/dbl-64/s_fdiv.c
index 918e1722ca..5de0f1f37c 100644
--- ./sysdeps/ieee754/dbl-64/s_fdiv.c
+++ ./sysdeps/ieee754/dbl-64/s_fdiv.c
@@ -29,7 +29,7 @@
float
__fdiv (double x, double y)
{
- NARROW_DIV_ROUND_TO_ODD (x, y, float, union ieee754_double, , mantissa1,
- false);
+ NARROW_DIV_ROUND_TO_ODD (x, y, float, __FLT_MIN__, union ieee754_double, ,
+ mantissa1, false);
}
libm_alias_float_double (div)
diff --git ./sysdeps/ieee754/dbl-64/s_ffma.c ./sysdeps/ieee754/dbl-64/s_ffma.c
index 14db126cfd..f341fa88cd 100644
--- ./sysdeps/ieee754/dbl-64/s_ffma.c
+++ ./sysdeps/ieee754/dbl-64/s_ffma.c
@@ -29,7 +29,7 @@
float
__ffma (double x, double y, double z)
{
- NARROW_FMA_ROUND_TO_ODD (x, y, z, float, union ieee754_double, , mantissa1,
- false);
+ NARROW_FMA_ROUND_TO_ODD (x, y, z, float, __FLT_MIN__, union ieee754_double,
+ , mantissa1, false);
}
libm_alias_float_double (fma)
diff --git ./sysdeps/ieee754/dbl-64/s_fmul.c ./sysdeps/ieee754/dbl-64/s_fmul.c
index 2fdc7c5f22..528096bc83 100644
--- ./sysdeps/ieee754/dbl-64/s_fmul.c
+++ ./sysdeps/ieee754/dbl-64/s_fmul.c
@@ -29,7 +29,7 @@
float
__fmul (double x, double y)
{
- NARROW_MUL_ROUND_TO_ODD (x, y, float, union ieee754_double, , mantissa1,
- false);
+ NARROW_MUL_ROUND_TO_ODD (x, y, float, __FLT_MIN__, union ieee754_double, ,
+ mantissa1, false);
}
libm_alias_float_double (mul)
diff --git ./sysdeps/ieee754/dbl-64/s_fsub.c ./sysdeps/ieee754/dbl-64/s_fsub.c
index 79ccfaef9d..9008e7cbf4 100644
--- ./sysdeps/ieee754/dbl-64/s_fsub.c
+++ ./sysdeps/ieee754/dbl-64/s_fsub.c
@@ -29,6 +29,7 @@
float
__fsub (double x, double y)
{
- NARROW_SUB_ROUND_TO_ODD (x, y, float, union ieee754_double, , mantissa1);
+ NARROW_SUB_ROUND_TO_ODD (x, y, float, __FLT_MIN__, union ieee754_double, ,
+ mantissa1);
}
libm_alias_float_double (sub)
diff --git ./sysdeps/ieee754/ldbl-128/s_daddl.c ./sysdeps/ieee754/ldbl-128/s_daddl.c
index 17a76321c0..97d1073b11 100644
--- ./sysdeps/ieee754/ldbl-128/s_daddl.c
+++ ./sysdeps/ieee754/ldbl-128/s_daddl.c
@@ -31,7 +31,7 @@
double
__daddl (_Float128 x, _Float128 y)
{
- NARROW_ADD_ROUND_TO_ODD (x, y, double, union ieee854_long_double, l,
- mantissa3);
+ NARROW_ADD_ROUND_TO_ODD (x, y, double, __DBL_MIN__,
+ union ieee854_long_double, l, mantissa3);
}
libm_alias_double_ldouble (add)
diff --git ./sysdeps/ieee754/ldbl-128/s_ddivl.c ./sysdeps/ieee754/ldbl-128/s_ddivl.c
index be17f2d3db..a30fcb959c 100644
--- ./sysdeps/ieee754/ldbl-128/s_ddivl.c
+++ ./sysdeps/ieee754/ldbl-128/s_ddivl.c
@@ -31,7 +31,7 @@
double
__ddivl (_Float128 x, _Float128 y)
{
- NARROW_DIV_ROUND_TO_ODD (x, y, double, union ieee854_long_double, l,
- mantissa3, false);
+ NARROW_DIV_ROUND_TO_ODD (x, y, double, __DBL_MIN__,
+ union ieee854_long_double, l, mantissa3, false);
}
libm_alias_double_ldouble (div)
diff --git ./sysdeps/ieee754/ldbl-128/s_dfmal.c ./sysdeps/ieee754/ldbl-128/s_dfmal.c
index a6784e6fc1..beacfa2c73 100644
--- ./sysdeps/ieee754/ldbl-128/s_dfmal.c
+++ ./sysdeps/ieee754/ldbl-128/s_dfmal.c
@@ -32,7 +32,7 @@
double
__dfmal (_Float128 x, _Float128 y, _Float128 z)
{
- NARROW_FMA_ROUND_TO_ODD (x, y, z, double, union ieee854_long_double, l,
- mantissa3, false);
+ NARROW_FMA_ROUND_TO_ODD (x, y, z, double, __DBL_MIN__,
+ union ieee854_long_double, l, mantissa3, false);
}
libm_alias_double_ldouble (fma)
diff --git ./sysdeps/ieee754/ldbl-128/s_dmull.c ./sysdeps/ieee754/ldbl-128/s_dmull.c
index 5e5f2ee6d1..60ab752095 100644
--- ./sysdeps/ieee754/ldbl-128/s_dmull.c
+++ ./sysdeps/ieee754/ldbl-128/s_dmull.c
@@ -31,7 +31,7 @@
double
__dmull (_Float128 x, _Float128 y)
{
- NARROW_MUL_ROUND_TO_ODD (x, y, double, union ieee854_long_double, l,
- mantissa3, false);
+ NARROW_MUL_ROUND_TO_ODD (x, y, double, __DBL_MIN__,
+ union ieee854_long_double, l, mantissa3, false);
}
libm_alias_double_ldouble (mul)
diff --git ./sysdeps/ieee754/ldbl-128/s_dsubl.c ./sysdeps/ieee754/ldbl-128/s_dsubl.c
index a2e51664bc..b0583ef518 100644
--- ./sysdeps/ieee754/ldbl-128/s_dsubl.c
+++ ./sysdeps/ieee754/ldbl-128/s_dsubl.c
@@ -31,7 +31,7 @@
double
__dsubl (_Float128 x, _Float128 y)
{
- NARROW_SUB_ROUND_TO_ODD (x, y, double, union ieee854_long_double, l,
- mantissa3);
+ NARROW_SUB_ROUND_TO_ODD (x, y, double, __DBL_MIN__,
+ union ieee854_long_double, l, mantissa3);
}
libm_alias_double_ldouble (sub)
diff --git ./sysdeps/ieee754/ldbl-128/s_f64xaddf128.c ./sysdeps/ieee754/ldbl-128/s_f64xaddf128.c
index 8a53f146fd..bf2d0ccf5f 100644
--- ./sysdeps/ieee754/ldbl-128/s_f64xaddf128.c
+++ ./sysdeps/ieee754/ldbl-128/s_f64xaddf128.c
@@ -29,8 +29,8 @@ _Float64x
__f64xaddf128 (_Float128 x, _Float128 y)
{
#if __HAVE_FLOAT64X_LONG_DOUBLE && __HAVE_DISTINCT_FLOAT128
- NARROW_ADD_ROUND_TO_ODD (x, y, _Float64x, union ieee854_long_double, l,
- mantissa3);
+ NARROW_ADD_ROUND_TO_ODD (x, y, _Float64x, __FLT64X_MIN__,
+ union ieee854_long_double, l, mantissa3);
#else
NARROW_ADD_TRIVIAL (x, y, _Float64x);
#endif
diff --git ./sysdeps/ieee754/ldbl-128/s_f64xdivf128.c ./sysdeps/ieee754/ldbl-128/s_f64xdivf128.c
index 51573c8adf..af594f566e 100644
--- ./sysdeps/ieee754/ldbl-128/s_f64xdivf128.c
+++ ./sysdeps/ieee754/ldbl-128/s_f64xdivf128.c
@@ -30,8 +30,9 @@ _Float64x
__f64xdivf128 (_Float128 x, _Float128 y)
{
#if __HAVE_FLOAT64X_LONG_DOUBLE && __HAVE_DISTINCT_FLOAT128
- NARROW_DIV_ROUND_TO_ODD (x, y, _Float64x, union ieee854_long_double, l,
- mantissa3, TININESS_AFTER_ROUNDING);
+ NARROW_DIV_ROUND_TO_ODD (x, y, _Float64x, __FLT64X_MIN__,
+ union ieee854_long_double, l, mantissa3,
+ TININESS_AFTER_ROUNDING);
#else
NARROW_DIV_TRIVIAL (x, y, _Float64x);
#endif
diff --git ./sysdeps/ieee754/ldbl-128/s_f64xfmaf128.c ./sysdeps/ieee754/ldbl-128/s_f64xfmaf128.c
index 0f7d5592e0..af0436263c 100644
--- ./sysdeps/ieee754/ldbl-128/s_f64xfmaf128.c
+++ ./sysdeps/ieee754/ldbl-128/s_f64xfmaf128.c
@@ -30,8 +30,9 @@
_Float64x
__f64xfmaf128 (_Float128 x, _Float128 y, _Float128 z)
{
- NARROW_FMA_ROUND_TO_ODD (x, y, z, _Float64x, union ieee854_long_double, l,
- mantissa3, TININESS_AFTER_ROUNDING);
+ NARROW_FMA_ROUND_TO_ODD (x, y, z, _Float64x, __FLT64X_MIN__,
+ union ieee854_long_double, l, mantissa3,
+ TININESS_AFTER_ROUNDING);
}
libm_alias_float64x_float128 (fma)
#else
diff --git ./sysdeps/ieee754/ldbl-128/s_f64xmulf128.c ./sysdeps/ieee754/ldbl-128/s_f64xmulf128.c
index 6a59e04bb1..d4e3322d25 100644
--- ./sysdeps/ieee754/ldbl-128/s_f64xmulf128.c
+++ ./sysdeps/ieee754/ldbl-128/s_f64xmulf128.c
@@ -30,8 +30,9 @@ _Float64x
__f64xmulf128 (_Float128 x, _Float128 y)
{
#if __HAVE_FLOAT64X_LONG_DOUBLE && __HAVE_DISTINCT_FLOAT128
- NARROW_MUL_ROUND_TO_ODD (x, y, _Float64x, union ieee854_long_double, l,
- mantissa3, TININESS_AFTER_ROUNDING);
+ NARROW_MUL_ROUND_TO_ODD (x, y, _Float64x, __FLT64X_MIN__,
+ union ieee854_long_double, l, mantissa3,
+ TININESS_AFTER_ROUNDING);
#else
NARROW_MUL_TRIVIAL (x, y, _Float64x);
#endif
diff --git ./sysdeps/ieee754/ldbl-128/s_f64xsubf128.c ./sysdeps/ieee754/ldbl-128/s_f64xsubf128.c
index 05311608c8..dffb7ac7d8 100644
--- ./sysdeps/ieee754/ldbl-128/s_f64xsubf128.c
+++ ./sysdeps/ieee754/ldbl-128/s_f64xsubf128.c
@@ -29,8 +29,8 @@ _Float64x
__f64xsubf128 (_Float128 x, _Float128 y)
{
#if __HAVE_FLOAT64X_LONG_DOUBLE && __HAVE_DISTINCT_FLOAT128
- NARROW_SUB_ROUND_TO_ODD (x, y, _Float64x, union ieee854_long_double, l,
- mantissa3);
+ NARROW_SUB_ROUND_TO_ODD (x, y, _Float64x, __FLT64X_MIN__,
+ union ieee854_long_double, l, mantissa3);
#else
NARROW_SUB_TRIVIAL (x, y, _Float64x);
#endif
diff --git ./sysdeps/ieee754/ldbl-128/s_faddl.c ./sysdeps/ieee754/ldbl-128/s_faddl.c
index 3b74da68dc..41d7a7846b 100644
--- ./sysdeps/ieee754/ldbl-128/s_faddl.c
+++ ./sysdeps/ieee754/ldbl-128/s_faddl.c
@@ -27,7 +27,7 @@
float
__faddl (_Float128 x, _Float128 y)
{
- NARROW_ADD_ROUND_TO_ODD (x, y, float, union ieee854_long_double, l,
- mantissa3);
+ NARROW_ADD_ROUND_TO_ODD (x, y, float, __FLT_MIN__,
+ union ieee854_long_double, l, mantissa3);
}
libm_alias_float_ldouble (add)
diff --git ./sysdeps/ieee754/ldbl-128/s_fdivl.c ./sysdeps/ieee754/ldbl-128/s_fdivl.c
index 3d10e4eec0..2d7389e02c 100644
--- ./sysdeps/ieee754/ldbl-128/s_fdivl.c
+++ ./sysdeps/ieee754/ldbl-128/s_fdivl.c
@@ -27,7 +27,7 @@
float
__fdivl (_Float128 x, _Float128 y)
{
- NARROW_DIV_ROUND_TO_ODD (x, y, float, union ieee854_long_double, l,
- mantissa3, false);
+ NARROW_DIV_ROUND_TO_ODD (x, y, float, __FLT_MIN__,
+ union ieee854_long_double, l, mantissa3, false);
}
libm_alias_float_ldouble (div)
diff --git ./sysdeps/ieee754/ldbl-128/s_ffmal.c ./sysdeps/ieee754/ldbl-128/s_ffmal.c
index 711baf893e..92be4e736c 100644
--- ./sysdeps/ieee754/ldbl-128/s_ffmal.c
+++ ./sysdeps/ieee754/ldbl-128/s_ffmal.c
@@ -28,7 +28,7 @@
float
__ffmal (_Float128 x, _Float128 y, _Float128 z)
{
- NARROW_FMA_ROUND_TO_ODD (x, y, z, float, union ieee854_long_double, l,
- mantissa3, false);
+ NARROW_FMA_ROUND_TO_ODD (x, y, z, float, __FLT_MIN__,
+ union ieee854_long_double, l, mantissa3, false);
}
libm_alias_float_ldouble (fma)
diff --git ./sysdeps/ieee754/ldbl-128/s_fmull.c ./sysdeps/ieee754/ldbl-128/s_fmull.c
index 2534d6636b..a13fe149db 100644
--- ./sysdeps/ieee754/ldbl-128/s_fmull.c
+++ ./sysdeps/ieee754/ldbl-128/s_fmull.c
@@ -27,7 +27,7 @@
float
__fmull (_Float128 x, _Float128 y)
{
- NARROW_MUL_ROUND_TO_ODD (x, y, float, union ieee854_long_double, l,
- mantissa3, false);
+ NARROW_MUL_ROUND_TO_ODD (x, y, float, __FLT_MIN__,
+ union ieee854_long_double, l, mantissa3, false);
}
libm_alias_float_ldouble (mul)
diff --git ./sysdeps/ieee754/ldbl-128/s_fsubl.c ./sysdeps/ieee754/ldbl-128/s_fsubl.c
index 57b7bb3f9f..38c5ce8d9b 100644
--- ./sysdeps/ieee754/ldbl-128/s_fsubl.c
+++ ./sysdeps/ieee754/ldbl-128/s_fsubl.c
@@ -27,7 +27,7 @@
float
__fsubl (_Float128 x, _Float128 y)
{
- NARROW_SUB_ROUND_TO_ODD (x, y, float, union ieee854_long_double, l,
- mantissa3);
+ NARROW_SUB_ROUND_TO_ODD (x, y, float, __FLT_MIN__,
+ union ieee854_long_double, l, mantissa3);
}
libm_alias_float_ldouble (sub)
diff --git ./sysdeps/ieee754/ldbl-96/s_daddl.c ./sysdeps/ieee754/ldbl-96/s_daddl.c
index ffdede0807..846509d819 100644
--- ./sysdeps/ieee754/ldbl-96/s_daddl.c
+++ ./sysdeps/ieee754/ldbl-96/s_daddl.c
@@ -27,7 +27,7 @@
double
__daddl (long double x, long double y)
{
- NARROW_ADD_ROUND_TO_ODD (x, y, double, union ieee854_long_double, l,
- mantissa1);
+ NARROW_ADD_ROUND_TO_ODD (x, y, double, __DBL_MIN__,
+ union ieee854_long_double, l, mantissa1);
}
libm_alias_double_ldouble (add)
diff --git ./sysdeps/ieee754/ldbl-96/s_ddivl.c ./sysdeps/ieee754/ldbl-96/s_ddivl.c
index 1bbea6fae7..fb811704e5 100644
--- ./sysdeps/ieee754/ldbl-96/s_ddivl.c
+++ ./sysdeps/ieee754/ldbl-96/s_ddivl.c
@@ -27,7 +27,7 @@
double
__ddivl (long double x, long double y)
{
- NARROW_DIV_ROUND_TO_ODD (x, y, double, union ieee854_long_double, l,
- mantissa1, false);
+ NARROW_DIV_ROUND_TO_ODD (x, y, double, __DBL_MIN__,
+ union ieee854_long_double, l, mantissa1, false);
}
libm_alias_double_ldouble (div)
diff --git ./sysdeps/ieee754/ldbl-96/s_dfmal.c ./sysdeps/ieee754/ldbl-96/s_dfmal.c
index 332ea895ec..b2fb24eb06 100644
--- ./sysdeps/ieee754/ldbl-96/s_dfmal.c
+++ ./sysdeps/ieee754/ldbl-96/s_dfmal.c
@@ -28,7 +28,7 @@
double
__dfmal (long double x, long double y, long double z)
{
- NARROW_FMA_ROUND_TO_ODD (x, y, z, double, union ieee854_long_double, l,
- mantissa1, false);
+ NARROW_FMA_ROUND_TO_ODD (x, y, z, double, __DBL_MIN__,
+ union ieee854_long_double, l, mantissa1, false);
}
libm_alias_double_ldouble (fma)
diff --git ./sysdeps/ieee754/ldbl-96/s_dmull.c ./sysdeps/ieee754/ldbl-96/s_dmull.c
index faeede2f0e..b023bded5d 100644
--- ./sysdeps/ieee754/ldbl-96/s_dmull.c
+++ ./sysdeps/ieee754/ldbl-96/s_dmull.c
@@ -27,7 +27,7 @@
double
__dmull (long double x, long double y)
{
- NARROW_MUL_ROUND_TO_ODD (x, y, double, union ieee854_long_double, l,
- mantissa1, false);
+ NARROW_MUL_ROUND_TO_ODD (x, y, double, __DBL_MIN__,
+ union ieee854_long_double, l, mantissa1, false);
}
libm_alias_double_ldouble (mul)
diff --git ./sysdeps/ieee754/ldbl-96/s_dsubl.c ./sysdeps/ieee754/ldbl-96/s_dsubl.c
index 7ac31434dd..594512810d 100644
--- ./sysdeps/ieee754/ldbl-96/s_dsubl.c
+++ ./sysdeps/ieee754/ldbl-96/s_dsubl.c
@@ -27,7 +27,7 @@
double
__dsubl (long double x, long double y)
{
- NARROW_SUB_ROUND_TO_ODD (x, y, double, union ieee854_long_double, l,
- mantissa1);
+ NARROW_SUB_ROUND_TO_ODD (x, y, double, __DBL_MIN__,
+ union ieee854_long_double, l, mantissa1);
}
libm_alias_double_ldouble (sub)
diff --git ./sysdeps/ieee754/ldbl-96/s_faddl.c ./sysdeps/ieee754/ldbl-96/s_faddl.c
index 46d4a035a3..fae922bb1b 100644
--- ./sysdeps/ieee754/ldbl-96/s_faddl.c
+++ ./sysdeps/ieee754/ldbl-96/s_faddl.c
@@ -25,7 +25,7 @@
float
__faddl (long double x, long double y)
{
- NARROW_ADD_ROUND_TO_ODD (x, y, float, union ieee854_long_double, l,
- mantissa1);
+ NARROW_ADD_ROUND_TO_ODD (x, y, float, __FLT_MIN__,
+ union ieee854_long_double, l, mantissa1);
}
libm_alias_float_ldouble (add)
diff --git ./sysdeps/ieee754/ldbl-96/s_fdivl.c ./sysdeps/ieee754/ldbl-96/s_fdivl.c
index a819df6d81..0cddc4f745 100644
--- ./sysdeps/ieee754/ldbl-96/s_fdivl.c
+++ ./sysdeps/ieee754/ldbl-96/s_fdivl.c
@@ -25,7 +25,7 @@
float
__fdivl (long double x, long double y)
{
- NARROW_DIV_ROUND_TO_ODD (x, y, float, union ieee854_long_double, l,
- mantissa1, false);
+ NARROW_DIV_ROUND_TO_ODD (x, y, float, __FLT_MIN__,
+ union ieee854_long_double, l, mantissa1, false);
}
libm_alias_float_ldouble (div)
diff --git ./sysdeps/ieee754/ldbl-96/s_ffmal.c ./sysdeps/ieee754/ldbl-96/s_ffmal.c
index 5f158b43b0..92ab91455e 100644
--- ./sysdeps/ieee754/ldbl-96/s_ffmal.c
+++ ./sysdeps/ieee754/ldbl-96/s_ffmal.c
@@ -26,7 +26,7 @@
float
__ffmal (long double x, long double y, long double z)
{
- NARROW_FMA_ROUND_TO_ODD (x, y, z, float, union ieee854_long_double, l,
- mantissa1, false);
+ NARROW_FMA_ROUND_TO_ODD (x, y, z, float, __FLT_MIN__,
+ union ieee854_long_double, l, mantissa1, false);
}
libm_alias_float_ldouble (fma)
diff --git ./sysdeps/ieee754/ldbl-96/s_fmull.c ./sysdeps/ieee754/ldbl-96/s_fmull.c
index cabe804070..103d819b24 100644
--- ./sysdeps/ieee754/ldbl-96/s_fmull.c
+++ ./sysdeps/ieee754/ldbl-96/s_fmull.c
@@ -25,7 +25,7 @@
float
__fmull (long double x, long double y)
{
- NARROW_MUL_ROUND_TO_ODD (x, y, float, union ieee854_long_double, l,
- mantissa1, false);
+ NARROW_MUL_ROUND_TO_ODD (x, y, float, __FLT_MIN__,
+ union ieee854_long_double, l, mantissa1, false);
}
libm_alias_float_ldouble (mul)
diff --git ./sysdeps/ieee754/ldbl-96/s_fsubl.c ./sysdeps/ieee754/ldbl-96/s_fsubl.c
index 0d2de90d5a..5827d02ff2 100644
--- ./sysdeps/ieee754/ldbl-96/s_fsubl.c
+++ ./sysdeps/ieee754/ldbl-96/s_fsubl.c
@@ -25,7 +25,7 @@
float
__fsubl (long double x, long double y)
{
- NARROW_SUB_ROUND_TO_ODD (x, y, float, union ieee854_long_double, l,
- mantissa1);
+ NARROW_SUB_ROUND_TO_ODD (x, y, float, __FLT_MIN__,
+ union ieee854_long_double, l, mantissa1);
}
libm_alias_float_ldouble (sub)
diff --git ./sysdeps/x86/fpu/s_ffma.c ./sysdeps/x86/fpu/s_ffma.c
index 329a9d7469..099f36971b 100644
--- ./sysdeps/x86/fpu/s_ffma.c
+++ ./sysdeps/x86/fpu/s_ffma.c
@@ -44,7 +44,7 @@
float
__ffma (double x, double y, double z)
{
- NARROW_FMA_ROUND_TO_ODD (x, y, z, float, union ieee754_double, , mantissa1,
- false);
+ NARROW_FMA_ROUND_TO_ODD (x, y, z, float, __FLT_MIN__, union ieee754_double,
+ , mantissa1, false);
}
libm_alias_float_double (fma)
--
2.54.0