summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2020-06-18 17:17:18 +0000
committervlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2020-06-18 17:17:18 +0000
commitd0cecbb99dcbc451ef87ebd93e7cd2b51b544743 (patch)
tree6588eeda6b0fdb8cf133beb7460f46daab1ed1db
parent2e9527809bd24b52a83cbd1120302bad13f2a00e (diff)
downloadmpfr-d0cecbb99dcbc451ef87ebd93e7cd2b51b544743.tar.gz
Merged r14021-14036 from the trunk:
r14021: [tests] Skip tabort_defalloc1 and tabort_defalloc2 under Valgrind, as Valgrind complains due to the large allocation size. * mpfr-test.h, tests.c: added tests_run_within_valgrind() function to guess whether the test runs within Valgrind. * tabort_defalloc1.c, tabort_defalloc2.c: skip the test (exit code 77) if this function returns true. r14022-14023: [tests/tset_ld.c] In bug_20160907 (tests on subnormals, specific to x86 extended precision): * Replaced an assertion by a test with detailed output. * In case of incorrect result, detect whether Valgrind is used and one gets the result obtained with Valgrind due to https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=890215 https://bugs.kde.org/show_bug.cgi?id=421262 (long double behaves as double); in this case, output a message without an error since Valgrind is the only cause of the miscalculation. * Corrected a value in a test, which did not match the comment. r14024-14027: [src/digamma.c] * Replaced some MPFR_EXP / mpfr_get_exp by MPFR_GET_EXP to check that the MPFR number has an exponent (i.e. it is not a special value). * Added an integer overflow check on a precision. * Fixed a bug: an exponent was read while the value could be zero. r14028: [tests/tdigamma.c] Increase the number of tests. r14029,14031: [doc/mpfr.texi] Specify the range of b for mpfr_get_str_ndigits. r14030: [src/get_str.c] Since the mpfr_get_str_ndigits function is in the public API, use MPFR_ASSERTN instead of MPFR_ASSERTD on the condition on the argument b in order to get an assertion failure (by default) if this condition is not satisfied. r14032,14035-14036: [src/mpfr-longlong.h] Applied patch on https://gmplib.org/list-archives/gmp-bugs/2020-June/004807.html to fix add_ssaaaa and sub_ddmmss on arm / aarch64, in order to resolve https://sympa.inria.fr/sympa/arc/mpfr/2020-06/msg00017.html https://sympa.inria.fr/sympa/arc/mpfr/2020-06/msg00059.html r14034: [tests/tcmp_ui.c] Added a comment about a failing test with tcc if one adds tcc support for macros using __builtin_constant_p in mpfr.h by testing __TINYC__. Bug report against tcc: https://savannah.nongnu.org/bugs/?58606 git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/branches/4.1@14042 280ebfd0-de03-0410-8827-d642c229c3f4
-rw-r--r--doc/mpfr.texi4
-rw-r--r--src/digamma.c49
-rw-r--r--src/get_str.c2
-rw-r--r--src/mpfr-longlong.h147
-rw-r--r--tests/mpfr-test.h1
-rw-r--r--tests/tabort_defalloc1.c5
-rw-r--r--tests/tabort_defalloc2.c5
-rw-r--r--tests/tcmp_ui.c6
-rw-r--r--tests/tdigamma.c2
-rw-r--r--tests/tests.c13
-rw-r--r--tests/tset_ld.c27
11 files changed, 134 insertions, 127 deletions
diff --git a/doc/mpfr.texi b/doc/mpfr.texi
index 4caa3cd50..89b7da28a 100644
--- a/doc/mpfr.texi
+++ b/doc/mpfr.texi
@@ -1735,6 +1735,10 @@ m = 1 + ceil(@var{p}*log(2)/log(@var{b})),
$m = 1 + \left\lceil @var{p} {\log 2 \over \log @var{b}} \right\rceil$,
@end tex
with @var{p} replaced by @var{p}@minus{}1 if @var{b} is a power of 2.
+
+The argument @var{b} must be in the range 2 to 62; this is the range of bases
+supported by the @code{mpfr_get_str} function. Note that contrary to the base
+argument of this function, negative values are not accepted.
@end deftypefun
@anchor{mpfr_get_str}
diff --git a/src/digamma.c b/src/digamma.c
index 0fdf9a7f7..e9e8389b1 100644
--- a/src/digamma.c
+++ b/src/digamma.c
@@ -22,6 +22,10 @@ https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
#include "mpfr-impl.h"
+/* FIXME: Check that MPFR_GET_EXP can only be called on regular values
+ (in r14025, this is not the case) and that there cannot be integer
+ overflows. */
+
/* Put in s an approximation of digamma(x).
Assumes x >= 2.
Assumes s does not overlap with x.
@@ -36,7 +40,7 @@ mpfr_digamma_approx (mpfr_ptr s, mpfr_srcptr x)
mpfr_exp_t e, exps, f, expu;
unsigned long n;
- MPFR_ASSERTN(MPFR_IS_POS(x) && (MPFR_EXP(x) >= 2));
+ MPFR_ASSERTN (MPFR_IS_POS (x) && MPFR_GET_EXP (x) >= 2);
mpfr_init2 (t, p);
mpfr_init2 (u, p);
@@ -74,13 +78,13 @@ mpfr_digamma_approx (mpfr_ptr s, mpfr_srcptr x)
/* if the terms 'u' are decreasing by a factor two at least,
then the error coming from those is bounded by
sum((10n+4)/2^n, n=1..infinity) = 24 */
- exps = mpfr_get_exp (s);
- expu = mpfr_get_exp (u);
+ exps = MPFR_GET_EXP (s);
+ expu = MPFR_GET_EXP (u);
if (expu < exps - (mpfr_exp_t) p)
break;
mpfr_sub (s, s, u, MPFR_RNDN); /* error <= 24 + n/2 */
- if (mpfr_get_exp (s) < exps)
- e <<= exps - mpfr_get_exp (s);
+ if (MPFR_GET_EXP (s) < exps)
+ e <<= exps - MPFR_GET_EXP (s);
e ++; /* error in mpfr_sub */
f = 10 * n + 4;
while (expu < exps)
@@ -111,9 +115,9 @@ mpfr_digamma_approx (mpfr_ptr s, mpfr_srcptr x)
static int
mpfr_digamma_reflection (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
{
- mpfr_prec_t p = MPFR_PREC(y) + 10, q;
+ mpfr_prec_t p = MPFR_PREC(y) + 10;
mpfr_t t, u, v;
- mpfr_exp_t e1, expv;
+ mpfr_exp_t e1, expv, expx, q;
int inex;
MPFR_ZIV_DECL (loop);
@@ -125,12 +129,14 @@ mpfr_digamma_reflection (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
q = PREC(x)-EXP(x) is ok, otherwise if -1 <= x < 0, q = PREC(x)-EXP(x)
is ok, otherwise for x < -1, PREC(x) is ok if EXP(x) <= PREC(x),
otherwise we need EXP(x) */
- if (MPFR_EXP(x) < 0)
- q = MPFR_PREC(x) + 1 - MPFR_EXP(x);
- else if (MPFR_EXP(x) <= MPFR_PREC(x))
+ expx = MPFR_GET_EXP (x);
+ if (expx < 0)
+ q = MPFR_PREC(x) + 1 - expx;
+ else if (expx <= MPFR_PREC(x))
q = MPFR_PREC(x) + 1;
else
- q = MPFR_EXP(x);
+ q = expx;
+ MPFR_ASSERTN (q <= MPFR_PREC_MAX);
mpfr_init2 (u, q);
MPFR_DBGRES(inex = mpfr_ui_sub (u, 1, x, MPFR_RNDN));
MPFR_ASSERTN(inex == 0);
@@ -153,10 +159,10 @@ mpfr_digamma_reflection (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
{
mpfr_const_pi (v, MPFR_RNDN); /* v = Pi*(1+theta) for |theta|<=2^(-p) */
mpfr_mul (t, v, x, MPFR_RNDN); /* (1+theta)^2 */
- e1 = MPFR_EXP(t) - (mpfr_exp_t) p + 1; /* bound for t: err(t) <= 2^e1 */
+ e1 = MPFR_GET_EXP(t) - (mpfr_exp_t) p + 1; /* bound for t: err(t) <= 2^e1 */
mpfr_cot (t, t, MPFR_RNDN);
/* cot(t * (1+h)) = cot(t) - theta * (1 + cot(t)^2) with |theta|<=t*h */
- if (MPFR_EXP(t) > 0)
+ if (MPFR_GET_EXP(t) > 0)
e1 = e1 + 2 * MPFR_EXP(t) + 1;
else
e1 = e1 + 1;
@@ -165,9 +171,9 @@ mpfr_digamma_reflection (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
mpfr_mul (t, t, v, MPFR_RNDN);
e1 ++;
mpfr_digamma (v, u, MPFR_RNDN); /* error <= 1/2 ulp */
- expv = MPFR_EXP(v);
+ expv = MPFR_GET_EXP (v);
mpfr_sub (v, v, t, MPFR_RNDN);
- if (MPFR_EXP(v) < MPFR_EXP(t))
+ if (MPFR_GET_EXP (v) < MPFR_GET_EXP (t))
e1 += MPFR_EXP(t) - MPFR_EXP(v); /* scale error for t wrt new v */
/* now take into account the 1/2 ulp error for v */
if (expv - MPFR_EXP(v) - 1 > e1)
@@ -209,7 +215,7 @@ mpfr_digamma_positive (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
("y[%Pu]=%.*Rg inexact=%d", mpfr_get_prec(y), mpfr_log_prec, y, inex));
/* compute a precision q such that x+1 is exact */
- if (MPFR_PREC(x) < MPFR_EXP(x))
+ if (MPFR_PREC(x) < MPFR_GET_EXP(x))
q = MPFR_EXP(x);
else
q = MPFR_PREC(x) + 1;
@@ -265,11 +271,14 @@ mpfr_digamma_positive (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
}
for (erru = 0; j > 1; erru++, j = (j + 1) / 2);
errt = mpfr_digamma_approx (t, x_plus_j);
- expt = MPFR_EXP(t);
+ expt = MPFR_GET_EXP (t);
mpfr_sub (t, t, u, MPFR_RNDN);
- if (MPFR_EXP(t) < expt)
+ if (MPFR_GET_EXP (t) < expt)
errt += expt - MPFR_EXP(t);
- if (MPFR_EXP(t) < MPFR_EXP(u))
+ /* Warning: if u is zero (which happens when x_plus_j >= min at the
+ beginning of the while loop above), EXP(u) is not defined.
+ In this case we have no error from u. */
+ if (MPFR_NOTZERO(u) && MPFR_GET_EXP (t) < MPFR_GET_EXP (u))
erru += MPFR_EXP(u) - MPFR_EXP(t);
if (errt > erru)
errt = errt + 1;
@@ -352,7 +361,7 @@ mpfr_digamma (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
|y - Digamma(x)| >= 2^(-2n-1)ufp(y), and rounding -1/x gives the correct result.
If x < 2^E, then y > 2^(-E), thus ufp(y) > 2^(-E-1).
A sufficient condition is thus EXP(x) <= -2 MAX(PREC(x),PREC(Y)). */
- if (MPFR_EXP(x) < -2)
+ if (MPFR_GET_EXP (x) < -2)
{
if (MPFR_EXP(x) <= -2 * (mpfr_exp_t) MAX(MPFR_PREC(x), MPFR_PREC(y)))
{
diff --git a/src/get_str.c b/src/get_str.c
index 306d332f7..7c530ec7a 100644
--- a/src/get_str.c
+++ b/src/get_str.c
@@ -2484,7 +2484,7 @@ mpfr_ceil_mul (mpfr_exp_t e, int beta, int i)
size_t
mpfr_get_str_ndigits (int b, mpfr_prec_t p)
{
- MPFR_ASSERTD(2 <= b && b <= 62);
+ MPFR_ASSERTN (2 <= b && b <= 62);
/* deal first with power of two bases, since even for those, mpfr_ceil_mul
might return a value too large by 1 */
diff --git a/src/mpfr-longlong.h b/src/mpfr-longlong.h
index b13c79c65..83eda2f51 100644
--- a/src/mpfr-longlong.h
+++ b/src/mpfr-longlong.h
@@ -6,7 +6,9 @@ This file is part of the GNU MPFR Library and has been copied from
GNU MP 6.2.0, with the following changes:
* the copyright notice (note: only LGPL 3+ is used in MPFR);
* the code declared as added for MPFR just below these comments;
- * __GMP_DECLSPEC renamed to __MPFR_DECLSPEC.
+ * __GMP_DECLSPEC renamed to __MPFR_DECLSPEC;
+ * patch on https://gmplib.org/list-archives/gmp-bugs/2020-June/004807.html
+ for arm / aarch64 / 64-bit powerpc applied.
The GNU MPFR Library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
@@ -441,20 +443,12 @@ long __MPN(count_leading_zeros) (UDItype);
#if defined (__arm__) && (defined (__thumb2__) || !defined (__thumb__)) \
&& W_TYPE_SIZE == 32
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
- do { \
- if (__builtin_constant_p (bl) && -(USItype)(bl) < 0x100) \
- __asm__ ("subs\t%1, %4, %5\n\tadc\t%0, %2, %3" \
- : "=r" (sh), "=&r" (sl) \
- : "r" (ah), "rI" (bh), \
- "%r" (al), "rI" (-(USItype)(bl)) __CLOBBER_CC); \
- else \
- __asm__ ("adds\t%1, %4, %5\n\tadc\t%0, %2, %3" \
+ __asm__ ("adds\t%1, %4, %5\n\tadc\t%0, %2, %3" \
: "=r" (sh), "=&r" (sl) \
- : "r" (ah), "rI" (bh), "%r" (al), "rI" (bl) __CLOBBER_CC); \
- } while (0)
+ : "r" (ah), "rI" (bh), "%r" (al), "rI" (bl) __CLOBBER_CC)
/* FIXME: Extend the immediate range for the low word by using both ADDS and
- SUBS, since they set carry in the same way. Note: We need separate
- definitions for thumb and non-thumb due to the absence of RSC under thumb. */
+ SUBS, since they set carry in the same way. We need separate definitions
+ for thumb and non-thumb since thumb lacks RSC. */
#if defined (__thumb__)
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
do { \
@@ -569,31 +563,15 @@ extern UWtype __MPN(udiv_qrnnd) (UWtype *, UWtype, UWtype, UWtype);
/* FIXME: Extend the immediate range for the low word by using both
ADDS and SUBS, since they set carry in the same way. */
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
- do { \
- if (__builtin_constant_p (bl) && -(UDItype)(bl) < 0x1000) \
- __asm__ ("subs\t%1, %x4, %5\n\tadc\t%0, %x2, %x3" \
- : "=r" (sh), "=&r" (sl) \
- : "rZ" ((UDItype)(ah)), "rZ" ((UDItype)(bh)), \
- "%r" ((UDItype)(al)), "rI" (-(UDItype)(bl)) __CLOBBER_CC);\
- else \
- __asm__ ("adds\t%1, %x4, %5\n\tadc\t%0, %x2, %x3" \
- : "=r" (sh), "=&r" (sl) \
- : "rZ" ((UDItype)(ah)), "rZ" ((UDItype)(bh)), \
- "%r" ((UDItype)(al)), "rI" ((UDItype)(bl)) __CLOBBER_CC);\
- } while (0)
+ __asm__ ("adds\t%1, %x4, %5\n\tadc\t%0, %x2, %x3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "rZ" ((UDItype)(ah)), "rZ" ((UDItype)(bh)), \
+ "%r" ((UDItype)(al)), "rI" ((UDItype)(bl)) __CLOBBER_CC)
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
- do { \
- if (__builtin_constant_p (bl) && -(UDItype)(bl) < 0x1000) \
- __asm__ ("adds\t%1, %x4, %5\n\tsbc\t%0, %x2, %x3" \
- : "=r,r" (sh), "=&r,&r" (sl) \
- : "rZ,rZ" ((UDItype)(ah)), "rZ,rZ" ((UDItype)(bh)), \
- "r,Z" ((UDItype)(al)), "rI,r" (-(UDItype)(bl)) __CLOBBER_CC);\
- else \
- __asm__ ("subs\t%1, %x4, %5\n\tsbc\t%0, %x2, %x3" \
- : "=r,r" (sh), "=&r,&r" (sl) \
- : "rZ,rZ" ((UDItype)(ah)), "rZ,rZ" ((UDItype)(bh)), \
- "r,Z" ((UDItype)(al)), "rI,r" ((UDItype)(bl)) __CLOBBER_CC);\
- } while(0);
+ __asm__ ("subs\t%1, %x4, %5\n\tsbc\t%0, %x2, %x3" \
+ : "=r,r" (sh), "=&r,&r" (sl) \
+ : "rZ,rZ" ((UDItype)(ah)), "rZ,rZ" ((UDItype)(bh)), \
+ "r,Z" ((UDItype)(al)), "rI,r" ((UDItype)(bl)) __CLOBBER_CC)
#if __GMP_GNUC_PREREQ (4,9)
#define umul_ppmm(w1, w0, u, v) \
do { \
@@ -1496,73 +1474,38 @@ extern UWtype __MPN(udiv_qrnnd) (UWtype *, UWtype, UWtype, UWtype);
"%r" ((UDItype)(al)), "rI" ((UDItype)(bl)) \
__CLOBBER_CC); \
} while (0)
-/* We use "*rI" for the constant operand here, since with just "I", gcc barfs.
- This might seem strange, but gcc folds away the dead code late. */
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
do { \
- if (__builtin_constant_p (bl) && bl > -0x8000 && bl <= 0x8000) { \
- if (__builtin_constant_p (ah) && (ah) == 0) \
- __asm__ ("addic %1,%3,%4\n\tsubfze %0,%2" \
- : "=r" (sh), "=&r" (sl) \
- : "r" ((UDItype)(bh)), \
- "rI" ((UDItype)(al)), "*rI" (-((UDItype)(bl))) \
- __CLOBBER_CC); \
- else if (__builtin_constant_p (ah) && (ah) == ~(UDItype) 0) \
- __asm__ ("addic %1,%3,%4\n\tsubfme %0,%2" \
- : "=r" (sh), "=&r" (sl) \
- : "r" ((UDItype)(bh)), \
- "rI" ((UDItype)(al)), "*rI" (-((UDItype)(bl))) \
- __CLOBBER_CC); \
- else if (__builtin_constant_p (bh) && (bh) == 0) \
- __asm__ ("addic %1,%3,%4\n\taddme %0,%2" \
- : "=r" (sh), "=&r" (sl) \
- : "r" ((UDItype)(ah)), \
- "rI" ((UDItype)(al)), "*rI" (-((UDItype)(bl))) \
- __CLOBBER_CC); \
- else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \
- __asm__ ("addic %1,%3,%4\n\taddze %0,%2" \
- : "=r" (sh), "=&r" (sl) \
- : "r" ((UDItype)(ah)), \
- "rI" ((UDItype)(al)), "*rI" (-((UDItype)(bl))) \
- __CLOBBER_CC); \
- else \
- __asm__ ("addic %1,%4,%5\n\tsubfe %0,%3,%2" \
- : "=r" (sh), "=&r" (sl) \
- : "r" ((UDItype)(ah)), "r" ((UDItype)(bh)), \
- "rI" ((UDItype)(al)), "*rI" (-((UDItype)(bl))) \
- __CLOBBER_CC); \
- } else { \
- if (__builtin_constant_p (ah) && (ah) == 0) \
- __asm__ ("subf%I3c %1,%4,%3\n\tsubfze %0,%2" \
- : "=r" (sh), "=&r" (sl) \
- : "r" ((UDItype)(bh)), \
- "rI" ((UDItype)(al)), "r" ((UDItype)(bl)) \
- __CLOBBER_CC); \
- else if (__builtin_constant_p (ah) && (ah) == ~(UDItype) 0) \
- __asm__ ("subf%I3c %1,%4,%3\n\tsubfme %0,%2" \
- : "=r" (sh), "=&r" (sl) \
- : "r" ((UDItype)(bh)), \
- "rI" ((UDItype)(al)), "r" ((UDItype)(bl)) \
- __CLOBBER_CC); \
- else if (__builtin_constant_p (bh) && (bh) == 0) \
- __asm__ ("subf%I3c %1,%4,%3\n\taddme %0,%2" \
- : "=r" (sh), "=&r" (sl) \
- : "r" ((UDItype)(ah)), \
- "rI" ((UDItype)(al)), "r" ((UDItype)(bl)) \
- __CLOBBER_CC); \
- else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \
- __asm__ ("subf%I3c %1,%4,%3\n\taddze %0,%2" \
- : "=r" (sh), "=&r" (sl) \
- : "r" ((UDItype)(ah)), \
- "rI" ((UDItype)(al)), "r" ((UDItype)(bl)) \
- __CLOBBER_CC); \
- else \
- __asm__ ("subf%I4c %1,%5,%4\n\tsubfe %0,%3,%2" \
- : "=r" (sh), "=&r" (sl) \
- : "r" ((UDItype)(ah)), "r" ((UDItype)(bh)), \
- "rI" ((UDItype)(al)), "r" ((UDItype)(bl)) \
- __CLOBBER_CC); \
- } \
+ if (__builtin_constant_p (ah) && (ah) == 0) \
+ __asm__ ("subf%I3c %1,%4,%3\n\tsubfze %0,%2" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" ((UDItype)(bh)), \
+ "rI" ((UDItype)(al)), "r" ((UDItype)(bl)) \
+ __CLOBBER_CC); \
+ else if (__builtin_constant_p (ah) && (ah) == ~(UDItype) 0) \
+ __asm__ ("subf%I3c %1,%4,%3\n\tsubfme %0,%2" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" ((UDItype)(bh)), \
+ "rI" ((UDItype)(al)), "r" ((UDItype)(bl)) \
+ __CLOBBER_CC); \
+ else if (__builtin_constant_p (bh) && (bh) == 0) \
+ __asm__ ("subf%I3c %1,%4,%3\n\taddme %0,%2" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" ((UDItype)(ah)), \
+ "rI" ((UDItype)(al)), "r" ((UDItype)(bl)) \
+ __CLOBBER_CC); \
+ else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \
+ __asm__ ("subf%I3c %1,%4,%3\n\taddze %0,%2" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" ((UDItype)(ah)), \
+ "rI" ((UDItype)(al)), "r" ((UDItype)(bl)) \
+ __CLOBBER_CC); \
+ else \
+ __asm__ ("subf%I4c %1,%5,%4\n\tsubfe %0,%3,%2" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" ((UDItype)(ah)), "r" ((UDItype)(bh)), \
+ "rI" ((UDItype)(al)), "r" ((UDItype)(bl)) \
+ __CLOBBER_CC); \
} while (0)
#endif /* ! _LONG_LONG_LIMB */
#define count_leading_zeros(count, x) \
diff --git a/tests/mpfr-test.h b/tests/mpfr-test.h
index d9891deec..e33fc19ae 100644
--- a/tests/mpfr-test.h
+++ b/tests/mpfr-test.h
@@ -113,6 +113,7 @@ void tests_start_mpfr (void);
void tests_end_mpfr (void);
void tests_expect_abort (void);
+int tests_run_within_valgrind (void);
int mpfr_set_machine_rnd_mode (mpfr_rnd_t);
void mpfr_test_init (void);
diff --git a/tests/tabort_defalloc1.c b/tests/tabort_defalloc1.c
index d4c903863..59d715445 100644
--- a/tests/tabort_defalloc1.c
+++ b/tests/tabort_defalloc1.c
@@ -35,6 +35,11 @@ https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
int
main (int argc, char **argv)
{
+ /* Disable this test under Valgrind, which complains due to the
+ large allocation size. */
+ if (tests_run_within_valgrind ())
+ return 77;
+
tests_start_mpfr ();
tests_expect_abort ();
diff --git a/tests/tabort_defalloc2.c b/tests/tabort_defalloc2.c
index 9187b47ae..7ae942272 100644
--- a/tests/tabort_defalloc2.c
+++ b/tests/tabort_defalloc2.c
@@ -37,6 +37,11 @@ main (int argc, char **argv)
{
void *ptr;
+ /* Disable this test under Valgrind, which complains due to the
+ large allocation size. */
+ if (tests_run_within_valgrind ())
+ return 77;
+
tests_start_mpfr ();
tests_expect_abort ();
diff --git a/tests/tcmp_ui.c b/tests/tcmp_ui.c
index b683fb5cd..831bf341c 100644
--- a/tests/tcmp_ui.c
+++ b/tests/tcmp_ui.c
@@ -113,6 +113,12 @@ check_macros (void)
/* Failure in r13626 on x86_64 with the clang-9 1:9-1 Debian package,
with any optimization level: c = 2 instead of 1
Bug report: https://bugs.llvm.org/show_bug.cgi?id=43557 */
+ /* [2020-06-17]
+ If one adds tcc support for macros using __builtin_constant_p
+ in mpfr.h by testing __TINYC__, one also gets a failure.
+ Bug report: https://savannah.nongnu.org/bugs/?58606
+ "__builtin_constant_p is buggy on argument with side effect and
+ constant value" */
printf ("Error 3 on mpfr_cmp_ui(x,17) in check_macros\n"
"(c = %d instead of 1)\n", c);
exit (1);
diff --git a/tests/tdigamma.c b/tests/tdigamma.c
index 2f42f2288..2eab8037d 100644
--- a/tests/tdigamma.c
+++ b/tests/tdigamma.c
@@ -56,7 +56,7 @@ main (int argc, char *argv[])
special ();
- test_generic (MPFR_PREC_MIN, 100, 2);
+ test_generic (MPFR_PREC_MIN, 200, 20);
data_check ("data/digamma", mpfr_digamma, "mpfr_digamma");
diff --git a/tests/tests.c b/tests/tests.c
index e51962b02..0a5fffaab 100644
--- a/tests/tests.c
+++ b/tests/tests.c
@@ -1179,3 +1179,16 @@ tests_expect_abort (void)
exit (77);
#endif
}
+
+/* Guess whether the test runs within Valgrind. */
+int
+tests_run_within_valgrind (void)
+{
+ char *p;
+
+ p = getenv ("LD_PRELOAD");
+ if (p == NULL)
+ return 0;
+ return (strstr (p, "/valgrind/") != NULL ||
+ strstr (p, "/vgpreload") != NULL);
+}
diff --git a/tests/tset_ld.c b/tests/tset_ld.c
index c032108ae..23a82e106 100644
--- a/tests/tset_ld.c
+++ b/tests/tset_ld.c
@@ -478,15 +478,36 @@ bug_20160907 (void)
ld = mpfr_get_ld (mp, MPFR_RNDU);
mpfr_set_ld (mp, ld, MPFR_RNDU);
/* mp is 2^e rounded up, thus should be >= 2^e */
- MPFR_ASSERTN(mpfr_cmp_ui_2exp (mp, 1, e) >= 0);
+ if (mpfr_cmp_ui_2exp (mp, 1, e) < 0)
+ {
+ if (tests_run_within_valgrind () && MPFR_IS_ZERO (mp))
+ {
+ /* Since this is not a bug in MPFR and it is just caused by
+ Valgrind, let's output a message and skip the remaining
+ part of the test without an error. Note that the message
+ will be not be visible via "make check".
+ Note that the other tests do not fail probably because
+ long double has the same behavior as double (which is
+ allowed by the C standard), but here this is a test that
+ is specific to x86 extended precision. */
+ printf
+ ("Error in bug_20160907 due to a bug in Valgrind.\n"
+ "https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=890215\n"
+ "https://bugs.kde.org/show_bug.cgi?id=421262\n");
+ break;
+ }
+ printf ("Error, expected value >= 2^(%ld)\n", e);
+ printf ("got "); mpfr_dump (mp);
+ exit (1);
+ }
mpfr_set_ui_2exp (mp, 1, e, MPFR_RNDN);
ld = mpfr_get_ld (mp, MPFR_RNDD);
mpfr_set_ld (mp, ld, MPFR_RNDD);
/* mp is 2^e rounded down, thus should be <= 2^e */
- if (mpfr_cmp_ui_2exp (mp, 3, e) > 0)
+ if (mpfr_cmp_ui_2exp (mp, 1, e) > 0)
{
- printf ("Error, expected value <= 2^%ld\n", e);
+ printf ("Error, expected value <= 2^(%ld)\n", e);
printf ("got "); mpfr_dump (mp);
exit (1);
}