Hi, [This bug was initially submitted to the Debian BTS at http://bugs.debian.org/466911 -- at the request of Debian's gcc maintainer, I am also sending it here] In porting CERNLIB to gfortran, I've found an apparent gfortran compiler bug that results in incorrect code on ia64 (Itanium) with the compiler flags -funroll-loops -fno-automatic -O2 (or higher), possibly due to a bad interaction between these flags and a common block variable used in a computed GO TO statement of the form "GO TO (1,2,3,4), L". The bug ONLY occurs in gfortran-4.3 -- I have tested that it does NOT happen in gfortran-4.1 (4.1.2-19), gfortran-4.2 (4.2.3-1), or g77-3.4 (3.4.6-6). The output of gfortran-4.3 -v is: (sid)kmccarty@merulo:~$ gfortran-4.3 -v Using built-in specs. Target: ia64-linux-gnu Configured with: ../src/configure linux gnu Thread model: posix gcc version 4.3.1 20080309 (prerelease) (Debian 4.3.0-1) Please see the complete test case I've provided at http://people.debian.org/~kmccarty/ia64-gfortran-test-fail.tar.gz [Note, I have updated this test case tarball to the gfortran version noted above since I originally submitted this bug to the Debian BTS.] Notes on the test case: 1) The code that gets mis-compiled is in c201s.F (this can be verified by building c201s.F with -O0 and building all the rest with -funroll-loops -fno-automatic -O2, then linking and running the test program c201test) 2) If *any* of the compiler flags are changed (remove -funroll-loops, remove -fno-automatic, or lower the optimization to -O1) the code is built OK. 3) I have put the output of gfortran-4.3 on ia64 (files c201s.f, c201s.s, and c201s.o) for various compiler flag combinations in subdirectories in the test case tarball. Also the output of the test program when run, in the file output.txt in each subdirectory. (Subdirectories are named first after whether the test succeeds, and second after the specific compiler flags used.) You can quickly regenerate this output for all the various flag combinations in the test case with "make output". 4) I believe the problem is that the variable L in common block "FLABEL" is not seen as having the correct value (should be 1, is set to that value in c201m.F prior to any call of C201S) within c201s.F. 5) If I make any tweak to L in c201s.F, the bug disappears. (Argh, heisenbug!) For instance, any of the following tweaks individually causes the test program to succeed: a) changing L to a local variable initialized to the value 1 at the top of c201s.F b) setting L=1 at the top of c201s.F (keeping it in the common block) c) printing the value of L to stdout at the top of c201s.F with a WRITE statement d) printing the literal string 'L=n' to stdout (n being one of 1,2,3,4) immediately after each label that the first GO TO jumps to (i.e. the value of L is not even directly read from). Hence I was not able to simplify the test case any, unfortunately. best regards, Kevin McCarty
Fortran is not a primary language.
I cannot reproduce this error. I have compiled the test case with various options and always get output that includes Test# 1 ( C201 ): *** failed *** and Test# 1 ( GENT ): *** failed *** I get this when I use -fno-automatic -O2 -funroll-loops and when I use no optimization at all. This is with GCC 4.3 released bits and ToT bits on a Debian 3.1 IA64 system.
(In reply to comment #2) > Test# 1 ( GENT ): *** failed *** > > I get this when I use -fno-automatic -O2 -funroll-loops and when I use no > optimization at all. This is with GCC 4.3 released bits and ToT bits on > a Debian 3.1 IA64 system. I tried again with the version of gcc from the 4.3 release branch (Subversion branch gcc-4_3-branch downloaded today) and can still reproduce the bug (and also can still reproduce the successes with no optimization or with -fno-automatic -O2 but not -funroll-loops). This is on an up-to-date Debian Sid system. (N.B. are you aware that Debian 3.1 is no longer security-supported?)
Now I can reproduce it. I don't know if you intended this or not but the clean target in the Makefile removed the good objects but left the bad one so that when I rebuilt I still had the old bad object around.
Created attachment 15672 [details] cutdown test case This smaller test case requires the same options as the original.
It looks like this is a bug in register renaming. register renaming is turned on by -floop-unroll. You can reproduce the bug using -frename-registers in place of -funroll-loops.
I now think this is a register scheduling bug. If I use -fno-schedule-insns2 then the bug doesn't happen even with "-O2 fno-automatic -frename-registers". The problem seems to be scheduling the assignment to TEMP2 and assigning TEMP2 to F(K). In the good code, in C201S I see the following instructions, in this order: addl r17 = @gprel(temp2.717#), gp - r17 is addr of temp2 stfd [r17] = f0 - zero out temp2 (p11) stfd [r17] = f10 - (maybe) put value (2.0) in temp2 ldfd f9 = [r17] - load temp2 add r16 = r34, r37 - r16 is addr of F(1) stfd [r16] = f9 - store temp2 in F(1) In the bad code (with instruction scheduling turned on) I see: addl r17 = @gprel(temp2.717#), gp - r17 is addr of temp2 add r16 = r34, r37 - r16 is addr of F(1) ldfd f9 = [r17] - load temp2 stfd [r17] = f0 - zero out temp2 stfd [r16] = f9 - store (old) temp2 in F(1) (p11) stfd [r17] = f10 - (maybe) put value (2.0) in temp2 The store into F(1) is done before we have put the correct value int temp2. I don't understand how instruction scheduling could be this broken.
4.3.1 is being released, adjusting target milestone.
Kevin, I can no longer reproduce this bug. I think it was fixed by the same patch that fixed PR 35659. Are you able to reproduce this or can we close it as fixed?
(In reply to comment #9) > Kevin, I can no longer reproduce this bug. I think it was fixed by the same > patch that fixed PR 35659. Are you able to reproduce this or can we close it > as fixed? First, sorry for the delayed reply. With the latest gfortran from the gcc 4.3 branch in svn, I can unfortunately still reproduce this bug using both my test case and the cut-down test case provided by Steve Ellcey. I do find that PR 35659 is now fixed for me. (sid)kmccarty@merulo:~$ ~/gcc-4.3-branch/bin/gfortran -v Using built-in specs. Target: ia64-unknown-linux-gnu Configured with: ./configure --enable-fortran --prefix=/home/kmccarty/gcc-4.3-branch/ --with-mpfr=/home/kmccarty/gcc-4.3-branch/ --with-gmp=/home/kmccarty/gcc-4.3-branch/ Thread model: posix gcc version 4.3.2 20080822 (prerelease) (GCC) Would you like me to also try with SVN trunk? Anything else you need to know?
(In reply to comment #9) By the way, Steve, I do find (as you mentioned) that -frename-registers in place of -funroll-loops also triggers the bug, and that adding -fno-schedule-insns2 makes it go away.
4.3.2 is released, changing milestones to 4.3.3.
GCC 4.3.3 is being released, adjusting target milestone.
GCC 4.3.4 is being released, adjusting target milestone.
GCC 4.3.5 is being released, adjusting target milestone.
May be a dup of 43494, based on comment #7.
Fixed for 4.4.0.