Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 11 Jul 2013 15:33:34 +0100
From:      David Chisnall <theraven@FreeBSD.org>
To:        Bruce Evans <brde@optusnet.com.au>
Cc:        Garrett Wollman <wollman@csail.mit.edu>, Tijl Coosemans <tijl@FreeBSD.org>, "freebsd-toolchain@FreeBSD.org" <freebsd-toolchain@FreeBSD.org>, "freebsd-standards@FreeBSD.org" <freebsd-standards@FreeBSD.org>, FreeBSD CURRENT <freebsd-current@FreeBSD.org>
Subject:   Re: CURRENT: CLANG 3.3 and -stad=c++11 and -stdlib=libc++: isnan()/isninf() oddity
Message-ID:  <C00DFA94-6182-4334-9C90-8012E576E475@FreeBSD.org>
In-Reply-To: <20130711202908.L84170@besplex.bde.org>
References:  <20130710155809.0f589c22@thor.walstatt.dyndns.org> <CD51F125-AE9E-4461-916D-CF583002B47D@FreeBSD.org> <20130710183315.725dfde0@thor.walstatt.dyndns.org> <C8C94CF2-7D5A-471B-AD63-8E961AED6274@FreeBSD.org> <20130710203200.5359fd18@thor.walstatt.dyndns.org> <51DDC04B.6040209@FreeBSD.org> <20957.49978.73666.392417@khavrinen.csail.mit.edu> <20130711130043.R920@besplex.bde.org> <FD768A6B-8B72-44A1-BC1C-14FF44CB4643@FreeBSD.org> <20130711202908.L84170@besplex.bde.org>

next in thread | previous in thread | raw e-mail | index | archive | help

--Apple-Mail=_F8478B29-A983-4EC7-89DB-B3DA02262956
Content-Type: multipart/mixed;
	boundary="Apple-Mail=_AEC87547-9126-4EA9-8106-07500F2E3C05"


--Apple-Mail=_AEC87547-9126-4EA9-8106-07500F2E3C05
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
	charset=us-ascii

On 11 Jul 2013, at 13:11, Bruce Evans <brde@optusnet.com.au> wrote:

> The error message for the __builtin_isnan() version is slightly better =
up
> to where it says more.
>=20
> The less-unportable macro can do more classification and detect =
problems
> at compile time using __typeof().

The attached patch fixes the related test cases in the libc++ test =
suite.  Please review.

This does not use __builtin_isnan(), but it does:

- Stop exposing isnan and isinf in the header.  We already have __isinf =
in libc, so this is used instead.

- Call the static functions for isnan __inline__isnan*() so that they =
don't conflict with the ones in libm.

- Add an __fp_type_select() macro that uses either __Generic(), =
__builtin_choose_expr() / __builtin_choose_expr(), or sizeof() =
comparisons, depending on what the compiler supports.

- Refactor all of the type-generic macros to use __fp_type_select(). =20

David



--Apple-Mail=_AEC87547-9126-4EA9-8106-07500F2E3C05
Content-Disposition: attachment;
	filename=isnan.diff
Content-Type: application/octet-stream;
	name="isnan.diff"
Content-Transfer-Encoding: 7bit

Index: src/math.h
===================================================================
--- src/math.h	(revision 253148)
+++ src/math.h	(working copy)
@@ -80,28 +80,39 @@
 #define	FP_NORMAL	0x04
 #define	FP_SUBNORMAL	0x08
 #define	FP_ZERO		0x10
+
+#if __STDC_VERSION__ >= 201112L
+#define __fp_type_select(x, f, d, ld) _Generic((x),     \
+	float: f(x),                                    \
+	double: d(x),                                   \
+	long double: ld(x))
+#elif __GNUC_PREREQ__(5, 1)
+#define __fp_type_select(x, f, d, ld) __builtin_choose_expr(                   \
+	__builtin_types_compatible_p(__typeof (x), long double), ld(x),        \
+	 __builtin_choose_expr(                                                \
+	  __builtin_types_compatible_p(__typeof (x), double), d(x),            \
+	   __builtin_choose_expr(                                              \
+	    __builtin_types_compatible_p(__typeof (x), float), f(x), (void)0)))
+#else
+#define __fp_type_select(x, f, d, ld)                         \
+	((sizeof (x) == sizeof (float)) ? f(x)                \
+	     : (sizeof (x) == sizeof (double)) ? d(x)         \
+	     : ld(x))
+#endif
+
+
+
 #define	fpclassify(x) \
-    ((sizeof (x) == sizeof (float)) ? __fpclassifyf(x) \
-    : (sizeof (x) == sizeof (double)) ? __fpclassifyd(x) \
-    : __fpclassifyl(x))
+	 __fp_type_select(x, __fpclassifyf, __fpclassifyd, __fpclassifyd)
+#define	isfinite(x) \
+	__fp_type_select(x, __isfinitef, __isfinite, __isfinitel)
+#define	isinf(x) \
+	__fp_type_select(x, __isinff, __isinf, __isinfl)
+#define	isnan(x) \
+	__fp_type_select(x, __inline_isnanf, __inline_isnan, __inline_isnanl)
+#define	isnormal(x) \
+	__fp_type_select(x, __isnormalf, __isnormal, __isnormall)
 
-#define	isfinite(x)					\
-    ((sizeof (x) == sizeof (float)) ? __isfinitef(x)	\
-    : (sizeof (x) == sizeof (double)) ? __isfinite(x)	\
-    : __isfinitel(x))
-#define	isinf(x)					\
-    ((sizeof (x) == sizeof (float)) ? __isinff(x)	\
-    : (sizeof (x) == sizeof (double)) ? isinf(x)	\
-    : __isinfl(x))
-#define	isnan(x)					\
-    ((sizeof (x) == sizeof (float)) ? __isnanf(x)	\
-    : (sizeof (x) == sizeof (double)) ? isnan(x)	\
-    : __isnanl(x))
-#define	isnormal(x)					\
-    ((sizeof (x) == sizeof (float)) ? __isnormalf(x)	\
-    : (sizeof (x) == sizeof (double)) ? __isnormal(x)	\
-    : __isnormall(x))
-
 #ifdef __MATH_BUILTIN_RELOPS
 #define	isgreater(x, y)		__builtin_isgreater((x), (y))
 #define	isgreaterequal(x, y)	__builtin_isgreaterequal((x), (y))
@@ -119,10 +130,8 @@
 #define	isunordered(x, y)	(isnan(x) || isnan(y))
 #endif /* __MATH_BUILTIN_RELOPS */
 
-#define	signbit(x)					\
-    ((sizeof (x) == sizeof (float)) ? __signbitf(x)	\
-    : (sizeof (x) == sizeof (double)) ? __signbit(x)	\
-    : __signbitl(x))
+#define signbit(x) \
+	__fp_type_select(x, __signbitf, __signbit, __signbitl)
 
 typedef	__double_t	double_t;
 typedef	__float_t	float_t;
@@ -175,6 +184,7 @@
 int	__isfinite(double) __pure2;
 int	__isfinitel(long double) __pure2;
 int	__isinff(float) __pure2;
+int	__isinf(double) __pure2;
 int	__isinfl(long double) __pure2;
 int	__isnanf(float) __pure2;
 int	__isnanl(long double) __pure2;
@@ -185,6 +195,23 @@
 int	__signbitf(float) __pure2;
 int	__signbitl(long double) __pure2;
 
+static __inline int
+__inline_isnanf(float __x)
+{
+	return (__x != __x);
+}
+static __inline int
+__inline_isnan(double __x)
+{
+	return (__x != __x);
+}
+static __inline int
+__inline_isnanl(long double __x)
+{
+	return (__x != __x);
+}
+
+
 double	acos(double);
 double	asin(double);
 double	atan(double);
@@ -227,8 +254,6 @@
 double	fma(double, double, double);
 double	hypot(double, double);
 int	ilogb(double) __pure2;
-int	(isinf)(double) __pure2;
-int	(isnan)(double) __pure2;
 double	lgamma(double);
 long long llrint(double);
 long long llround(double);

--Apple-Mail=_AEC87547-9126-4EA9-8106-07500F2E3C05--

--Apple-Mail=_F8478B29-A983-4EC7-89DB-B3DA02262956
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
	filename=signature.asc
Content-Type: application/pgp-signature;
	name=signature.asc
Content-Description: Message signed with OpenPGP using GPGMail

-----BEGIN PGP SIGNATURE-----
Version: GnuPG/MacGPG2 v2.0.18 (Darwin)
Comment: GPGTools - http://gpgtools.org

iQIcBAEBAgAGBQJR3sI+AAoJEKx65DEEsqId32IQAJZK9h5IrteHBj43ympoqEz4
XqfWOje7QIB1nMI10pOdT2oGMjF18ea7g/YMnYZ5PrHtMNlreuYqX/DkoeYvg7Lk
WA2cROCI3CgIveTuODn0zfZGAd/vMlOKOm7Vw5s96vzHH/Ow8kVPbAOzd+bfmCSk
xGKSi8pOHhFqBXufb269cy1Pjlh78cdY3/mEtxGFrpVxO3IZP6o844UiAicicQ+1
aqggtQH+BK7UfJN2uwGiuLjxjJmCfJR2MNqqA86q3XeACMOh52wd49w2CWt2cNrv
AP5SMizT5G6gt+Qvvev5aN+1EZM7pTTSTfMtfCJyhP6iqmRPQ5yISj1A/qIzPaPd
5Qqj+xa0Y87OTf1E5xihIpZa3OileGA9nvJPLiUejLM67rjmCoA8Yea3yKoxR/58
EY6L+ZsLSJiXihO/mdTavVmHpc9u+DEO6BWo94dycciNE6KXOrFspQe6SyAgCPZ2
bqorYrrT+wWBKAox5cjGwBnkibSCdqXCZiPo/lPreZQRKgGHWgxuOSXj705fAumT
1Gg2rIbvfXWVoDlKUnXhHcmiAkRJL8hQsN/KOBTP5zOXA9xCd2LSnWSEBy5nJXha
lnoBga9xG1cNlLaSMwRNd3WlSLtA5sW8ldz/wWJlaHh4zMijBwoip9VpFiLrVSi7
f4Mj5wRDY9oZclRi3PHa
=v+Kg
-----END PGP SIGNATURE-----

--Apple-Mail=_F8478B29-A983-4EC7-89DB-B3DA02262956--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?C00DFA94-6182-4334-9C90-8012E576E475>