On Wed, Jul 18, 2018 at 6:10 PM, Janne Blomqvist <blomqvist.ja...@gmail.com> wrote:
> On Wed, Jul 18, 2018 at 4:26 PM, Thomas König <t...@tkoenig.net> wrote: > >> Hi Kyrlll, >> >> > Am 18.07.2018 um 13:17 schrieb Kyrill Tkachov < >> kyrylo.tkac...@foss.arm.com>: >> > >> > Thomas, Janne, would this relaxation of NaN handling be acceptable >> given the benefits >> > mentioned above? If so, what would be the recommended adjustment to the >> nan_1.f90 test? >> >> I would be a bit careful about changing behavior in such a major way. >> What would the results with NaN and infinity then be, with or without >> optimization? Would the results be consistent with min(nan,num) vs >> min(num,nan)? Would they be consistent with the new IEEE standard? >> > > AFAIU, MIN/MAX_EXPR do the right thing when comparing a normal number with > Inf. For NaN the result is undefined, and you might indeed have > > min(a, NaN) = a > min(NaN, a) = NaN > > where "a" is a normal number. > > (I think that happens at least on x86 if MIN_EXPR is expanded to > minsd/minpd. > > Apparently what the proper result for min(a, NaN) should be is contentious > enough that minnum was removed from the upcoming IEEE 754 revision, and new > operations AFAICS have the semantics > > minimum(a, NaN) = minimum(NaN, a) = NaN > minimumNumber(a, NaN) = minimumNumber(NaN, a) = a > > That is minimumNumber corresponds to minnum in IEEE 754-2008 and fmin* in > C, and to the current behavior of gfortran. > > >> In general, I think that min(nan,num) should be nan and that our current >> behavior is not the best. >> > > There was some extensive discussion of that in the Julia bug report I > linked to in an earlier message, and they came to the same conclusion and > changed their behavior. > > >> Does anybody have dats points on how this is handled by other compilers? >> > > The only other compiler I have access to at the moment is ifort (and not > the latest version), but maybe somebody has access to a wider variety? > > >> Oh, and if anything is changed, then compile and runtime behavior should >> always be the same. >> > > Well, IFF we place some weight on the runtime behavior being particularly > sensible wrt NaN's, which it wouldn't be if we just use a plain > MIN/MAX_EXPR. Is it worth taking a performance hit for, though? In > particular, if other compilers are inconsistent, we might as well do > whatever is fastest. > > > -- > Janne Blomqvist > The testcase below (the functions in a separate file to prevent inter-procedural and constant propagation optimizations): program main implicit none real :: a, b = 1., mymax, mydiv external mymax, mydiv a = mydiv(0., 0.) print *, 'Verify that the following value is a NaN: ', a print *, 'max(', a, ',', b, ') = ', mymax(a, b) print *, 'max(', b, ',', a, ') = ', mymax(b, a) a = mydiv(1., 0.) print *, 'Verify that the following is a Inf: ', a print *, 'max(', a, ',', b, ') = ', mymax(a, b) print *, 'max(', b, ',', a, ') = ', mymax(b, a) end program main real function mymax(a, b) implicit none real :: a, b mymax = max(a, b) end function mymax real function mydiv(a, b) implicit none real :: a, b mydiv = a/b end function mydiv With gfortran 6.2 (didn't bother to check other versions as it shouldn't have changed lately) and Intel Fortran 17.0.1 I get the following: % gfortran main.f90 my.f90 && ./a.out Verify that the following value is a NaN: NaN max( NaN , 1.00000000 ) = 1.00000000 max( 1.00000000 , NaN ) = 1.00000000 Verify that the following is a Inf: Infinity max( Infinity , 1.00000000 ) = Infinity max( 1.00000000 , Infinity ) = Infinity % gfortran -ffast-math main.f90 my.f90 && ./a.out Verify that the following value is a NaN: NaN max( NaN , 1.00000000 ) = NaN max( 1.00000000 , NaN ) = 1.00000000 Verify that the following is a Inf: Infinity max( Infinity , 1.00000000 ) = Infinity max( 1.00000000 , Infinity ) = Infinity % ifort main.f90 my.f90 && ./a.out Verify that the following value is a NaN: NaN max( NaN , 1.000000 ) = 1.000000 max( 1.000000 , NaN ) = NaN Verify that the following is a Inf: Infinity max( Infinity , 1.000000 ) = Infinity max( 1.000000 , Infinity ) = Infinity % ifort -fp-model strict main.f90 my.f90 && ./a.out Verify that the following value is a NaN: NaN max( NaN , 1.000000 ) = 1.000000 max( 1.000000 , NaN ) = NaN Verify that the following is a Inf: Infinity max( Infinity , 1.000000 ) = Infinity max( 1.000000 , Infinity ) = Infinity For brevity I have omitted tests with various -O[N] optimization levels, which didn't affect the results on either gfortran nor ifort. This suggests that ifort does the equivalent of MAX_EXPR unconditionally. Does anyone have access to other compilers, what results do they give? -- Janne Blomqvist