This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
soft-fp: fix negation NaN handling (bug 16034)
- From: "Joseph S. Myers" <joseph at codesourcery dot com>
- To: <libc-alpha at sourceware dot org>
- Cc: "David S. Miller" <davem at davemloft dot net>
- Date: Wed, 9 Oct 2013 20:51:11 +0000
- Subject: soft-fp: fix negation NaN handling (bug 16034)
- Authentication-results: sourceware.org; auth=none
Floating-point negation is, in IEEE 754-2008, a quiet-computational
operation affecting only the sign bit and not handling signaling NaNs
specially. The soft-fp code for negation uses cooked packing and
unpacking, meaning signaling NaNs are wrongly quieted (bug 16034); it
uses the peculiar "FP_CLEAR_EXCEPTIONS; FP_HANDLE_EXCEPTIONS;"
combination so exception processing takes place for an empty set of
exceptions. This patch makes it use raw packing / unpacking and not
handle exceptions at all. (The immediate motivation is that the
cooked packing, without FP_INIT_ROUNDMODE having been used to
initialize rounding / exception state, causes warnings building for
e500, as the rounding (which does nothing) in the cooked packing uses
an uninitialized rounding mode value. Some architectures use default
initializations in their _FP_DECL_EX to avoid such warnings, but I
don't think this should be necessary and it could hide bugs in cases
where a non-default initialization is actually needed.)
These function won't generally be used, in that negation will
generally be expanded inline for soft-float, but of course they should
have the correct semantics in case they are used.
Tested for powerpc-nofpu. Note that I haven't tested the SPARC
change.
2013-10-09 Joseph Myers <joseph@codesourcery.com>
[BZ #16034]
* soft-fp/op-common.h (_FP_NEG): Document input as raw. Do not
copy class of input value.
* soft-fp/negdf2.c (__negdf2): Use raw unpacking and packing. Do
not handle exceptions.
* soft-fp/negsf2.c (__negsf2): Likewise.
* soft-fp/negtf2.c (__negtf2): Likewise.
* sysdeps/sparc/sparc32/soft-fp/q_neg.c (_Q_neg): Likewise.
diff --git a/soft-fp/negdf2.c b/soft-fp/negdf2.c
index 3cc6f5f..1dedc71 100644
--- a/soft-fp/negdf2.c
+++ b/soft-fp/negdf2.c
@@ -33,15 +33,12 @@
DFtype __negdf2(DFtype a)
{
- FP_DECL_EX;
FP_DECL_D(A); FP_DECL_D(R);
DFtype r;
- FP_UNPACK_D(A, a);
+ FP_UNPACK_RAW_D(A, a);
FP_NEG_D(R, A);
- FP_PACK_D(r, R);
- FP_CLEAR_EXCEPTIONS;
- FP_HANDLE_EXCEPTIONS;
+ FP_PACK_RAW_D(r, R);
return r;
}
diff --git a/soft-fp/negsf2.c b/soft-fp/negsf2.c
index d8d5910..35ece56 100644
--- a/soft-fp/negsf2.c
+++ b/soft-fp/negsf2.c
@@ -33,15 +33,12 @@
SFtype __negsf2(SFtype a)
{
- FP_DECL_EX;
FP_DECL_S(A); FP_DECL_S(R);
SFtype r;
- FP_UNPACK_S(A, a);
+ FP_UNPACK_RAW_S(A, a);
FP_NEG_S(R, A);
- FP_PACK_S(r, R);
- FP_CLEAR_EXCEPTIONS;
- FP_HANDLE_EXCEPTIONS;
+ FP_PACK_RAW_S(r, R);
return r;
}
diff --git a/soft-fp/negtf2.c b/soft-fp/negtf2.c
index 1c08441..f51a621 100644
--- a/soft-fp/negtf2.c
+++ b/soft-fp/negtf2.c
@@ -33,15 +33,12 @@
TFtype __negtf2(TFtype a)
{
- FP_DECL_EX;
FP_DECL_Q(A); FP_DECL_Q(R);
TFtype r;
- FP_UNPACK_Q(A, a);
+ FP_UNPACK_RAW_Q(A, a);
FP_NEG_Q(R, A);
- FP_PACK_Q(r, R);
- FP_CLEAR_EXCEPTIONS;
- FP_HANDLE_EXCEPTIONS;
+ FP_PACK_RAW_Q(r, R);
return r;
}
diff --git a/soft-fp/op-common.h b/soft-fp/op-common.h
index 75ea352..5dfb73c 100644
--- a/soft-fp/op-common.h
+++ b/soft-fp/op-common.h
@@ -771,14 +771,12 @@ do { \
/*
- * Main negation routine. FIXME -- when we care about setting exception
- * bits reliably, this will not do. We should examine all of the fp classes.
+ * Main negation routine. The input value is raw.
*/
#define _FP_NEG(fs, wc, R, X) \
do { \
_FP_FRAC_COPY_##wc(R, X); \
- R##_c = X##_c; \
R##_e = X##_e; \
R##_s = 1 ^ X##_s; \
} while (0)
diff --git a/sysdeps/sparc/sparc32/soft-fp/q_neg.c b/sysdeps/sparc/sparc32/soft-fp/q_neg.c
index 551c408..5e2449c 100644
--- a/sysdeps/sparc/sparc32/soft-fp/q_neg.c
+++ b/sysdeps/sparc/sparc32/soft-fp/q_neg.c
@@ -24,7 +24,6 @@
long double _Q_neg(const long double a)
{
- FP_DECL_EX;
long double c = a;
#if (__BYTE_ORDER == __BIG_ENDIAN)
@@ -36,11 +35,9 @@ long double _Q_neg(const long double a)
#else
FP_DECL_Q(A); FP_DECL_Q(C);
- FP_UNPACK_Q(A, a);
+ FP_UNPACK_RAW_Q(A, a);
FP_NEG_Q(C, A);
- FP_PACK_Q(c, C);
+ FP_PACK_RAW_Q(c, C);
#endif
- FP_CLEAR_EXCEPTIONS;
- FP_HANDLE_EXCEPTIONS;
return c;
}
--
Joseph S. Myers
joseph@codesourcery.com