[V2] powerpc: properly check for feenableexcept() on FreeBSD

Message ID 20220503102111.10406-1-pkubaj@FreeBSD.org
State New
Headers
Series [V2] powerpc: properly check for feenableexcept() on FreeBSD |

Commit Message

Piotr Kubaj May 3, 2022, 10:21 a.m. UTC
  From: Piotr Kubaj <pkubaj@FreeBSD.org>

FreeBSD/powerpc* has feenableexcept() defined in fenv.h header.

Signed-off-by: Piotr Kubaj <pkubaj@FreeBSD.org>
---
 libgfortran/configure    | 41 +++++++++++++++++++++++++++++++++++++++-
 libgfortran/configure.ac | 17 ++++++++++++++++-
 2 files changed, 56 insertions(+), 2 deletions(-)
  

Comments

Piotr Kubaj May 3, 2022, 10:33 a.m. UTC | #1
Here are gmake check-gfortran results requested by FX.

Before patching:
                === gfortran Summary ===

# of expected passes            65106
# of unexpected failures        6
# of expected failures          262
# of unsupported tests          367

After patching:
                === gfortran Summary ===

# of expected passes            65384
# of unexpected failures        6
# of expected failures          262
# of unsupported tests          373

In both cases, unexpected failures are:
FAIL: gfortran.dg/pr98076.f90   -O0  execution test
FAIL: gfortran.dg/pr98076.f90   -O1  execution test
FAIL: gfortran.dg/pr98076.f90   -O2  execution test
FAIL: gfortran.dg/pr98076.f90   -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions  execution test
FAIL: gfortran.dg/pr98076.f90   -O3 -g  execution test
FAIL: gfortran.dg/pr98076.f90   -Os  execution test

But this seems unrelated to my patch.

On 22-05-03 12:21:12, pkubaj@FreeBSD.org wrote:
> From: Piotr Kubaj <pkubaj@FreeBSD.org>
> 
> FreeBSD/powerpc* has feenableexcept() defined in fenv.h header.
> 
> Signed-off-by: Piotr Kubaj <pkubaj@FreeBSD.org>
> ---
>  libgfortran/configure    | 41 +++++++++++++++++++++++++++++++++++++++-
>  libgfortran/configure.ac | 17 ++++++++++++++++-
>  2 files changed, 56 insertions(+), 2 deletions(-)
> 
> diff --git a/libgfortran/configure b/libgfortran/configure
> index ae64dca3114..ad71694ef05 100755
> --- a/libgfortran/configure
> +++ b/libgfortran/configure
> @@ -27338,8 +27338,45 @@ fi
>  
>  
>  
> +case x$target in
> +  xpowerpc*-freebsd*)
> +    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fenv.h and feenableexcept" >&5
> +$as_echo_n "checking for fenv.h and feenableexcept... " >&6; }
> +if ${have_feenableexcept+:} false; then :
> +  $as_echo_n "(cached) " >&6
> +else
> +
> +        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
> +/* end confdefs.h.  */
> + #include <fenv.h>
> +int
> +main ()
> +{
> + feenableexcept(FE_DIVBYZERO | FE_INVALID);
> +  ;
> +  return 0;
> +}
> +_ACEOF
> +if ac_fn_c_try_compile "$LINENO"; then :
> +   have_feenableexcept="yes"
> +else
> +   have_feenableexcept="no"
> +fi
> +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
> +fi
> +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_feenableexcept" >&5
> +$as_echo "$have_feenableexcept" >&6; }
> +    if test "x$have_feenableexcept" = "xyes"; then
> +
> +cat >>confdefs.h <<_ACEOF
> +#define HAVE_FEENABLEEXCEPT 1
> +_ACEOF
> +
> +    fi;
> +    ;;
> +  *)
>  # Check for GNU libc feenableexcept
> -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for feenableexcept in -lm" >&5
> +    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for feenableexcept in -lm" >&5
>  $as_echo_n "checking for feenableexcept in -lm... " >&6; }
>  if ${ac_cv_lib_m_feenableexcept+:} false; then :
>    $as_echo_n "(cached) " >&6
> @@ -27384,6 +27421,8 @@ $as_echo "#define HAVE_FEENABLEEXCEPT 1" >>confdefs.h
>  
>  fi
>  
> +    ;;
> +esac
>  
>  # At least for glibc, clock_gettime is in librt.  But don't
>  # pull that in if it still doesn't give us the function we want.  This
> diff --git a/libgfortran/configure.ac b/libgfortran/configure.ac
> index 97cc490cb5e..2dd6d345b22 100644
> --- a/libgfortran/configure.ac
> +++ b/libgfortran/configure.ac
> @@ -602,8 +602,23 @@ fi
>  # Check whether we have a __float128 type, depends on enable_libquadmath_support
>  LIBGFOR_CHECK_FLOAT128
>  
> +case x$target in
> +  xpowerpc*-freebsd*)
> +    AC_CACHE_CHECK([for fenv.h and feenableexcept], have_feenableexcept, [
> +      AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
> +        [[ #include <fenv.h>  ]],
> +        [[ feenableexcept(FE_DIVBYZERO | FE_INVALID); ]])],
> +        [ have_feenableexcept="yes" ],
> +        [ have_feenableexcept="no"  ])])
> +    if test "x$have_feenableexcept" = "xyes"; then
> +      AC_DEFINE(HAVE_FEENABLEEXCEPT,1,[fenv.h includes feenableexcept])
> +    fi;
> +    ;;
> +  *)
>  # Check for GNU libc feenableexcept
> -AC_CHECK_LIB([m],[feenableexcept],[have_feenableexcept=yes AC_DEFINE([HAVE_FEENABLEEXCEPT],[1],[libm includes feenableexcept])])
> +    AC_CHECK_LIB([m],[feenableexcept],[have_feenableexcept=yes AC_DEFINE([HAVE_FEENABLEEXCEPT],[1],[libm includes feenableexcept])])
> +    ;;
> +esac
>  
>  # At least for glibc, clock_gettime is in librt.  But don't
>  # pull that in if it still doesn't give us the function we want.  This
> -- 
> 2.36.0
>
  
Piotr Kubaj May 10, 2022, 11:32 p.m. UTC | #2
Is there anything more required?

On 22-05-03 12:33:43, Piotr Kubaj wrote:
> Here are gmake check-gfortran results requested by FX.
> 
> Before patching:
>                 === gfortran Summary ===
> 
> # of expected passes            65106
> # of unexpected failures        6
> # of expected failures          262
> # of unsupported tests          367
> 
> After patching:
>                 === gfortran Summary ===
> 
> # of expected passes            65384
> # of unexpected failures        6
> # of expected failures          262
> # of unsupported tests          373
> 
> In both cases, unexpected failures are:
> FAIL: gfortran.dg/pr98076.f90   -O0  execution test
> FAIL: gfortran.dg/pr98076.f90   -O1  execution test
> FAIL: gfortran.dg/pr98076.f90   -O2  execution test
> FAIL: gfortran.dg/pr98076.f90   -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions  execution test
> FAIL: gfortran.dg/pr98076.f90   -O3 -g  execution test
> FAIL: gfortran.dg/pr98076.f90   -Os  execution test
> 
> But this seems unrelated to my patch.
> 
> On 22-05-03 12:21:12, pkubaj@FreeBSD.org wrote:
> > From: Piotr Kubaj <pkubaj@FreeBSD.org>
> > 
> > FreeBSD/powerpc* has feenableexcept() defined in fenv.h header.
> > 
> > Signed-off-by: Piotr Kubaj <pkubaj@FreeBSD.org>
> > ---
> >  libgfortran/configure    | 41 +++++++++++++++++++++++++++++++++++++++-
> >  libgfortran/configure.ac | 17 ++++++++++++++++-
> >  2 files changed, 56 insertions(+), 2 deletions(-)
> > 
> > diff --git a/libgfortran/configure b/libgfortran/configure
> > index ae64dca3114..ad71694ef05 100755
> > --- a/libgfortran/configure
> > +++ b/libgfortran/configure
> > @@ -27338,8 +27338,45 @@ fi
> >  
> >  
> >  
> > +case x$target in
> > +  xpowerpc*-freebsd*)
> > +    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fenv.h and feenableexcept" >&5
> > +$as_echo_n "checking for fenv.h and feenableexcept... " >&6; }
> > +if ${have_feenableexcept+:} false; then :
> > +  $as_echo_n "(cached) " >&6
> > +else
> > +
> > +        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
> > +/* end confdefs.h.  */
> > + #include <fenv.h>
> > +int
> > +main ()
> > +{
> > + feenableexcept(FE_DIVBYZERO | FE_INVALID);
> > +  ;
> > +  return 0;
> > +}
> > +_ACEOF
> > +if ac_fn_c_try_compile "$LINENO"; then :
> > +   have_feenableexcept="yes"
> > +else
> > +   have_feenableexcept="no"
> > +fi
> > +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
> > +fi
> > +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_feenableexcept" >&5
> > +$as_echo "$have_feenableexcept" >&6; }
> > +    if test "x$have_feenableexcept" = "xyes"; then
> > +
> > +cat >>confdefs.h <<_ACEOF
> > +#define HAVE_FEENABLEEXCEPT 1
> > +_ACEOF
> > +
> > +    fi;
> > +    ;;
> > +  *)
> >  # Check for GNU libc feenableexcept
> > -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for feenableexcept in -lm" >&5
> > +    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for feenableexcept in -lm" >&5
> >  $as_echo_n "checking for feenableexcept in -lm... " >&6; }
> >  if ${ac_cv_lib_m_feenableexcept+:} false; then :
> >    $as_echo_n "(cached) " >&6
> > @@ -27384,6 +27421,8 @@ $as_echo "#define HAVE_FEENABLEEXCEPT 1" >>confdefs.h
> >  
> >  fi
> >  
> > +    ;;
> > +esac
> >  
> >  # At least for glibc, clock_gettime is in librt.  But don't
> >  # pull that in if it still doesn't give us the function we want.  This
> > diff --git a/libgfortran/configure.ac b/libgfortran/configure.ac
> > index 97cc490cb5e..2dd6d345b22 100644
> > --- a/libgfortran/configure.ac
> > +++ b/libgfortran/configure.ac
> > @@ -602,8 +602,23 @@ fi
> >  # Check whether we have a __float128 type, depends on enable_libquadmath_support
> >  LIBGFOR_CHECK_FLOAT128
> >  
> > +case x$target in
> > +  xpowerpc*-freebsd*)
> > +    AC_CACHE_CHECK([for fenv.h and feenableexcept], have_feenableexcept, [
> > +      AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
> > +        [[ #include <fenv.h>  ]],
> > +        [[ feenableexcept(FE_DIVBYZERO | FE_INVALID); ]])],
> > +        [ have_feenableexcept="yes" ],
> > +        [ have_feenableexcept="no"  ])])
> > +    if test "x$have_feenableexcept" = "xyes"; then
> > +      AC_DEFINE(HAVE_FEENABLEEXCEPT,1,[fenv.h includes feenableexcept])
> > +    fi;
> > +    ;;
> > +  *)
> >  # Check for GNU libc feenableexcept
> > -AC_CHECK_LIB([m],[feenableexcept],[have_feenableexcept=yes AC_DEFINE([HAVE_FEENABLEEXCEPT],[1],[libm includes feenableexcept])])
> > +    AC_CHECK_LIB([m],[feenableexcept],[have_feenableexcept=yes AC_DEFINE([HAVE_FEENABLEEXCEPT],[1],[libm includes feenableexcept])])
> > +    ;;
> > +esac
> >  
> >  # At least for glibc, clock_gettime is in librt.  But don't
> >  # pull that in if it still doesn't give us the function we want.  This
> > -- 
> > 2.36.0
> >
  
Kewen.Lin May 12, 2022, 7:20 a.m. UTC | #3
Hi Piotr,

Thanks for doing this, some comments are inlined.

on 2022/5/11 07:32, Piotr Kubaj via Gcc-patches wrote:
> Is there anything more required?
> 
> On 22-05-03 12:33:43, Piotr Kubaj wrote:
>> Here are gmake check-gfortran results requested by FX.
>>
>> Before patching:
>>                 === gfortran Summary ===
>>
>> # of expected passes            65106
>> # of unexpected failures        6
>> # of expected failures          262
>> # of unsupported tests          367
>>
>> After patching:
>>                 === gfortran Summary ===
>>
>> # of expected passes            65384
>> # of unexpected failures        6
>> # of expected failures          262
>> # of unsupported tests          373
>>

Nice!

>> In both cases, unexpected failures are:
>> FAIL: gfortran.dg/pr98076.f90   -O0  execution test
>> FAIL: gfortran.dg/pr98076.f90   -O1  execution test
>> FAIL: gfortran.dg/pr98076.f90   -O2  execution test
>> FAIL: gfortran.dg/pr98076.f90   -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions  execution test
>> FAIL: gfortran.dg/pr98076.f90   -O3 -g  execution test
>> FAIL: gfortran.dg/pr98076.f90   -Os  execution test
>>
>> But this seems unrelated to my patch.>>
>> On 22-05-03 12:21:12, pkubaj@FreeBSD.org wrote:
>>> From: Piotr Kubaj <pkubaj@FreeBSD.org>
>>>
>>> FreeBSD/powerpc* has feenableexcept() defined in fenv.h header.
>>>
>>> Signed-off-by: Piotr Kubaj <pkubaj@FreeBSD.org>
>>> ---
>>>  libgfortran/configure    | 41 +++++++++++++++++++++++++++++++++++++++-
>>>  libgfortran/configure.ac | 17 ++++++++++++++++-
>>>  2 files changed, 56 insertions(+), 2 deletions(-)
>>>
... snip 
>>>  # At least for glibc, clock_gettime is in librt.  But don't
>>>  # pull that in if it still doesn't give us the function we want.  This
>>> diff --git a/libgfortran/configure.ac b/libgfortran/configure.ac
>>> index 97cc490cb5e..2dd6d345b22 100644
>>> --- a/libgfortran/configure.ac
>>> +++ b/libgfortran/configure.ac
>>> @@ -602,8 +602,23 @@ fi
>>>  # Check whether we have a __float128 type, depends on enable_libquadmath_support
>>>  LIBGFOR_CHECK_FLOAT128
>>>  
>>> +case x$target in
>>> +  xpowerpc*-freebsd*)
>>> +    AC_CACHE_CHECK([for fenv.h and feenableexcept], have_feenableexcept, [
>>> +      AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
>>> +        [[ #include <fenv.h>  ]],
>>> +        [[ feenableexcept(FE_DIVBYZERO | FE_INVALID); ]])],
>>> +        [ have_feenableexcept="yes" ],
>>> +        [ have_feenableexcept="no"  ])])
>>> +    if test "x$have_feenableexcept" = "xyes"; then
>>> +      AC_DEFINE(HAVE_FEENABLEEXCEPT,1,[fenv.h includes feenableexcept])
>>> +    fi;
>>> +    ;;
>>> +  *)

As your explanation in [1], IMHO it's not a good idea to take powerpc*-freebsd* specially
here, for your mentioned triples that may also suffer this same issue, we will have to
update this hunk for them in future.

How about: do the glibc check first as before, if it fails then do one further general check
(for all) with one compilation on fenv.h as what your patch proposes.

Besides, IMHO it should use AC_LINK_IFELSE, since one fenv.h which doesn't implement
feenableexcept could also pass the check.  And there is one AC_CHECK_HEADERS_ONCE checking
for fenv.h existence, not sure if it's worth to guarding the further check with its result.

[1] https://gcc.gnu.org/pipermail/gcc-patches/2022-April/593248.html

BR,
Kewen
  
Segher Boessenkool May 12, 2022, 8:16 p.m. UTC | #4
Hi Piotr,

On Tue, May 03, 2022 at 12:21:12PM +0200, pkubaj@FreeBSD.org wrote:
> FreeBSD/powerpc* has feenableexcept() defined in fenv.h header.

Declared, not defined.  These are required to be real functions (on all
platforms that have these functions), not macros or inlines or whatever.

So what library *does* have these functions?  It would be much neater to
do the similar to the libm test but with that other library.  Just libc,
maybe?

The answer to this will probably also answer Ke Wen's questions, or at
least just point to a good and more general way of solving this :-)

Maybe the AC_CHECK_LIB could just use GCC_CHECK_MATH_FUNC or such?

You also need a changelog entry here.  Something like


2022-05-12  Piotr Kubaj  <pkubaj@FreeBSD.org>

libgfortran/
	* configure.ac (powerpc*-freebsd*): Define HAVE_FEENABLEEXCEPT if
	<fenv.h> declares the feenableexcept function.
	* configure: Regenerate.


> +case x$target in
> +  xpowerpc*-freebsd*)
> +    AC_CACHE_CHECK([for fenv.h and feenableexcept], have_feenableexcept, [
> +      AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
> +        [[ #include <fenv.h>  ]],
> +        [[ feenableexcept(FE_DIVBYZERO | FE_INVALID); ]])],
> +        [ have_feenableexcept="yes" ],
> +        [ have_feenableexcept="no"  ])])

Please get rid of all surplus whitespace here.  Imitate existing tests,
if you need inspiration :-)


Segher
  
Kewen.Lin May 13, 2022, 2:59 a.m. UTC | #5
on 2022/5/13 04:16, Segher Boessenkool wrote:
> Hi Piotr,
> 
> On Tue, May 03, 2022 at 12:21:12PM +0200, pkubaj@FreeBSD.org wrote:
>> FreeBSD/powerpc* has feenableexcept() defined in fenv.h header.
> 
> Declared, not defined.  These are required to be real functions (on all
> platforms that have these functions), not macros or inlines or whatever.
> 

Piotr's reply "FreeBSD doesn't have this function in libm, it's
implemented in /usr/include/fenv.h." from [1] made me feel like
it's a definition instead of declaration.  So I thought the check
should use AC_LINK_IFELSE instead, since one fenv.h which doesn't
have the definition can still pass the proposed AC_COMPILE_IFELSE
check.

I just did a further search, the powerpc fenv.h [2] does include
the definition of feenableexcept.  By comparison, the x86 fenv.h [3]
doesn't.  But I'm not sure if it's the same as what Piotr's
environments have.  Hope it's similar. :-)

[1] https://gcc.gnu.org/pipermail/gcc-patches/2022-April/593193.html
[2] https://github.com/freebsd/freebsd-src/blob/main/lib/msun/powerpc/fenv.h
[3] https://github.com/freebsd/freebsd-src/blob/main/lib/msun/x86/fenv.h

BR,
Kewen
  
Piotr Kubaj May 13, 2022, 10:34 a.m. UTC | #6
On 22-05-13 10:59:59, Kewen.Lin wrote:
> on 2022/5/13 04:16, Segher Boessenkool wrote:
> > Hi Piotr,
> > 
> > On Tue, May 03, 2022 at 12:21:12PM +0200, pkubaj@FreeBSD.org wrote:
> >> FreeBSD/powerpc* has feenableexcept() defined in fenv.h header.
> > 
> > Declared, not defined.  These are required to be real functions (on all
> > platforms that have these functions), not macros or inlines or whatever.
> > 
> 
> Piotr's reply "FreeBSD doesn't have this function in libm, it's
> implemented in /usr/include/fenv.h." from [1] made me feel like
> it's a definition instead of declaration.  So I thought the check
> should use AC_LINK_IFELSE instead, since one fenv.h which doesn't
> have the definition can still pass the proposed AC_COMPILE_IFELSE
> check.
> 
> I just did a further search, the powerpc fenv.h [2] does include
> the definition of feenableexcept.  By comparison, the x86 fenv.h [3]
> doesn't.  But I'm not sure if it's the same as what Piotr's
> environments have.  Hope it's similar. :-)
> 
> [1] https://gcc.gnu.org/pipermail/gcc-patches/2022-April/593193.html
> [2] https://github.com/freebsd/freebsd-src/blob/main/lib/msun/powerpc/fenv.h
> [3] https://github.com/freebsd/freebsd-src/blob/main/lib/msun/x86/fenv.h

Yes, it's a definition and thanks for confirming that. As for why it's not in libm, I asked a developer about that:
03:04 <@adalava> It shouldn't be difficulted but I moved to other thing after months looking at FPE in kernel, bugs in context switch and msun test cases failing :-P

As far as I know, there are currently no plans to move it to libm on powerpc. riscv, arm and arm64 are in the same boat.

I will follow with a next patch that will check for feenableexcept() in fenv.h if libm check is unsuccessful.

Thanks,
Piotr Kubaj.

> 
> BR,
> Kewen
>
  
Segher Boessenkool May 13, 2022, 12:53 p.m. UTC | #7
On Fri, May 13, 2022 at 12:34:05PM +0200, Piotr Kubaj wrote:
> On 22-05-13 10:59:59, Kewen.Lin wrote:
> > on 2022/5/13 04:16, Segher Boessenkool wrote:
> > > On Tue, May 03, 2022 at 12:21:12PM +0200, pkubaj@FreeBSD.org wrote:
> > >> FreeBSD/powerpc* has feenableexcept() defined in fenv.h header.
> > > 
> > > Declared, not defined.  These are required to be real functions (on all
> > > platforms that have these functions), not macros or inlines or whatever.
> > > 
> > 
> > Piotr's reply "FreeBSD doesn't have this function in libm, it's
> > implemented in /usr/include/fenv.h." from [1] made me feel like
> > it's a definition instead of declaration.  So I thought the check
> > should use AC_LINK_IFELSE instead, since one fenv.h which doesn't
> > have the definition can still pass the proposed AC_COMPILE_IFELSE
> > check.
> > 
> > I just did a further search, the powerpc fenv.h [2] does include
> > the definition of feenableexcept.  By comparison, the x86 fenv.h [3]
> > doesn't.  But I'm not sure if it's the same as what Piotr's
> > environments have.  Hope it's similar. :-)
> > 
> > [1] https://gcc.gnu.org/pipermail/gcc-patches/2022-April/593193.html
> > [2] https://github.com/freebsd/freebsd-src/blob/main/lib/msun/powerpc/fenv.h
> > [3] https://github.com/freebsd/freebsd-src/blob/main/lib/msun/x86/fenv.h
> 
> Yes, it's a definition and thanks for confirming that. As for why it's not in libm, I asked a developer about that:
> 03:04 <@adalava> It shouldn't be difficulted but I moved to other thing after months looking at FPE in kernel, bugs in context switch and msun test cases failing :-P
> 
> As far as I know, there are currently no plans to move it to libm on powerpc. riscv, arm and arm64 are in the same boat.
> 
> I will follow with a next patch that will check for feenableexcept() in fenv.h if libm check is unsuccessful.

FreeBSD's own documentation
(<https://www.freebsd.org/cgi/man.cgi?query=feenableexcept>) says it is
a function, and it suggests it is in the standard library even.  This
would be as expected, the same holds for the similar C standard
functions.

This <fenv.h> does not provide an external definition, only a static
inline (this is a good thing for a header file of course).

You can take the address of a function.  You also can interpose a real
function normally, but that may not be relevant for FreeBSD, no idea.
You can do neither with a static inline.

So this should probably be fixed?

Thanks for explaining the situation better!


Segher
  
Piotr Kubaj May 14, 2022, 5:46 a.m. UTC | #8
I'm abandoning this patch. It was fixed in FreeBSD instead to have feenableexcept() in libm in https://cgit.freebsd.org/src/commit/?id=448c505c33cc334193590f3844406d6a74f26e2a

Thanks for your insight!

On 22-05-13 10:59:59, Kewen.Lin wrote:
> on 2022/5/13 04:16, Segher Boessenkool wrote:
> > Hi Piotr,
> > 
> > On Tue, May 03, 2022 at 12:21:12PM +0200, pkubaj@FreeBSD.org wrote:
> >> FreeBSD/powerpc* has feenableexcept() defined in fenv.h header.
> > 
> > Declared, not defined.  These are required to be real functions (on all
> > platforms that have these functions), not macros or inlines or whatever.
> > 
> 
> Piotr's reply "FreeBSD doesn't have this function in libm, it's
> implemented in /usr/include/fenv.h." from [1] made me feel like
> it's a definition instead of declaration.  So I thought the check
> should use AC_LINK_IFELSE instead, since one fenv.h which doesn't
> have the definition can still pass the proposed AC_COMPILE_IFELSE
> check.
> 
> I just did a further search, the powerpc fenv.h [2] does include
> the definition of feenableexcept.  By comparison, the x86 fenv.h [3]
> doesn't.  But I'm not sure if it's the same as what Piotr's
> environments have.  Hope it's similar. :-)
> 
> [1] https://gcc.gnu.org/pipermail/gcc-patches/2022-April/593193.html
> [2] https://github.com/freebsd/freebsd-src/blob/main/lib/msun/powerpc/fenv.h
> [3] https://github.com/freebsd/freebsd-src/blob/main/lib/msun/x86/fenv.h
> 
> BR,
> Kewen
>
  

Patch

diff --git a/libgfortran/configure b/libgfortran/configure
index ae64dca3114..ad71694ef05 100755
--- a/libgfortran/configure
+++ b/libgfortran/configure
@@ -27338,8 +27338,45 @@  fi
 
 
 
+case x$target in
+  xpowerpc*-freebsd*)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fenv.h and feenableexcept" >&5
+$as_echo_n "checking for fenv.h and feenableexcept... " >&6; }
+if ${have_feenableexcept+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+ #include <fenv.h>
+int
+main ()
+{
+ feenableexcept(FE_DIVBYZERO | FE_INVALID);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+   have_feenableexcept="yes"
+else
+   have_feenableexcept="no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_feenableexcept" >&5
+$as_echo "$have_feenableexcept" >&6; }
+    if test "x$have_feenableexcept" = "xyes"; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_FEENABLEEXCEPT 1
+_ACEOF
+
+    fi;
+    ;;
+  *)
 # Check for GNU libc feenableexcept
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for feenableexcept in -lm" >&5
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for feenableexcept in -lm" >&5
 $as_echo_n "checking for feenableexcept in -lm... " >&6; }
 if ${ac_cv_lib_m_feenableexcept+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -27384,6 +27421,8 @@  $as_echo "#define HAVE_FEENABLEEXCEPT 1" >>confdefs.h
 
 fi
 
+    ;;
+esac
 
 # At least for glibc, clock_gettime is in librt.  But don't
 # pull that in if it still doesn't give us the function we want.  This
diff --git a/libgfortran/configure.ac b/libgfortran/configure.ac
index 97cc490cb5e..2dd6d345b22 100644
--- a/libgfortran/configure.ac
+++ b/libgfortran/configure.ac
@@ -602,8 +602,23 @@  fi
 # Check whether we have a __float128 type, depends on enable_libquadmath_support
 LIBGFOR_CHECK_FLOAT128
 
+case x$target in
+  xpowerpc*-freebsd*)
+    AC_CACHE_CHECK([for fenv.h and feenableexcept], have_feenableexcept, [
+      AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
+        [[ #include <fenv.h>  ]],
+        [[ feenableexcept(FE_DIVBYZERO | FE_INVALID); ]])],
+        [ have_feenableexcept="yes" ],
+        [ have_feenableexcept="no"  ])])
+    if test "x$have_feenableexcept" = "xyes"; then
+      AC_DEFINE(HAVE_FEENABLEEXCEPT,1,[fenv.h includes feenableexcept])
+    fi;
+    ;;
+  *)
 # Check for GNU libc feenableexcept
-AC_CHECK_LIB([m],[feenableexcept],[have_feenableexcept=yes AC_DEFINE([HAVE_FEENABLEEXCEPT],[1],[libm includes feenableexcept])])
+    AC_CHECK_LIB([m],[feenableexcept],[have_feenableexcept=yes AC_DEFINE([HAVE_FEENABLEEXCEPT],[1],[libm includes feenableexcept])])
+    ;;
+esac
 
 # At least for glibc, clock_gettime is in librt.  But don't
 # pull that in if it still doesn't give us the function we want.  This