[Bug fortran/94324] [10 regression] gfortran.dg/default_format_1.f90 etc. FAIL on 32-bit Solaris/x86

burnus at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Fri Mar 27 10:50:47 GMT 2020


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

Tobias Burnus <burnus at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |burnus at gcc dot gnu.org,
                   |                            |jvdelisle at gcc dot gnu.org,
                   |                            |tkoenig at gcc dot gnu.org

--- Comment #1 from Tobias Burnus <burnus at gcc dot gnu.org> ---
(In reply to Rainer Orth from comment #0)
> I just remembered that between 20191031 (r277679) and 20191101 (r277705) a
> couple of Fortran tests regressed on 32-bit Solaris/x86:

Hmm, that's odd. If I look at this range, there was no libgfortran change and
under gcc/ only an OpenMP change and gcc/config/aarch64.

> However, given that I know nothing about fortran, it would be very helpful
> to have some guidance on where to look.

I hope the following notes help.

 * * *

> +FAIL: gfortran.dg/default_format_1.f90   -O0  execution test
This test is rather old (Feb 2018) — however, there were changes recently,
especially to the "g0" output.

> Note: The following floating-point exceptions are signalling:
> IEEE_UNDERFLOW_FLAG
> STOP 6

  if (test (1.0_8, 0) /= 0) STOP 6

Here, 1.0 (double-prevision) is run as:

      do i = 0, count
        write (s,*) x
        read (s,*) y
        if (y /= x) res = res + 1
        x = nearest(x,huge(x))
      end do

Namely: the variable is written out (with default output precision) into the
string "s" and read-in again.  – The test passes if the written-read variable
and the original variable compare equal.

For count=200 steps, the same is repeated for the next higher variable
[nearest() = POSIX's nextafter()]. – Seemingly, one of those fails.

Suggestion: Add (after the "read"):
  print *, i, s, x == y
  print *, x
  print *, y
and - to stop directly after the first fail -
  if (y /= x) stop
and have a look at the output.


 * * *

> +FAIL: gfortran.dg/fmt_g0_1.f08   -O0  execution test
> STOP 3
> 
> #2  0x0805143d in MAIN__ ()
>     at /vol/gcc/src/hg/master/local/gcc/testsuite/gfortran.dg/fmt_g0_1.f08:11
> 11	    if (buffer.ne.":0.33333333333333331:") STOP 3
> (gdb) p buffer
> $1 = ':0.', '3' <repeats 16 times>, '2:', ' ' <repeats 29 times>

This is also an older test (Feb 2018).


    write(buffer, string) ':',1.0_8/3.0_8,':'
    if (buffer.ne.":0.33333333333333331:") STOP 3

This test case writes a ':' + 1./3. in double-precision + ':' to buffer.
For each input, "g0" is used.

The expected output is ':' followed by the printed number + ':' (plus padding
by spaces on the right). The assumption is 
":0.33333333333333331:" - this output
":0.33333333333333332:" - you get

which also sounds fine. — I don't know whether it has to be '1' or whether '2'
is acceptable as well, one would have to look at the bit representation.

I personally would be fine to accept  ...2 as well.

@ Jerry + Thomas: What do you think?


 * * *

> +FAIL: gfortran.dg/round_4.f90   -Os  execution test
> STOP 15

    ref10u = 0.1000000000000000000014_xp

  round = 'nearest'
  call t()
  if (rnd10 .and. (r10p /= ref10u .or. r10m /= -ref10u)) STOP 15

which does:
    str = "0.1 0.1 0.1 0.1"
    read (str, *,round=round) r4p, r8p, r10p, r16p
    str = "-0.1 -0.1 -0.1 -0.1"
    read (str, *,round=round) r4m, r8m, r10m, r16m

Namely, the string '0.1' and '-0.1' is read in as 80-bit floating type ("long
double", x87 floating-type number.)

[Or actually: it a this if both 80 bit and 128 bit floating-point numbers are
available; otherweise it is either a 32bit (non available) or 64bit (either
available) number. But as the previous test passes, I assume that it is a 80bit
number in you case.]


0.1 is not representable in binary floating-point numbers and round="nearest"
means:

"the value resulting from conversion shall be the closer of the two nearest
representable values if one is closer than the other. If the two nearest
representable values are equidistant from the original value, it is9processor
dependent which one of them is chosen."


The code assume that
  '0.1' becomes  0.1000000000000000000014
 '-0.1' becomes -0.1000000000000000000014
while you get:   0.100000000000000005551
                -0.100000000000000005551
this number is suspiciously close to the
expected value for a 64bit floating-point number:
                 0.10000000000000001

Thus, either 80bit FP numbers are not properly supported or
the output of 80bit FP numbers does not work. However, the
reference value could properly be stored, hmm.

> #2  0x08051f41 in MAIN__ ()
>     at /vol/gcc/src/hg/master/local/gcc/testsuite/gfortran.dg/round_4.f90:100
> 100	  if (rnd10 .and. (r10p /= ref10u .or. r10m /= -ref10u)) STOP 15
> 
> (gdb) p rnd10
> $1 = .TRUE.
> (gdb) p r10p
> $2 = 0.100000000000000005551
> (gdb) p ref10u
> $3 = 0.100000000000000000001
> (gdb) p r10m
> $4 = -0.100000000000000005551
> (gdb) p ref10u
> $5 = 0.100000000000000000001


More information about the Gcc-bugs mailing list