# Checking Inf/NaN when compilers are invoked with aggressive optimization flags

**URL:** <https://fortran-lang.discourse.group/t/checking-inf-nan-when-compilers-are-invoked-with-aggressive-optimization-flags/1851>\
**Category:** Help\
**Created:** [September 16, 2021, 3:56am UTC](https://fortran-lang.discourse.group/t/checking-inf-nan-when-compilers-are-invoked-with-aggressive-optimization-flags/1851 "2021-09-16T03:56:11Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![zaikunzhang](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/zaikunzhang/32/785_2.png) [@zaikunzhang](https://fortran-lang.discourse.group/u/zaikunzhang)\
**Post date:** [September 16, 2021, 3:56am UTC](https://fortran-lang.discourse.group/t/checking-inf-nan-when-compilers-are-invoked-with-aggressive-optimization-flags/1851/1 "2021-09-16T03:56:11Z")

</div>

I have posted on [GitHub](https://github.com/zaikunzhang/infnan) some functions for checking Inf/NaN, which aim to work even when compilers are invoked with aggressive optimization flags, such as `gfortran -Ofast`.

There are many ways to implement functions like `is_nan`. However, not all of them work with aggressive optimization flags. For example, there are such discussions on [StackOverflow](https://stackoverflow.com/questions/15944614/is-it-possible-to-make-isnan-work-in-gfortran-o3-ffast-math).

In addition, some compilers are buggy concerning the return type of `ieee_is_nan` when some special compilation options are imposed, as has been discussed here on [Fortran Discourse](https://fortran-lang.discourse.group/t/is-this-expected-fortran-standard-is-not-respected-by-gfortran-fdefault-integer-8-ifort-i8-or-nagfor-i8/1793).

My choice of implementation is **totally empirical** , in the sense that I have not studied in-depth what the **aggressive optimization flags** really do, but only made some tests and found some implementation that worked correctly. In other words, I do not know why my implementation works but other implementations may not. **The story may change when compilers are changed/updated.**

The good news is, I have tested the functions on **9 compilers** with the most aggressive optimization flags that I can figure out, all of which are happy. In particular, the functions work well with `gfortran -Ofast` (`gfortran` version 9.3.0), but those based on `ieee_arithmetic` fail. Given the fact that `-Ofast` implies `-ffinite-math-only`, we cannot blame `ieee_arithmetic` for the failure; instead, I am surprised by the success of my implementation under such an option.

You may try them if you are interested. The [GitHub](https://github.com/zaikunzhang/infnan) repository includes some simple tests in test/testinfnan.f90.

For your convenience, I copy-paste the functions below. More details can be found on [GitHub](https://github.com/zaikunzhang/infnan).

```auto
! consts.f90
module consts_mod

implicit none
private
public :: SP, DP

integer, parameter :: SP = kind(0.0)
integer, parameter :: DP = kind(0.0D0)

end module consts_mod

```

```auto
! infnan.f90
module infnan_mod

use consts_mod, only : SP, DP
implicit none
private
public :: is_nan, is_finite, is_inf, is_posinf, is_neginf

interface is_nan
    module procedure is_nan_sp, is_nan_dp
end interface is_nan
 
interface is_finite
    module procedure is_finite_sp, is_finite_dp
end interface is_finite

interface is_posinf
    module procedure is_posinf_sp, is_posinf_dp
end interface is_posinf

interface is_neginf
    module procedure is_neginf_sp, is_neginf_dp
end interface is_neginf

interface is_inf
    module procedure is_inf_sp, is_inf_dp
end interface is_inf

contains

elemental pure function is_nan_sp(x) result(y)
implicit none
real(SP), intent(in) :: x
logical :: y
y = (.not. (x <= huge(x) .and. x >= -huge(x))) .and. (.not. abs(x) > huge(x))
end function is_nan_sp

elemental pure function is_nan_dp(x) result(y)
implicit none
real(DP), intent(in) :: x
logical :: y
y = (.not. (x <= huge(x) .and. x >= -huge(x))) .and. (.not. abs(x) > huge(x))
end function is_nan_dp

elemental pure function is_finite_sp(x) result(y)
implicit none
real(SP), intent(in) :: x
logical :: y
y = (x <= huge(x) .and. x >= -huge(x))
end function is_finite_sp

elemental pure function is_finite_dp(x) result(y)
implicit none
real(DP), intent(in) :: x
logical :: y
y = (x <= huge(x) .and. x >= -huge(x))
end function is_finite_dp

elemental pure function is_inf_sp(x) result(y)
implicit none
real(SP), intent(in) :: x
logical :: y
y = (abs(x) > huge(x))
end function is_inf_sp

elemental pure function is_inf_dp(x) result(y)
implicit none
real(DP), intent(in) :: x
logical :: y
y = (abs(x) > huge(x))
end function is_inf_dp

elemental pure function is_posinf_sp(x) result(y)
implicit none
real(SP), intent(in) :: x
logical :: y
y = (abs(x) > huge(x)) .and. (x > 0)
end function is_posinf_sp

elemental pure function is_posinf_dp(x) result(y)
implicit none
real(DP), intent(in) :: x
logical :: y
y = (abs(x) > huge(x)) .and. (x > 0)
end function is_posinf_dp

elemental pure function is_neginf_sp(x) result(y)
implicit none
real(SP), intent(in) :: x
logical :: y
y = (abs(x) > huge(x)) .and. (x < 0)
end function is_neginf_sp

elemental pure function is_neginf_dp(x) result(y)
implicit none
real(DP), intent(in) :: x
logical :: y
y = (abs(x) > huge(x)) .and. (x < 0)
end function is_neginf_dp

end module infnan_mod

```

Any comments, suggestions, or criticism will be appreciated. Thank you very much for your attention!

---

<div class="post-metadata">

**Author:** ![CRquantum](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/crquantum/32/730_2.png) [@CRquantum](https://fortran-lang.discourse.group/u/CRquantum)\
**Post date:** [September 16, 2021, 6:23am UTC](https://fortran-lang.discourse.group/t/checking-inf-nan-when-compilers-are-invoked-with-aggressive-optimization-flags/1851/2 "2021-09-16T06:23:19Z")

</div>

Thank you very much!  
So a simply question, for ‘release’ code, what flags do you suggest?

-O3 -march-native

is the above flag OK?  
In my shallow experience, gfortran with the above flags almost always performs similar speed and same results with Intel Fortran with -O3 -xHost -heaparray -ipo  
Although I almost always use Intel Fortran. gfortran for me is mostly just for testing.

---

<div class="post-metadata">

**Author:** ![zaikunzhang](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/zaikunzhang/32/785_2.png) [@zaikunzhang](https://fortran-lang.discourse.group/u/zaikunzhang)\
**Post date:** [September 16, 2021, 2:04pm UTC](https://fortran-lang.discourse.group/t/checking-inf-nan-when-compilers-are-invoked-with-aggressive-optimization-flags/1851/3 "2021-09-16T14:04:51Z")

</div>

> [@CRquantum](#):
>
> -O3 -march-native

My knowledge about the options is quite limited. I suppose the best information source would be the official document of `gfortran`.

`-O3` seems OK, but combining it with `-ffast-math` is aggressive. In my tests, some naive implementations of `is_nan` work with `-O3` or `-ffast-math` separately, but not when both are imposed.
