GFortran releases

GCC 13.1 was released on April 26th. The Release Notes mention Fortran just twice:

OpenMP

  • OpenMP 5.0: Fortran now supports some non-rectangular loop nests; for C/C++, the support was added in GCC 11

Fortran

  • Finalization is now fully supported.

There are also a few dozen bugs claimed to be fixed

The only environment (from quite a few) I use that offers gcc-13.1 as of today is Homebrew.

9 Likes

FreeBSD ports as well.

1 Like

Also MSYS2: Base Package: mingw-w64-gcc - MSYS2 Packages
And Linux Fedora 38: gcc-13.1.1-1.fc38 | Build Info | koji

Iā€™m on Arch Linux and itā€™s available there.

1 Like

Thomas Koenig announced GFortran 13.1 on comp.lang.fortran:
https://groups.google.com/g/comp.lang.fortran/c/OTphp3EQFtg

To the two Fortran novelties already announced he added these notes:

Behavior on integer overflow
GCC 13 includes new optimizations which may change behavior on
integer overflow. Traditional code, like linear congruential
pseudo-random number generators in old programs and relying on
a specific, non-standard behavior may now generate unexpected
results. The option -fsanitize=undefined can be used to detect
such code at runtime.

It is recommended to use the intrinsic subroutine RANDOM_NUMBER for
random number generators or, if the old behavior is desired, to use
the -fwrapv option. Note that this option can impact performance.

Please find more details at GCC 13 Release Series ā€” Changes, New Features, and Fixes - GNU Project
and Porting to GCC 13 - GNU Project .

5 Likes

Unfortunately, the PDT issues remain. The @han190ā€™s code given here still segfaults at runtime.

What is the new behavior and what is the workaround? I use linear congruential generators to generate hash values and checksums, and in these cases, I expect the overflows to wrap, mod 2^32. If this is no longer the behavior, then what is the workaround?

The intrinsic RANDOM_NUMBER() only returns floating point values. For applications like hash codes and checksums, one usually wants integer values.

From that text, it is not the fortran standard that defines the behavior but rather ā€œthe processorā€, which in practice means the compiler, operating system, and runtime libraries that they use.

So if gfortran (or any other compiler) defined arithmetic so that LCGs work as expected, then those arithmetic operations would not be prohibited, which is a long way of saying they would be allowed (as they have been in fortran processors for some 60+ years). I understand that the fortran standard does not require LCGs to work, but I do think it allows them to work. So I donā€™t think it is correct for gfortran to try to hide behind the standard for a decision that it made itself.

Also, I donā€™t understand why specifying -fwrapv would adversely impact performance. It seems like it would be the other way around. If the overflows are trapped, that is what would take the effort, not ignoring them. If not, then what am I missing here?

Given that gfortran is changing legacy behavior, Instead of a compiler option, my preference to address this would have been something more local in the source code. For example, a source code directive, or perhaps an intrinsic function that the compiler would inline, or a mode function that turns off the unwanted behavior temporarily. The ability to ignore integer overflow is only preferred in very limited places, so you donā€™t want to change compiler options on a whole program just to get a few specific multiplications to work right, just those few places where you want overflows to wrap.

Are these the first adverse comments on this new feature that you have encountered?

1 Like

I read from this that other gcc languages, including C and C++, are also going to have difficulty implementing LCGs efficiently. LCGs are a common part of many algorithms, not just random number generators, but also the hashes and checksums that I mentioned, cryptography, security, and so on. LCGs are used within other encryption algorithms, primarily because they require just an integer multiplication and possibly an integer addition.

There have always been many good use cases for unisgned integers.

However, with twos-complement arithmetic, multiplications, additions, etc. all work the same in the hardware for signed and unsigned integers. The only difference is how numerical values are assigned to the resulting bits. That is why things like LCGs have always worked correctly in fortran on such hardware, they are really doing 32-bit unsigned arithmetic modulo 2**32 beneath the surface. And as you pointed out before, if the processor works that way, then the fortran standard allows the programmer to take advantage of that arithmetic feature.

Of course we all understand that that behavior cannot be incorporated into the standard because the standard must also accommodate other signed integer conventions, ones-complement, signed magnitude, biased, etc.

This all seems like it would be an important topic to me. Iā€™m surprised that the gcc people (not just the gfortran people) have not had more push-back for this change from legacy behavior.

Even the people writing compilers, gcc included, use hashes and checksums and LCGs internally. Certainly the people writing operating systems with these languages use them. By changing conventions so that LCGs can no longer be implemented, they are knowingly shooting themselves in the foot. My point was that the compiler writers should be the first ones to recognize the problem.

In this 1988 article is the sentence, ā€œAs a convention we frequently advise our students to respond with the 9 digits of their social security number.ā€ How times have changed!

Regarding your sample codes, these all rely on the convention that the integer overflows that occur in the statement

jsee = jsee * jm + ja

are silently ignored. The issue being discussed was that those overflows are no longer ignored in the new gcc/gfortran. Right? If the new gcc/gfortran is still treating these overflows the same as before, then this whole discussion has been a red herring.

Iā€™m not sure I understand why the results were wrong in the second run, with the -O compiler option. This is a compiler error, not a code error, right? Is it inlining the code, but missing the fact that the intent(inout) argument is modified?

Do you mean that -fsanitize=undefined prevents the function from being inlined? That is a little surprising.

Just out of curiosity, what happens if the above lines are changed to

         integer, parameter :: jm = 5
         integer, parameter :: ja = 3

so that no integer overflow occurs. Does the -O version still print the same value every iteration of the DO loop?

People interested by contributing to GFortran should read that post:

Yes. For the moment, the free Mattermost instance is still online and we have time:

Upgrade to paid plan to keep your workspace
Cloud Free will be deprecated in 81 days. Upgrade to a paid plan or contact sales.

And @JerryD has begun discussions with that university.

Well, the Oregon State University Open Source Lab is now hosting the GFortran Mattermost instance: https://gfortran-mm.osuosl.org/

Those people made a great job, importing the whole content of the previous instance. One thousand thanks! :pray:

As stated above by @JerryD :

If anyone here would be interested in joining the gfortran developers team, send an email to gfortran@gcc.gnu.org or myself at jvdelisle@gcc.gnu.org.

1 Like

ā€œlike 1-2 hours of intense compiling using every single thread your CPU has, and typically with computerā€™s fans spinning fastā€

Sometimes I forget why I liked my Dell R820 with 40 coresā€¦ even though it cost me $6 per month to run in the garage and it wasnā€™t as performant as my new desktopā€¦ man could it compile code fast.

A faster solution is to install a Linux binary build. I had for example tested successfully a nightly build in an Ubuntu, following these steps:
https://fortranwiki.org/fortran/show/GFortran#testing_the_latest_nightly_build