https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94586

--- Comment #14 from Steve Kargl <sgk at troutmask dot apl.washington.edu> ---
On Wed, Apr 15, 2020 at 03:28:29PM +0000, dave.anglin at bell dot net wrote:
> 
> On 2020-04-15 11:02 a.m., sgk at troutmask dot apl.washington.edu wrote:
> > 
> > #if defined(HAVE_GFC_REAL_16)
> > # if defined(HAVE_GFC_REAL_10)
> > #  define GFC_REAL_16_IS_FLOAT128
> > #  if !defined(HAVE_FLOAT128)
> > #   error "Where has __float128 gone?"
> > #  endif
> > # else
> > #  define GFC_REAL_16_IS_LONG_DOUBLE
> > # endif
> > #endif
> > 
> > So, hpux does not have REAL(10) and has REAL(16).  This is doing
> > what it is designed to do based on the assumption that a target
> > like hpux with REAL(16) will define the long double functions 
> > with the 'l' suffix.  It seems the the fix for hpux is to change
> > the test to something like 
> > 
> > # if defined(HAVE_GFC_REAL_10) || defined(__HPUX__)
> > 
> > using, of course, whatever the relevant macro.  This will then
> > select the 'q' suffix.
> 
> I tried the above approach yesterday but it led to a couple of undefined
> symbols in libgfortran that
> caused a new test fail.  Possibly, the above might be a better overall 
> approach

It likely is the start of an approach, but it seems hpux is conflating 
long double and __float128, where it flips between an 'l' and 'q' suffix.
gfortran simply assumes a correspondence with C types and C99 naming
conventions (e.g., sinf, sin, and sinl).  If a target has REAL(4), REAL(8),
REAL(10), and REAL(16) the correspondence is float, double, long double,
and __float128, respectively.  If a target has REAL(4), REAL(8), and REAL(16),
then the correspondence is float, double, and long double.  There is no
__float128, and by extension, no functions with a 'q' suffix.  The long
double math function will end in 'l'.

> but this is what I ended
> up doing last night:
> 
> diff --git a/libgfortran/intrinsics/trigd.c b/libgfortran/intrinsics/trigd.c
> index 81699069545..970c60952ee 100644
> --- a/libgfortran/intrinsics/trigd.c
> +++ b/libgfortran/intrinsics/trigd.c
> @@ -27,6 +27,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  
> If
> not, see
> 
>  #include <math.h>
> 
> +#if (_POSIX_VERSION < 200112L)
> +#define fmaf(a,b,c) ((a)*(b)+(c))
> +#define fma(a,b,c) ((a)*(b)+(c))
> +#endif
> 
>  /*
>     For real x, let {x}_P or x_P be the closest representible number in the
> @@ -169,7 +173,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. 
> If not, see
>  #define COSD        cosd_r16
>  #define TAND        tand_r16
> 
> -#ifdef GFC_REAL_16_IS_FLOAT128 /* libquadmath.  */
> +#if defined(GFC_REAL_16_IS_FLOAT128) || !defined(HAVE_COSL) /* libquadmath. 
> */
>  #define SUFFIX(x) x ## q
>  #else
>  #define SUFFIX(x) x ## l
> 
> This fixed build of trigd.c.  I think I need to do something similar to fix
> dec_math.f90:
> 
> FAIL: gfortran.dg/dec_math.f90   -O0  (test for excess errors)
> Excess errors:
> /usr/ccs/bin/ld: Unsatisfied symbols:
>    tanl (first referenced in /var/tmp//ccLGIJFM.o) (code)
>    asinl (first referenced in /var/tmp//ccLGIJFM.o) (code)
>    sinl (first referenced in /var/tmp//ccLGIJFM.o) (code)
>    acosl (first referenced in /var/tmp//ccLGIJFM.o) (code)
>    atanl (first referenced in /var/tmp//ccLGIJFM.o) (code)
>    atan2l (first referenced in /var/tmp//ccLGIJFM.o) (code)
>    cosl (first referenced in /var/tmp//ccLGIJFM.o) (code)
> 
> It's the only new fail.

What does -fdump-tree-original show for

function foo(x)
   real(16) foo, x
   foo = cos(x)
end function foo

Reply via email to