Module Name:    src
Committed By:   riastradh
Date:           Mon Jul 15 06:19:17 UTC 2024

Modified Files:
        src/tests/lib/libm: t_log.c

Log Message:
tests/lib/libm/t_log.c: Expand to handle many more cases.

Also make this much more concise.

Prompted by PR lib/58337: logl() crashes on arm64


To generate a diff of this commit:
cvs rdiff -u -r1.15 -r1.16 src/tests/lib/libm/t_log.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/tests/lib/libm/t_log.c
diff -u src/tests/lib/libm/t_log.c:1.15 src/tests/lib/libm/t_log.c:1.16
--- src/tests/lib/libm/t_log.c:1.15	Sun Jun  9 16:53:12 2024
+++ src/tests/lib/libm/t_log.c	Mon Jul 15 06:19:17 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: t_log.c,v 1.15 2024/06/09 16:53:12 riastradh Exp $ */
+/* $NetBSD: t_log.c,v 1.16 2024/07/15 06:19:17 riastradh Exp $ */
 
 /*-
  * Copyright (c) 2011 The NetBSD Foundation, Inc.
@@ -29,836 +29,590 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: t_log.c,v 1.15 2024/06/09 16:53:12 riastradh Exp $");
+__RCSID("$NetBSD: t_log.c,v 1.16 2024/07/15 06:19:17 riastradh Exp $");
 
 #include <atf-c.h>
 
+#include <errno.h>
 #include <float.h>
 #include <math.h>
 #include <stdio.h>
 #include <string.h>
 
+#define	CHECK_EQ(i, f, x, y)						      \
+	ATF_CHECK_EQ_MSG(f(x), y,					      \
+	    "[%u] %s(%a=%.17g)=%a=%.17g, expected %a=%.17g",		      \
+	    (i), #f, (double)(x), (double)(x), f(x), f(x),		      \
+	    (double)(y), (double)(y))
+
+#define	CHECKL_EQ(i, f, x, y)						      \
+	ATF_CHECK_EQ_MSG(f(x), y,					      \
+	    "[%u] %s(%La=%.17Lg)=%La=%.17Lg, expected %La=%.17Lg",	      \
+	    (i), #f, (long double)(x), (long double)(x), f(x), f(x),	      \
+	    (long double)(y), (long double)(y))
+
+#ifdef NAN
+
+#define	CHECK_NAN(i, f, x)						      \
+	ATF_CHECK_MSG(isnan(f(x)),					      \
+	    "[%u] %s(%a=%.17g)=%a=%.17g, expected NaN",			      \
+	    (i), #f, (x), (x), f(x), f(x))
+
+#define	CHECKL_NAN(i, f, x)						      \
+	ATF_CHECK_MSG(isnan(f(x)),					      \
+	    "[%u] %s(%La=%.17Lg)=%La=%.17Lg, expected NaN",		      \
+	    (i), #f, (long double)(x), (long double)(x), f(x), f(x))
+
+#else  /* !defined(NAN) */
+
+#define	CHECK_NAN(i, f, x) do						      \
+{									      \
+	int _checknan_error;						      \
+	double _checknan_result;					      \
+	errno = 0;							      \
+	_checknan_result = f(x);					      \
+	_checknan_error = errno;					      \
+	ATF_CHECK_EQ_MSG(errno, EDOM,					      \
+	    "[%u] %s(%a=%.17g)=%a=%.17g errno=%d, expected EDOM=%d",	      \
+	    (i), #f, (double)(x), (double)(x),				      \
+	    _checknan_result, _checknan_result,				      \
+	    _checknan_error, EDOM);					      \
+} while (0)
+
+#define	CHECKL_NAN(i, f, x) do						      \
+{									      \
+	int _checknan_error;						      \
+	long double _checknan_result;					      \
+	errno = 0;							      \
+	_checknan_result = f(x);					      \
+	_checknan_error = errno;					      \
+	ATF_CHECK_EQ_MSG(errno, EDOM,					      \
+	    "[%u] %s(%La=%.17Lg)=%La=%.17Lg errno=%d, expected EDOM=%d",      \
+	    (i), #f, (long double)(x), (long double)(x),		      \
+	    _checknan_result, _checknan_result,				      \
+	    _checknan_error, EDOM);					      \
+} while (0)
+
+#endif	/* NAN */
+
+static const float logf_invalid[] = {
+#ifdef NAN
+	NAN,
+#endif
+	-HUGE_VALF,
+	-FLT_MAX,
+	-10,
+	-1,
+	-FLT_EPSILON,
+	-FLT_MIN,
+#ifdef FLT_DENORM_MIN
+	-FLT_DENORM_MIN,
+#endif
+};
+
+static const double log_invalid[] = {
+#ifdef NAN
+	NAN,
+#endif
+	-HUGE_VAL,
+	-DBL_MAX,
+	-10,
+	-1,
+	-DBL_EPSILON,
+	-DBL_MIN,
+#ifdef DBL_DENORM_MIN
+	-DBL_DENORM_MIN,
+#endif
+};
+
+static const long double logl_invalid[] = {
+#ifdef NAN
+	NAN,
+#endif
+	-HUGE_VALL,
+	-LDBL_MAX,
+	-10,
+	-1,
+	-LDBL_EPSILON,
+	-LDBL_MIN,
+#ifdef LDBL_DENORM_MIN
+	-LDBL_DENORM_MIN,
+#endif
+};
+
+static const float log1pf_invalid[] = {
+#ifdef NAN
+	NAN,
+#endif
+	-HUGE_VALF,
+	-FLT_MAX,
+	-10,
+	-1 - FLT_EPSILON,
+};
+
+static const double log1p_invalid[] = {
+#ifdef NAN
+	NAN,
+#endif
+	-HUGE_VAL,
+	-DBL_MAX,
+	-10,
+	-1 - DBL_EPSILON,
+};
+
+static const long double log1pl_invalid[] = {
+#ifdef NAN
+	NAN,
+#endif
+	-HUGE_VALL,
+	-LDBL_MAX,
+	-10,
+	-1 - LDBL_EPSILON,
+};
+
 /*
  * log10(3)
  */
-ATF_TC(log10_base);
-ATF_TC_HEAD(log10_base, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test log10(10) == 1");
-}
-
-ATF_TC_BODY(log10_base, tc)
-{
-	ATF_CHECK(log10(10.0) == 1.0);
-}
-
-ATF_TC(log10_nan);
-ATF_TC_HEAD(log10_nan, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test log10(NaN) == NaN");
-}
-
-ATF_TC_BODY(log10_nan, tc)
-{
-	const double x = 0.0L / 0.0L;
-
-	ATF_CHECK(isnan(x) != 0);
-	ATF_CHECK(isnan(log10(x)) != 0);
-}
-
-ATF_TC(log10_inf_neg);
-ATF_TC_HEAD(log10_inf_neg, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test log10(-Inf) == NaN");
-}
-
-ATF_TC_BODY(log10_inf_neg, tc)
-{
-	const double x = -1.0L / 0.0L;
-	const double y = log10(x);
-
-	ATF_CHECK(isnan(y) != 0);
-}
-
-ATF_TC(log10_inf_pos);
-ATF_TC_HEAD(log10_inf_pos, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test log10(+Inf) == +Inf");
-}
-
-ATF_TC_BODY(log10_inf_pos, tc)
-{
-	const double x = 1.0L / 0.0L;
-
-	ATF_CHECK(log10(x) == x);
-}
-
-ATF_TC(log10_one_pos);
-ATF_TC_HEAD(log10_one_pos, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test log10(1.0) == +0.0");
-}
-
-ATF_TC_BODY(log10_one_pos, tc)
-{
-	const double x = log10(1.0);
-	const double y = 0.0L;
-
-	ATF_CHECK(x == y);
-	ATF_CHECK(signbit(x) == 0);
-	ATF_CHECK(signbit(y) == 0);
-}
-
-ATF_TC(log10_zero_neg);
-ATF_TC_HEAD(log10_zero_neg, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test log10(-0.0) == -HUGE_VAL");
-}
-
-ATF_TC_BODY(log10_zero_neg, tc)
-{
-	const double x = -0.0L;
-
-	ATF_CHECK(log10(x) == -HUGE_VAL);
-}
-
-ATF_TC(log10_zero_pos);
-ATF_TC_HEAD(log10_zero_pos, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test log10(+0.0) == -HUGE_VAL");
-}
-
-ATF_TC_BODY(log10_zero_pos, tc)
-{
-	const double x = 0.0L;
-
-	ATF_CHECK(log10(x) == -HUGE_VAL);
-}
+static const struct {
+	float x, y;
+} log10f_exact[] = {
+	{ 1, 0 },
+	{ 10, 1 },
+	{ 100, 2 },
+};
 
-/*
- * log10f(3)
- */
-ATF_TC(log10f_base);
-ATF_TC_HEAD(log10f_base, tc)
+ATF_TC(log10_invalid);
+ATF_TC_HEAD(log10_invalid, tc)
 {
-	atf_tc_set_md_var(tc, "descr", "Test log10f(10) == 1");
+	atf_tc_set_md_var(tc, "descr", "Test log10/f/l on invalid inputs");
 }
-
-ATF_TC_BODY(log10f_base, tc)
+ATF_TC_BODY(log10_invalid, tc)
 {
-	ATF_CHECK(log10f(10.0) == 1.0);
-}
+	unsigned i;
 
-ATF_TC(log10f_nan);
-ATF_TC_HEAD(log10f_nan, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test log10f(NaN) == NaN");
-}
+	for (i = 0; i < __arraycount(logf_invalid); i++) {
+		CHECK_NAN(i, log10f, logf_invalid[i]);
+		CHECK_NAN(i, log10, logf_invalid[i]);
+		CHECKL_NAN(i, log10l, logf_invalid[i]);
+	}
 
-ATF_TC_BODY(log10f_nan, tc)
-{
-	const float x = 0.0L / 0.0L;
+	for (i = 0; i < __arraycount(log_invalid); i++) {
+		CHECK_NAN(i, log10, log_invalid[i]);
+		CHECKL_NAN(i, log10l, log_invalid[i]);
+	}
 
-	ATF_CHECK(isnan(x) != 0);
-	ATF_CHECK(isnan(log10f(x)) != 0);
+	for (i = 0; i < __arraycount(logl_invalid); i++) {
+		CHECKL_NAN(i, log10l, logl_invalid[i]);
+	}
 }
 
-ATF_TC(log10f_inf_neg);
-ATF_TC_HEAD(log10f_inf_neg, tc)
+ATF_TC(log10_zero);
+ATF_TC_HEAD(log10_zero, tc)
 {
-	atf_tc_set_md_var(tc, "descr", "Test log10f(-Inf) == NaN");
+	atf_tc_set_md_var(tc, "descr", "Test log10/f/l on zero");
 }
-
-ATF_TC_BODY(log10f_inf_neg, tc)
+ATF_TC_BODY(log10_zero, tc)
 {
-	const float x = -1.0L / 0.0L;
-	const float y = log10f(x);
 
-	ATF_CHECK(isnan(y) != 0);
-}
+	CHECK_EQ(0, log10f, +0., -HUGE_VALF);
+	CHECK_EQ(0, log10, +0., -HUGE_VAL);
+	CHECKL_EQ(0, log10l, +0., -HUGE_VALL);
 
-ATF_TC(log10f_inf_pos);
-ATF_TC_HEAD(log10f_inf_pos, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test log10f(+Inf) == +Inf");
+	CHECK_EQ(1, log10f, -0., -HUGE_VALF);
+	CHECK_EQ(1, log10, -0., -HUGE_VAL);
+	CHECKL_EQ(1, log10l, -0., -HUGE_VALL);
 }
 
-ATF_TC_BODY(log10f_inf_pos, tc)
+ATF_TC(log10_exact);
+ATF_TC_HEAD(log10_exact, tc)
 {
-	const float x = 1.0L / 0.0L;
-
-	ATF_CHECK(log10f(x) == x);
+	atf_tc_set_md_var(tc, "descr", "Test log10/f/l exact cases");
 }
-
-ATF_TC(log10f_one_pos);
-ATF_TC_HEAD(log10f_one_pos, tc)
+ATF_TC_BODY(log10_exact, tc)
 {
-	atf_tc_set_md_var(tc, "descr", "Test log10f(1.0) == +0.0");
-}
+	unsigned i;
 
-ATF_TC_BODY(log10f_one_pos, tc)
-{
-	const float x = log10f(1.0);
-	const float y = 0.0L;
+	ATF_CHECK_EQ(signbit(log10f(1)), 0);
+	ATF_CHECK_EQ(signbit(log10(1)), 0);
+	ATF_CHECK_EQ(signbit(log10l(1)), 0);
 
-	ATF_CHECK(x == y);
-	ATF_CHECK(signbit(x) == 0);
-	ATF_CHECK(signbit(y) == 0);
-}
+	for (i = 0; i < __arraycount(log10f_exact); i++) {
+		const float x = log10f_exact[i].x;
+		const float y = log10f_exact[i].y;
 
-ATF_TC(log10f_zero_neg);
-ATF_TC_HEAD(log10f_zero_neg, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test log10f(-0.0) == -HUGE_VALF");
+		CHECK_EQ(i, log10f, x, y);
+		CHECK_EQ(i, log10, x, y);
+		CHECKL_EQ(i, log10l, x, y);
+	}
 }
 
-ATF_TC_BODY(log10f_zero_neg, tc)
+ATF_TC(log10_inf);
+ATF_TC_HEAD(log10_inf, tc)
 {
-	const float x = -0.0L;
-
-	ATF_CHECK(log10f(x) == -HUGE_VALF);
+	atf_tc_set_md_var(tc, "descr", "Test log10/f/l on +infinity");
 }
-
-ATF_TC(log10f_zero_pos);
-ATF_TC_HEAD(log10f_zero_pos, tc)
+ATF_TC_BODY(log10_inf, tc)
 {
-	atf_tc_set_md_var(tc, "descr", "Test log10f(+0.0) == -HUGE_VALF");
-}
 
-ATF_TC_BODY(log10f_zero_pos, tc)
-{
-	const float x = 0.0L;
+	if (!isinf(INFINITY))
+		atf_tc_skip("no infinities on this architecture");
 
-	ATF_CHECK(log10f(x) == -HUGE_VALF);
+	CHECK_EQ(0, log10f, INFINITY, INFINITY);
+	CHECK_EQ(0, log10, INFINITY, INFINITY);
+	CHECKL_EQ(0, log10l, INFINITY, INFINITY);
 }
 
 /*
  * log1p(3)
  */
-ATF_TC(log1p_nan);
-ATF_TC_HEAD(log1p_nan, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test log1p(NaN) == NaN");
-}
-
-ATF_TC_BODY(log1p_nan, tc)
-{
-	const double x = 0.0L / 0.0L;
 
-	ATF_CHECK(isnan(x) != 0);
-	ATF_CHECK(isnan(log1p(x)) != 0);
-}
-
-ATF_TC(log1p_inf_neg);
-ATF_TC_HEAD(log1p_inf_neg, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test log1p(-Inf) == NaN");
-}
-
-ATF_TC_BODY(log1p_inf_neg, tc)
-{
-	const volatile double x = -1.0 / 0.0;
-	const double y = log1p(x);
-
-	ATF_CHECK_MSG(isnan(y), "y=%a", y);
-}
-
-ATF_TC(log1p_inf_pos);
-ATF_TC_HEAD(log1p_inf_pos, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test log1p(+Inf) == +Inf");
-}
-
-ATF_TC_BODY(log1p_inf_pos, tc)
-{
-	const double x = 1.0L / 0.0L;
-
-	ATF_CHECK(log1p(x) == x);
-}
-
-ATF_TC(log1p_one_neg);
-ATF_TC_HEAD(log1p_one_neg, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test log1p(-1.0) == -HUGE_VAL");
-}
-
-ATF_TC_BODY(log1p_one_neg, tc)
-{
-	const volatile double x = -1.0;
-	const double y = log1p(x);
-
-	ATF_CHECK_EQ_MSG(y, -HUGE_VAL, "y=%a", y);
-}
-
-ATF_TC(log1p_zero_neg);
-ATF_TC_HEAD(log1p_zero_neg, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test log1p(-0.0) == -0.0");
-}
-
-ATF_TC_BODY(log1p_zero_neg, tc)
-{
-	const double x = -0.0L;
-
-	ATF_CHECK(log1p(x) == x);
-}
-
-ATF_TC(log1p_zero_pos);
-ATF_TC_HEAD(log1p_zero_pos, tc)
+ATF_TC(log1p_invalid);
+ATF_TC_HEAD(log1p_invalid, tc)
 {
-	atf_tc_set_md_var(tc, "descr", "Test log1p(+0.0) == +0.0");
+	atf_tc_set_md_var(tc, "descr", "Test log1p/f/l on invalid inputs");
 }
-
-ATF_TC_BODY(log1p_zero_pos, tc)
+ATF_TC_BODY(log1p_invalid, tc)
 {
-	const double x = 0.0L;
+	unsigned i;
 
-	ATF_CHECK(log1p(x) == x);
-}
-
-/*
- * log1pf(3)
- */
-ATF_TC(log1pf_nan);
-ATF_TC_HEAD(log1pf_nan, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test log1pf(NaN) == NaN");
-}
+	for (i = 0; i < __arraycount(log1pf_invalid); i++) {
+		CHECK_NAN(i, log1pf, log1pf_invalid[i]);
+		CHECK_NAN(i, log1p, log1pf_invalid[i]);
+		CHECKL_NAN(i, log1pl, log1pf_invalid[i]);
+	}
 
-ATF_TC_BODY(log1pf_nan, tc)
-{
-	const float x = 0.0L / 0.0L;
+	for (i = 0; i < __arraycount(log1p_invalid); i++) {
+		CHECK_NAN(i, log1p, log1p_invalid[i]);
+		CHECKL_NAN(i, log1pl, log1p_invalid[i]);
+	}
 
-	ATF_CHECK(isnan(x) != 0);
-	ATF_CHECK(isnan(log1pf(x)) != 0);
+	for (i = 0; i < __arraycount(log1pl_invalid); i++) {
+		CHECKL_NAN(i, log1pl, log1pl_invalid[i]);
+	}
 }
 
-ATF_TC(log1pf_inf_neg);
-ATF_TC_HEAD(log1pf_inf_neg, tc)
+ATF_TC(log1p_neg_one);
+ATF_TC_HEAD(log1p_neg_one, tc)
 {
-	atf_tc_set_md_var(tc, "descr", "Test log1pf(-Inf) == NaN");
+	atf_tc_set_md_var(tc, "descr", "Test log1p/f/l on -1");
 }
-
-ATF_TC_BODY(log1pf_inf_neg, tc)
+ATF_TC_BODY(log1p_neg_one, tc)
 {
-	const volatile float x = -1.0f / 0.0f;
-	const float y = log1pf(x);
 
-	ATF_CHECK_MSG(isnan(y), "y=%a", y);
+	CHECK_EQ(0, log1pf, -1., -HUGE_VALF);
+	CHECK_EQ(0, log1p, -1., -HUGE_VAL);
+	CHECKL_EQ(0, log1pl, -1., -HUGE_VALL);
 }
 
-ATF_TC(log1pf_inf_pos);
-ATF_TC_HEAD(log1pf_inf_pos, tc)
+ATF_TC(log1p_exact);
+ATF_TC_HEAD(log1p_exact, tc)
 {
-	atf_tc_set_md_var(tc, "descr", "Test log1pf(+Inf) == +Inf");
+	atf_tc_set_md_var(tc, "descr", "Test log1p/f/l exact cases");
 }
-
-ATF_TC_BODY(log1pf_inf_pos, tc)
+ATF_TC_BODY(log1p_exact, tc)
 {
-	const float x = 1.0L / 0.0L;
 
-	ATF_CHECK(log1pf(x) == x);
-}
+	/*
+	 * Not _exact_, but the approximation is good enough.
+	 */
+#ifdef FLT_DENORM_MIN
+	CHECK_EQ(0, log1pf, -FLT_DENORM_MIN, -FLT_DENORM_MIN);
+#endif
+#ifdef DBL_DENORM_MIN
+	CHECK_EQ(0, log1p, -DBL_DENORM_MIN, -DBL_DENORM_MIN);
+#endif
+#ifdef LDBL_DENORM_MIN
+	CHECKL_EQ(0, log1pl, -LDBL_DENORM_MIN, -LDBL_DENORM_MIN);
+#endif
 
-ATF_TC(log1pf_one_neg);
-ATF_TC_HEAD(log1pf_one_neg, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test log1pf(-1.0) == -HUGE_VALF");
-}
+	CHECK_EQ(1, log1pf, -FLT_MIN, -FLT_MIN);
+	CHECK_EQ(1, log1p, -DBL_MIN, -DBL_MIN);
+	CHECKL_EQ(1, log1pl, -LDBL_MIN, -LDBL_MIN);
 
-ATF_TC_BODY(log1pf_one_neg, tc)
-{
-	const volatile float x = -1.0f;
-	const float y = log1pf(x);
+	CHECK_EQ(0, log1pf, -0., 0);
+	CHECK_EQ(0, log1p, -0., 0);
+	CHECKL_EQ(0, log1pl, -0., 0);
 
-	ATF_CHECK_EQ_MSG(y, -HUGE_VALF, "y=%a", y);
-}
+	CHECK_EQ(1, log1pf, +0., 0);
+	CHECK_EQ(1, log1p, +0., 0);
+	CHECKL_EQ(1, log1pl, +0., 0);
 
-ATF_TC(log1pf_zero_neg);
-ATF_TC_HEAD(log1pf_zero_neg, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test log1pf(-0.0) == -0.0");
+	CHECK_EQ(2, log1pf, 1, logf(2));
+	CHECK_EQ(2, log1p, 1, log(2));
+	CHECKL_EQ(2, log1pl, 1, logl(2));
 }
 
-ATF_TC_BODY(log1pf_zero_neg, tc)
+ATF_TC(log1p_inf);
+ATF_TC_HEAD(log1p_inf, tc)
 {
-	const float x = -0.0L;
-
-	ATF_CHECK(log1pf(x) == x);
+	atf_tc_set_md_var(tc, "descr", "Test log1p/f/l on +infinity");
 }
-
-ATF_TC(log1pf_zero_pos);
-ATF_TC_HEAD(log1pf_zero_pos, tc)
+ATF_TC_BODY(log1p_inf, tc)
 {
-	atf_tc_set_md_var(tc, "descr", "Test log1pf(+0.0) == +0.0");
-}
 
-ATF_TC_BODY(log1pf_zero_pos, tc)
-{
-	const float x = 0.0L;
+	if (!isinf(INFINITY))
+		atf_tc_skip("no infinities on this architecture");
 
-	ATF_CHECK(log1pf(x) == x);
+	CHECK_EQ(0, log1pf, INFINITY, INFINITY);
+	CHECK_EQ(0, log1p, INFINITY, INFINITY);
+	CHECKL_EQ(0, log1pl, INFINITY, INFINITY);
 }
 
 /*
  * log2(3)
  */
-ATF_TC(log2_base);
-ATF_TC_HEAD(log2_base, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test log2(2) == 1");
-}
-
-ATF_TC_BODY(log2_base, tc)
-{
-	ATF_CHECK(log2(2.0) == 1.0);
-}
-
-ATF_TC(log2_nan);
-ATF_TC_HEAD(log2_nan, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test log2(NaN) == NaN");
-}
-
-ATF_TC_BODY(log2_nan, tc)
-{
-	const double x = 0.0L / 0.0L;
-
-	ATF_CHECK(isnan(x) != 0);
-	ATF_CHECK(isnan(log2(x)) != 0);
-}
-
-ATF_TC(log2_inf_neg);
-ATF_TC_HEAD(log2_inf_neg, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test log2(-Inf) == NaN");
-}
-
-ATF_TC_BODY(log2_inf_neg, tc)
-{
-	const double x = -1.0L / 0.0L;
-	const double y = log2(x);
-
-	ATF_CHECK(isnan(y) != 0);
-}
-
-ATF_TC(log2_inf_pos);
-ATF_TC_HEAD(log2_inf_pos, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test log2(+Inf) == +Inf");
-}
-
-ATF_TC_BODY(log2_inf_pos, tc)
-{
-	const double x = 1.0L / 0.0L;
-
-	ATF_CHECK(log2(x) == x);
-}
-
-ATF_TC(log2_one_pos);
-ATF_TC_HEAD(log2_one_pos, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test log2(1.0) == +0.0");
-}
-
-ATF_TC_BODY(log2_one_pos, tc)
-{
-	const double x = log2(1.0);
-	const double y = 0.0L;
-
-	ATF_CHECK(x == y);
-	ATF_CHECK(signbit(x) == 0);
-	ATF_CHECK(signbit(y) == 0);
-}
-
-ATF_TC(log2_zero_neg);
-ATF_TC_HEAD(log2_zero_neg, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test log2(-0.0) == -HUGE_VAL");
-}
-
-ATF_TC_BODY(log2_zero_neg, tc)
-{
-	const double x = -0.0L;
-
-	ATF_CHECK(log2(x) == -HUGE_VAL);
-}
-
-ATF_TC(log2_zero_pos);
-ATF_TC_HEAD(log2_zero_pos, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test log2(+0.0) == -HUGE_VAL");
-}
-
-ATF_TC_BODY(log2_zero_pos, tc)
-{
-	const double x = 0.0L;
-
-	ATF_CHECK(log2(x) == -HUGE_VAL);
-}
-
-/*
- * log2f(3)
- */
-ATF_TC(log2f_base);
-ATF_TC_HEAD(log2f_base, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test log2f(2) == 1");
-}
-
-ATF_TC_BODY(log2f_base, tc)
-{
-	ATF_CHECK(log2f(2.0) == 1.0);
-}
-
-ATF_TC(log2f_nan);
-ATF_TC_HEAD(log2f_nan, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test log2f(NaN) == NaN");
-}
-
-ATF_TC_BODY(log2f_nan, tc)
-{
-	const float x = 0.0L / 0.0L;
-
-	ATF_CHECK(isnan(x) != 0);
-	ATF_CHECK(isnan(log2f(x)) != 0);
-}
-
-ATF_TC(log2f_inf_neg);
-ATF_TC_HEAD(log2f_inf_neg, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test log2f(-Inf) == NaN");
-}
-
-ATF_TC_BODY(log2f_inf_neg, tc)
-{
-	const float x = -1.0L / 0.0L;
-	const float y = log2f(x);
-
-	ATF_CHECK(isnan(y) != 0);
-}
-
-ATF_TC(log2f_inf_pos);
-ATF_TC_HEAD(log2f_inf_pos, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test log2f(+Inf) == +Inf");
-}
-
-ATF_TC_BODY(log2f_inf_pos, tc)
-{
-	const float x = 1.0L / 0.0L;
-
-	ATF_CHECK(log2f(x) == x);
-}
-
-ATF_TC(log2f_one_pos);
-ATF_TC_HEAD(log2f_one_pos, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test log2f(1.0) == +0.0");
-}
-
-ATF_TC_BODY(log2f_one_pos, tc)
-{
-	const float x = log2f(1.0);
-	const float y = 0.0L;
-
-	ATF_CHECK(x == y);
-	ATF_CHECK(signbit(x) == 0);
-	ATF_CHECK(signbit(y) == 0);
-}
-
-ATF_TC(log2f_zero_neg);
-ATF_TC_HEAD(log2f_zero_neg, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test log2f(-0.0) == -HUGE_VALF");
-}
-
-ATF_TC_BODY(log2f_zero_neg, tc)
-{
-	const float x = -0.0L;
-
-	ATF_CHECK(log2f(x) == -HUGE_VALF);
-}
-
-ATF_TC(log2f_zero_pos);
-ATF_TC_HEAD(log2f_zero_pos, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test log2f(+0.0) == -HUGE_VALF");
-}
-
-ATF_TC_BODY(log2f_zero_pos, tc)
-{
-	const float x = 0.0L;
-
-	ATF_CHECK(log2f(x) == -HUGE_VALF);
+static const struct {
+	float x, y;
+} log2f_exact[] = {
+#ifdef FLT_DENORM_MIN
+	{ FLT_DENORM_MIN, FLT_MIN_EXP - FLT_MANT_DIG },
+#endif
+	{ FLT_MIN, FLT_MIN_EXP - 1 },
+	{ 0.25, -2 },
+	{ 0.5, -1 },
+	{ 1, 0 },
+	{ 2, 1 },
+	{ 4, 2 },
+	{ 8, 3 },
+	{ 1 << FLT_MANT_DIG, FLT_MANT_DIG },
+	{ (float)(1 << FLT_MANT_DIG) * (1 << FLT_MANT_DIG),
+	  2*FLT_MANT_DIG },
+};
+static const struct {
+	double x, y;
+} log2_exact[] = {
+#ifdef DBL_DENORM_MIN
+	{ DBL_DENORM_MIN, DBL_MIN_EXP - DBL_MANT_DIG },
+#endif
+	{ DBL_MIN, DBL_MIN_EXP - 1 },
+	{ (uint64_t)1 << DBL_MANT_DIG, DBL_MANT_DIG },
+	{ ((double)((uint64_t)1 << DBL_MANT_DIG) *
+		    ((uint64_t)1 << DBL_MANT_DIG)),
+	  2*DBL_MANT_DIG },
+};
+
+static const struct {
+	long double x, y;
+} log2l_exact[] = {
+#ifdef LDBL_DENORM_MIN
+	{ LDBL_DENORM_MIN, LDBL_MIN_EXP - LDBL_MANT_DIG },
+#endif
+	{ LDBL_MIN, LDBL_MIN_EXP - 1 },
+	{ ((long double)((uint64_t)1 << (LDBL_MANT_DIG/2)) *
+		    ((uint64_t)1 << ((LDBL_MANT_DIG + 1)/2))),
+	  LDBL_MANT_DIG },
+	{ (((long double)((uint64_t)1 << (LDBL_MANT_DIG/2)) *
+			((uint64_t)1 << ((LDBL_MANT_DIG + 1)/2))) *
+		    ((long double)((uint64_t)1 << (LDBL_MANT_DIG/2)) *
+			((uint64_t)1 << ((LDBL_MANT_DIG + 1)/2)))),
+	  2*LDBL_MANT_DIG },
+};
+
+ATF_TC(log2_invalid);
+ATF_TC_HEAD(log2_invalid, tc)
+{
+	atf_tc_set_md_var(tc, "descr", "Test log2/f/l on invalid inputs");
+}
+ATF_TC_BODY(log2_invalid, tc)
+{
+	unsigned i;
+
+	for (i = 0; i < __arraycount(logf_invalid); i++) {
+		CHECK_NAN(i, log2f, logf_invalid[i]);
+		CHECK_NAN(i, log2, logf_invalid[i]);
+		CHECKL_NAN(i, log2l, logf_invalid[i]);
+	}
+
+	for (i = 0; i < __arraycount(log_invalid); i++) {
+		CHECK_NAN(i, log2, log_invalid[i]);
+		CHECKL_NAN(i, log2l, log_invalid[i]);
+	}
+
+	for (i = 0; i < __arraycount(logl_invalid); i++) {
+		CHECKL_NAN(i, log2l, logl_invalid[i]);
+	}
+}
+
+ATF_TC(log2_zero);
+ATF_TC_HEAD(log2_zero, tc)
+{
+	atf_tc_set_md_var(tc, "descr", "Test log2/f/l on zero");
+}
+ATF_TC_BODY(log2_zero, tc)
+{
+
+	CHECK_EQ(0, log2f, +0., -HUGE_VALF);
+	CHECK_EQ(0, log2, +0., -HUGE_VAL);
+	CHECKL_EQ(0, log2l, +0., -HUGE_VALL);
+
+	CHECK_EQ(1, log2f, -0., -HUGE_VALF);
+	CHECK_EQ(1, log2, -0., -HUGE_VAL);
+	CHECKL_EQ(1, log2l, -0., -HUGE_VALL);
+}
+
+ATF_TC(log2_exact);
+ATF_TC_HEAD(log2_exact, tc)
+{
+	atf_tc_set_md_var(tc, "descr", "Test log2/f/l exact cases");
+}
+ATF_TC_BODY(log2_exact, tc)
+{
+	unsigned i;
+
+	ATF_CHECK_EQ(signbit(log2f(1)), 0);
+	ATF_CHECK_EQ(signbit(log2(1)), 0);
+	ATF_CHECK_EQ(signbit(log2l(1)), 0);
+
+	for (i = 0; i < __arraycount(log2f_exact); i++) {
+		const float x = log2f_exact[i].x;
+		const float y = log2f_exact[i].y;
+
+		CHECK_EQ(i, log2f, x, y);
+		CHECK_EQ(i, log2, x, y);
+		CHECKL_EQ(i, log2l, x, y);
+	}
+
+	for (i = 0; i < __arraycount(log2_exact); i++) {
+		const double x = log2_exact[i].x;
+		const double y = log2_exact[i].y;
+
+		CHECK_EQ(i, log2, x, y);
+		CHECKL_EQ(i, log2l, x, y);
+	}
+
+	for (i = 0; i < __arraycount(log2l_exact); i++) {
+		const long double x = log2l_exact[i].x;
+		const long double y = log2l_exact[i].y;
+
+		CHECKL_EQ(i, log2l, x, y);
+	}
+}
+
+ATF_TC(log2_inf);
+ATF_TC_HEAD(log2_inf, tc)
+{
+	atf_tc_set_md_var(tc, "descr", "Test log2/f/l on +infinity");
+}
+ATF_TC_BODY(log2_inf, tc)
+{
+
+	if (!isinf(INFINITY))
+		atf_tc_skip("no infinities on this architecture");
+
+	CHECK_EQ(0, log2f, INFINITY, INFINITY);
+	CHECK_EQ(0, log2, INFINITY, INFINITY);
+	CHECKL_EQ(0, log2l, INFINITY, INFINITY);
 }
 
 /*
  * log(3)
  */
-ATF_TC(log_base);
-ATF_TC_HEAD(log_base, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test log(e) == 1");
-}
-
-ATF_TC_BODY(log_base, tc)
-{
-	const double eps = DBL_EPSILON;
-
-	if (!(fabs(log(M_E) - 1.0) <= eps))
-		atf_tc_fail_nonfatal("log(e) = %.17g != 1", log(M_E));
-}
-
-ATF_TC(log_nan);
-ATF_TC_HEAD(log_nan, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test log(NaN) == NaN");
-}
 
-ATF_TC_BODY(log_nan, tc)
+ATF_TC(log_invalid);
+ATF_TC_HEAD(log_invalid, tc)
 {
-	const double x = 0.0L / 0.0L;
-
-	ATF_CHECK(isnan(x) != 0);
-	ATF_CHECK(isnan(log(x)) != 0);
+	atf_tc_set_md_var(tc, "descr", "Test log/f/l on invalid inputs");
 }
-
-ATF_TC(log_inf_neg);
-ATF_TC_HEAD(log_inf_neg, tc)
+ATF_TC_BODY(log_invalid, tc)
 {
-	atf_tc_set_md_var(tc, "descr", "Test log(-Inf) == NaN");
-}
-
-ATF_TC_BODY(log_inf_neg, tc)
-{
-	const double x = -1.0L / 0.0L;
-	const double y = log(x);
-
-	ATF_CHECK(isnan(y) != 0);
-}
+	unsigned i;
 
-ATF_TC(log_inf_pos);
-ATF_TC_HEAD(log_inf_pos, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test log(+Inf) == +Inf");
-}
+	for (i = 0; i < __arraycount(logf_invalid); i++) {
+		CHECK_NAN(i, logf, logf_invalid[i]);
+		CHECK_NAN(i, log, logf_invalid[i]);
+		CHECKL_NAN(i, logl, logf_invalid[i]);
+	}
 
-ATF_TC_BODY(log_inf_pos, tc)
-{
-	const double x = 1.0L / 0.0L;
+	for (i = 0; i < __arraycount(log_invalid); i++) {
+		CHECK_NAN(i, log, log_invalid[i]);
+		CHECKL_NAN(i, logl, log_invalid[i]);
+	}
 
-	ATF_CHECK(log(x) == x);
+	for (i = 0; i < __arraycount(logl_invalid); i++) {
+		CHECKL_NAN(i, logl, logl_invalid[i]);
+	}
 }
 
-ATF_TC(log_one_pos);
-ATF_TC_HEAD(log_one_pos, tc)
+ATF_TC(log_zero);
+ATF_TC_HEAD(log_zero, tc)
 {
-	atf_tc_set_md_var(tc, "descr", "Test log(1.0) == +0.0");
+	atf_tc_set_md_var(tc, "descr", "Test log/f/l on zero");
 }
-
-ATF_TC_BODY(log_one_pos, tc)
+ATF_TC_BODY(log_zero, tc)
 {
-	const double x = log(1.0);
-	const double y = 0.0L;
 
-	ATF_CHECK(x == y);
-	ATF_CHECK(signbit(x) == 0);
-	ATF_CHECK(signbit(y) == 0);
-}
+	CHECK_EQ(0, logf, +0., -HUGE_VALF);
+	CHECK_EQ(0, log, +0., -HUGE_VAL);
+	CHECKL_EQ(0, logl, +0., -HUGE_VALL);
 
-ATF_TC(log_zero_neg);
-ATF_TC_HEAD(log_zero_neg, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test log(-0.0) == -HUGE_VAL");
+	CHECK_EQ(1, logf, -0., -HUGE_VALF);
+	CHECK_EQ(1, log, -0., -HUGE_VAL);
+	CHECKL_EQ(1, logl, -0., -HUGE_VALL);
 }
 
-ATF_TC_BODY(log_zero_neg, tc)
+ATF_TC(log_normal);
+ATF_TC_HEAD(log_normal, tc)
 {
-	const double x = -0.0L;
-
-	ATF_CHECK(log(x) == -HUGE_VAL);
+	atf_tc_set_md_var(tc, "descr", "Test log/f/l normal cases");
 }
-
-ATF_TC(log_zero_pos);
-ATF_TC_HEAD(log_zero_pos, tc)
+ATF_TC_BODY(log_normal, tc)
 {
-	atf_tc_set_md_var(tc, "descr", "Test log(+0.0) == -HUGE_VAL");
-}
+	volatile long double e = M_E;
 
-ATF_TC_BODY(log_zero_pos, tc)
-{
-	const double x = 0.0L;
+	CHECK_EQ(0, logf, 1, 0);
+	CHECK_EQ(0, log, 1, 0);
+	CHECKL_EQ(0, logl, 1, 0);
 
-	ATF_CHECK(log(x) == -HUGE_VAL);
-}
+	ATF_CHECK_EQ(signbit(logf(1)), 0);
+	ATF_CHECK_EQ(signbit(log(1)), 0);
+	ATF_CHECK_EQ(signbit(logl(1)), 0);
 
-/*
- * logf(3)
- */
-ATF_TC(logf_base);
-ATF_TC_HEAD(logf_base, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test logf(e) == 1");
+	ATF_CHECK_MSG(fabsf((logf(e) - 1)/1) < FLT_EPSILON,
+	    "logf(e)=%a=%.8g", logf(e), logf(e));
+	ATF_CHECK_MSG(fabs((log(e) - 1)/1) < DBL_EPSILON,
+	    "log(e)=%a=%.17g", log(e), log(e));
+	ATF_CHECK_MSG(fabsl((logl(e) - 1)/1) < LDBL_EPSILON,
+	    "logl(e)=%La=%.34Lg", logl(e), logl(e));
 }
 
-ATF_TC_BODY(logf_base, tc)
+ATF_TC(log_inf);
+ATF_TC_HEAD(log_inf, tc)
 {
-	const float eps = FLT_EPSILON;
-
-	if (!(fabsf(logf(M_E) - 1.0f) <= eps))
-		atf_tc_fail_nonfatal("logf(e) = %.17g != 1",
-		    (double)logf(M_E));
+	atf_tc_set_md_var(tc, "descr", "Test log/f/l on +infinity");
 }
-
-ATF_TC(logf_nan);
-ATF_TC_HEAD(logf_nan, tc)
+ATF_TC_BODY(log_inf, tc)
 {
-	atf_tc_set_md_var(tc, "descr", "Test logf(NaN) == NaN");
-}
 
-ATF_TC_BODY(logf_nan, tc)
-{
-	const float x = 0.0L / 0.0L;
-
-	ATF_CHECK(isnan(x) != 0);
-	ATF_CHECK(isnan(logf(x)) != 0);
-}
-
-ATF_TC(logf_inf_neg);
-ATF_TC_HEAD(logf_inf_neg, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test logf(-Inf) == NaN");
-}
-
-ATF_TC_BODY(logf_inf_neg, tc)
-{
-	const float x = -1.0L / 0.0L;
-	const float y = logf(x);
-
-	ATF_CHECK(isnan(y) != 0);
-}
-
-ATF_TC(logf_inf_pos);
-ATF_TC_HEAD(logf_inf_pos, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test logf(+Inf) == +Inf");
-}
-
-ATF_TC_BODY(logf_inf_pos, tc)
-{
-	const float x = 1.0L / 0.0L;
-
-	ATF_CHECK(logf(x) == x);
-}
-
-ATF_TC(logf_one_pos);
-ATF_TC_HEAD(logf_one_pos, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test logf(1.0) == +0.0");
-}
-
-ATF_TC_BODY(logf_one_pos, tc)
-{
-	const float x = logf(1.0);
-	const float y = 0.0L;
-
-	ATF_CHECK(x == y);
-	ATF_CHECK(signbit(x) == 0);
-	ATF_CHECK(signbit(y) == 0);
-}
-
-ATF_TC(logf_zero_neg);
-ATF_TC_HEAD(logf_zero_neg, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test logf(-0.0) == -HUGE_VALF");
-}
-
-ATF_TC_BODY(logf_zero_neg, tc)
-{
-	const float x = -0.0L;
-
-	ATF_CHECK(logf(x) == -HUGE_VALF);
-}
-
-ATF_TC(logf_zero_pos);
-ATF_TC_HEAD(logf_zero_pos, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Test logf(+0.0) == -HUGE_VALF");
-}
-
-ATF_TC_BODY(logf_zero_pos, tc)
-{
-	const float x = 0.0L;
+	if (!isinf(INFINITY))
+		atf_tc_skip("no infinities on this architecture");
 
-	ATF_CHECK(logf(x) == -HUGE_VALF);
+	CHECK_EQ(0, logf, INFINITY, INFINITY);
+	CHECK_EQ(0, log, INFINITY, INFINITY);
+	CHECKL_EQ(0, logl, INFINITY, INFINITY);
 }
 
 ATF_TP_ADD_TCS(tp)
 {
 
-	ATF_TP_ADD_TC(tp, log10_base);
-	ATF_TP_ADD_TC(tp, log10_nan);
-	ATF_TP_ADD_TC(tp, log10_inf_neg);
-	ATF_TP_ADD_TC(tp, log10_inf_pos);
-	ATF_TP_ADD_TC(tp, log10_one_pos);
-	ATF_TP_ADD_TC(tp, log10_zero_neg);
-	ATF_TP_ADD_TC(tp, log10_zero_pos);
-
-	ATF_TP_ADD_TC(tp, log10f_base);
-	ATF_TP_ADD_TC(tp, log10f_nan);
-	ATF_TP_ADD_TC(tp, log10f_inf_neg);
-	ATF_TP_ADD_TC(tp, log10f_inf_pos);
-	ATF_TP_ADD_TC(tp, log10f_one_pos);
-	ATF_TP_ADD_TC(tp, log10f_zero_neg);
-	ATF_TP_ADD_TC(tp, log10f_zero_pos);
-
-	ATF_TP_ADD_TC(tp, log1p_nan);
-	ATF_TP_ADD_TC(tp, log1p_inf_neg);
-	ATF_TP_ADD_TC(tp, log1p_inf_pos);
-	ATF_TP_ADD_TC(tp, log1p_one_neg);
-	ATF_TP_ADD_TC(tp, log1p_zero_neg);
-	ATF_TP_ADD_TC(tp, log1p_zero_pos);
-
-	ATF_TP_ADD_TC(tp, log1pf_nan);
-	ATF_TP_ADD_TC(tp, log1pf_inf_neg);
-	ATF_TP_ADD_TC(tp, log1pf_inf_pos);
-	ATF_TP_ADD_TC(tp, log1pf_one_neg);
-	ATF_TP_ADD_TC(tp, log1pf_zero_neg);
-	ATF_TP_ADD_TC(tp, log1pf_zero_pos);
-
-	ATF_TP_ADD_TC(tp, log2_base);
-	ATF_TP_ADD_TC(tp, log2_nan);
-	ATF_TP_ADD_TC(tp, log2_inf_neg);
-	ATF_TP_ADD_TC(tp, log2_inf_pos);
-	ATF_TP_ADD_TC(tp, log2_one_pos);
-	ATF_TP_ADD_TC(tp, log2_zero_neg);
-	ATF_TP_ADD_TC(tp, log2_zero_pos);
-
-	ATF_TP_ADD_TC(tp, log2f_base);
-	ATF_TP_ADD_TC(tp, log2f_nan);
-	ATF_TP_ADD_TC(tp, log2f_inf_neg);
-	ATF_TP_ADD_TC(tp, log2f_inf_pos);
-	ATF_TP_ADD_TC(tp, log2f_one_pos);
-	ATF_TP_ADD_TC(tp, log2f_zero_neg);
-	ATF_TP_ADD_TC(tp, log2f_zero_pos);
-
-	ATF_TP_ADD_TC(tp, log_base);
-	ATF_TP_ADD_TC(tp, log_nan);
-	ATF_TP_ADD_TC(tp, log_inf_neg);
-	ATF_TP_ADD_TC(tp, log_inf_pos);
-	ATF_TP_ADD_TC(tp, log_one_pos);
-	ATF_TP_ADD_TC(tp, log_zero_neg);
-	ATF_TP_ADD_TC(tp, log_zero_pos);
-
-	ATF_TP_ADD_TC(tp, logf_base);
-	ATF_TP_ADD_TC(tp, logf_nan);
-	ATF_TP_ADD_TC(tp, logf_inf_neg);
-	ATF_TP_ADD_TC(tp, logf_inf_pos);
-	ATF_TP_ADD_TC(tp, logf_one_pos);
-	ATF_TP_ADD_TC(tp, logf_zero_neg);
-	ATF_TP_ADD_TC(tp, logf_zero_pos);
+	ATF_TP_ADD_TC(tp, log10_invalid);
+	ATF_TP_ADD_TC(tp, log10_zero);
+	ATF_TP_ADD_TC(tp, log10_exact);
+	ATF_TP_ADD_TC(tp, log10_inf);
+
+	ATF_TP_ADD_TC(tp, log1p_invalid);
+	ATF_TP_ADD_TC(tp, log1p_neg_one);
+	ATF_TP_ADD_TC(tp, log1p_exact);
+	ATF_TP_ADD_TC(tp, log1p_inf);
+
+	ATF_TP_ADD_TC(tp, log2_invalid);
+	ATF_TP_ADD_TC(tp, log2_zero);
+	ATF_TP_ADD_TC(tp, log2_exact);
+	ATF_TP_ADD_TC(tp, log2_inf);
+
+	ATF_TP_ADD_TC(tp, log_invalid);
+	ATF_TP_ADD_TC(tp, log_zero);
+	ATF_TP_ADD_TC(tp, log_normal);
+	ATF_TP_ADD_TC(tp, log_inf);
 
 	return atf_no_error();
 }

Reply via email to