Hi Harald,

Harald Anlauf wrote:
This breaks bootstrap here on openSUSE Leap 15.6 with mpfr-4.0.2:

../../gcc-trunk/gcc/fortran/simplify.cc: In function 'gfc_expr* gfc_simplify_cospi(gfc_expr*)': ../../gcc-trunk/gcc/fortran/simplify.cc:2305:3: error: 'mpfr_fmod_ui' was not declared in this scope; did you mean 'mpfr_fmodquo'?
 2305 |   mpfr_fmod_ui (cs, n, 2, GFC_RND_MODE);
      |   ^~~~~~~~~~~~

Interestingly, mpfr_fmod_ui has been added only in 4.2.0,
at the same time as mpfr_sinpi.

Solution is to use mpfr_fmod.

I have now committed the attached patch as r16-940-ga64a7f0a6cf8af.

* * *

I build GCC successfully with mpfr 3.1.6 and "make check-fortran"
in $build/gcc was also successful. Except for the following fails:

I get an ICE for gfortran.dg/complex_intrinsic_8.f90 in gfc_simplify_atan:

mpfr/src/init2.c:52: MPFR assertion failed:
   p >= 2 && p <= ((mpfr_prec_t)((mpfr_uprec_t)(~(mpfr_uprec_t)0)>>1))

but that looks unrelated. Likewise (same assert in init2.c) for
arith_power via gfortran.dg/integer_exponentiation_4.f90 and
in gimple_resimplify2 (with -O1) for /gfortran.dg/large_real_kind_2.F90.

As those seem to be mpfr bugs, they don't trigger for the ...pi functions,
I have decided to ignore them when applying the patch.

Sorry for the breakage!

Tobias

PS: I tried to build mpfr 3.1.0 in tree but that had compile issues with my
GCC 14 system compiler; but at least mpfr-3.1.6 seems to build fine. I think
MPFR 4.0.x avoids the assert.


@Yuao: To build mpfr in tree, you can use:
  ./contrib/download_prerequisites
and the then build like normal. This installs multiple libraries - but not
all are needed and mpfr 4.1.0 might be to new. Thus, the following is better:

For only mpfr, the simplest is to download it from 
https://www.mpfr.org/history.html
unpack the tarball, and add a symlink 'ln -s mpfr-3.1.6 mpfr'. If you now build
GCC, it will automatically first configure and build 'mpfr' and then use it to 
build
GCC.
Fortran: gfc_simplify_{cospi,sinpi} - fix for MPFR < 4.2.0

gcc/fortran/ChangeLog:

	PR fortran/113152
	* simplify.cc (gfc_simplify_cospi, gfc_simplify_sinpi): Avoid using
	mpfr_fmod_ui in the MPFR < 4.2.0 version.

 gcc/fortran/simplify.cc | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/gcc/fortran/simplify.cc b/gcc/fortran/simplify.cc
index 2ceb479faf5..b25cd2c2388 100644
--- a/gcc/fortran/simplify.cc
+++ b/gcc/fortran/simplify.cc
@@ -2288,10 +2288,10 @@ gfc_simplify_cospi (gfc_expr *x)
 #if MPFR_VERSION >= MPFR_VERSION_NUM(4, 2, 0)
   mpfr_cospi (result->value.real, x->value.real, GFC_RND_MODE);
 #else
-  mpfr_t cs, n, r;
+  mpfr_t cs, n, r, two;
   int s;
 
-  mpfr_inits2 (2 * mpfr_get_prec (x->value.real), cs, n, r, NULL);
+  mpfr_inits2 (2 * mpfr_get_prec (x->value.real), cs, n, r, two, NULL);
 
   mpfr_abs (r, x->value.real, GFC_RND_MODE);
   mpfr_modf (n, r, r, GFC_RND_MODE);
@@ -2302,7 +2302,8 @@ gfc_simplify_cospi (gfc_expr *x)
       return result;
     }
 
-  mpfr_fmod_ui (cs, n, 2, GFC_RND_MODE);
+  mpfr_set_ui (two, 2, GFC_RND_MODE);
+  mpfr_fmod (cs, n, two, GFC_RND_MODE);
   s = mpfr_cmp_ui (cs, 0) == 0 ? 1 : -1;
 
   mpfr_const_pi (cs, GFC_RND_MODE);
@@ -2310,7 +2311,7 @@ gfc_simplify_cospi (gfc_expr *x)
   mpfr_cos (cs, cs, GFC_RND_MODE);
   mpfr_mul_si (result->value.real, cs, s, GFC_RND_MODE);
 
-  mpfr_clears (cs, n, r, NULL);
+  mpfr_clears (cs, n, r, two, NULL);
 #endif
 
   return range_check (result, "COSPI");
@@ -2329,10 +2330,10 @@ gfc_simplify_sinpi (gfc_expr *x)
 #if MPFR_VERSION >= MPFR_VERSION_NUM(4, 2, 0)
   mpfr_sinpi (result->value.real, x->value.real, GFC_RND_MODE);
 #else
-  mpfr_t sn, n, r;
+  mpfr_t sn, n, r, two;
   int s;
 
-  mpfr_inits2 (2 * mpfr_get_prec (x->value.real), sn, n, r, NULL);
+  mpfr_inits2 (2 * mpfr_get_prec (x->value.real), sn, n, r, two, NULL);
 
   mpfr_abs (r, x->value.real, GFC_RND_MODE);
   mpfr_modf (n, r, r, GFC_RND_MODE);
@@ -2343,7 +2344,8 @@ gfc_simplify_sinpi (gfc_expr *x)
       return result;
     }
 
-  mpfr_fmod_ui (sn, n, 2, GFC_RND_MODE);
+  mpfr_set_ui (two, 2, GFC_RND_MODE);
+  mpfr_fmod (sn, n, two, GFC_RND_MODE);
   s = mpfr_cmp_si (x->value.real, 0) < 0 ? -1 : 1;
   s *= mpfr_cmp_ui (sn, 0) == 0 ? 1 : -1;
 
@@ -2352,7 +2354,7 @@ gfc_simplify_sinpi (gfc_expr *x)
   mpfr_sin (sn, sn, GFC_RND_MODE);
   mpfr_mul_si (result->value.real, sn, s, GFC_RND_MODE);
 
-  mpfr_clears (sn, n, r, NULL);
+  mpfr_clears (sn, n, r, two, NULL);
 #endif
 
   return range_check (result, "SINPI");

Reply via email to