Dear all,

my fix for PR fortran/96711 adds a testcase that failed on powerpc64-*-*
as well as sparc*-sun-solaris2.11.  This is a consequence of the, say,
mess, on x86, where we have real kinds 4,8,10,16, with kind=10 being long
double and kind=16 being represented as float128, while on sparc real(16)
is mapped to long double.  I'm not going to comment on power, see PR for
details.

A minimal solution to the issue would extend an intermediate conversion
that is done for e.g. x86 to float128 to a conversion to long double
on platforms where the TYPE_PRECISION of long double equals 128.  This
solves the issue on sparc*-sun-solaris2.11, as confirmed by Rainer.

The attached patch does just this, and disables the testcase for target
powerpc*-*-*.  I expect a more sophisticated solution being needed for
that platform.

That said, the patch regtests cleanly on x86_64-pc-linux-gnu, and as
reported in the PR, sparc-sun-solaris2.11 and i386-pc-solaris2.11.

OK for master?  Or does anyone with better knowledge of the affected
platforms want to take over?  As this is a technical regression, it
should and could be fixed before the gcc-11 release.

My intention to either close the PR after committing, or changing it
into some appropriate state (SUSPENDED?) so that it can be handled
later, or to rather open a new PR that is finally a target issue.

Thanks,
Harald


PR/fortran 96983 - ICE compiling gfortran.dg/pr96711.f90

The fix for PR fortran/96711 introduced an intermediate conversion to
the float128 type that is used e.g. on x86 but not on some other
targets.  Use a conversion to long double on targets where this type
has a type precision of 128 bit.

gcc/fortran/ChangeLog:

        * trans-intrinsic.c (build_round_expr): Use conversion to long
        double when this type has a type precision of 128 bit.

gcc/testsuite/ChangeLog:

        * gfortran.dg/pr96711.f90: Skip testcase for target powerpc*-*-*.

diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index 32fe9886c57..552cdf5f19c 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -395,6 +395,13 @@ build_round_expr (tree arg, tree restype)
     fn = builtin_decl_for_precision (BUILT_IN_LROUND, argprec);
   else if (resprec <= LONG_LONG_TYPE_SIZE)
     fn = builtin_decl_for_precision (BUILT_IN_LLROUND, argprec);
+  else if (resprec == TYPE_PRECISION (long_double_type_node)
+	   && resprec >= argprec)
+    {
+      int kind = TYPE_PRECISION (long_double_type_node) / 8;
+      arg = fold_convert (long_double_type_node, arg);
+      fn = gfc_builtin_decl_for_float_kind (BUILT_IN_ROUND, kind);
+    }
   else if (resprec >= argprec && resprec == 128)
     {
       /* Search for a real kind suitable as temporary for conversion.  */
diff --git a/gcc/testsuite/gfortran.dg/pr96711.f90 b/gcc/testsuite/gfortran.dg/pr96711.f90
index 3761a8ea416..13b6e829ed6 100644
--- a/gcc/testsuite/gfortran.dg/pr96711.f90
+++ b/gcc/testsuite/gfortran.dg/pr96711.f90
@@ -3,6 +3,8 @@
 ! { dg-require-effective-target fortran_real_16 }
 ! { dg-additional-options "-fdump-tree-original" }
 ! { dg-final { scan-tree-dump-times "_gfortran_stop_numeric" 2 "original" } }
+! { dg-skip-if "" { "powerpc*-*-*" } }
+! This test expects a target that supports IEEE128.
 !
 ! PR fortran/96711 - ICE on NINT() Function

Reply via email to