This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

bug in g77 -O2 optimization found -- resending with attachment



Originator Jonathan DeSena
Organization     JHU/APL
Confidential NO

Synopsis
     g77 generates incorrect code for a particular looping construct 
when optimization of -O2 or higher is used.

Severity serious
Priority medium
Category fortran
Class     wrong-code
Release     2.95.3 19991030 (prerelease)
Environment Linux Mandrake 7.2 on a Pentium III
Description
     A simple old style fortran loop operating on a small array produces 
incorrect results when optimization -O2 or higher is used to compile the 
code.  The program seems to be accessing the wrong array member, or 
using the wrong subscript inside the if statement. ARRAY(I) should not 
equal ARRAY(I1) (where I1=I+1).  When optimized ARRAY(I) seems to access 
ARRAY(I1), thus any calculation depending on such values in a real 
program are incorrect.  Adding/Removing certain lines seems to eliminate 
the problem.  See attached source code.

This same code compiles correctly under Sun's f77 for Solaris/SPARC 
under all optimization levels.  The problem was noted when porting code 
from Solaris/SPARC to ix86/Linux.

I worry that I may not be able to as easily find similar cases in other 
code where the output might not be as noticeably wrong as it was in this 
case. For what appears to be such a simple (albeit deprecated) code 
sample, the incorrect results are distressing.  I hope this can be fixed 
rather quickly.

How-To-Repeat
     Test case source code file test.for is attached.  The following 
shows compilation and execution on the command line:
_______________________________________________________________________
$ g77 -v -O2 -o test test.for
g77 version 2.95.3 19991030 (prerelease) (from FSF-g77 version 0.5.25 
19991030 (prerelease))
Driving: g77 -v -save-temps -O2 -o test test.for -lg2c -lm
Reading specs from /usr/lib/gcc-lib/i586-mandrake-linux/2.95.3/specs
gcc version 2.95.3 19991030 (prerelease)
  /usr/lib/gcc-lib/i586-mandrake-linux/2.95.3/f771 test.for -quiet 
-dumpbase test.f -O2 -version -fversion -o test.s
GNU F77 version 2.95.3 19991030 (prerelease) (i586-mandrake-linux) 
compiled by GNU C version 2.95.3 19991030 (prerelease).
GNU Fortran Front End version 0.5.25 19991030 (prerelease)
  as -V -Qy -o test.o test.s
GNU assembler version 2.10.90 (i586-mandrake-linux) using BFD version 
2.10.0.24
  /usr/lib/gcc-lib/i586-mandrake-linux/2.95.3/collect2 -m elf_i386 
-dynamic-linker /lib/ld-linux.so.2 -o test /usr/lib/crt1.o 
/usr/lib/crti.o /usr/lib/gcc-lib/i586-mandrake-linux/2.95.3/crtbegin.o 
-L/usr/lib/gcc-lib/i586-mandrake-linux/2.95.3 
-L/usr/i586-mandrake-linux/lib test.o -lg2c -lm -lgcc -lc -lgcc 
/usr/lib/gcc-lib/i586-mandrake-linux/2.95.3/crtend.o /usr/lib/crtn.o
$ ./test
  IF THESE TWO NUMBERS ARE EQUAL, THE CODE IS BAD:  60.  60.
_______________________________________________________________________

Fix
     Actually, the only real fix is to get the compiler -O2+ 
optimizations working correctly.  However, it is possible to replace the 
misbehaving code with a logically equivalent while loop (not Fortran 77 
standard, but most compilers I know accept it).  This is what I have 
done to get the code where this problem appeared working correctly.

C     THIS PROGRAM DEMONSTRATES A BUG IN G77 VERSION 2.95.3 19991030 (prerelease)
C     THIS BUG ONLY APPEARS WHEN THIS CODE IS COMPILED WITH -O2 OR
C     HIGHER LEVEL OPTIMIZATION.
C     THE SIMPLE LOOPING CONSTRUCT SHOULD ALWAYS PRINT TWO DIFFERENT NUMBERS.
C     SOMEHOW, IN OPTIMIZATION, THE CODE INCORRECTLY PRINTS TWO IDENTICAL VALUES.
      PROGRAM TEST
      IMPLICIT DOUBLE PRECISION (A-H, O-Z)
      IMPLICIT INTEGER (I-N)
      DIMENSION ARRAY(7)

      TIN=50.0D0 !INPUT VALUE TO USE FOR TEST 

      DATA ARRAY /0.0D0, 10.0D0, 20.0D0, 30.0D0, 40.0D0, 50.0D0, 60.0D0/

C     REWRITING THE FOLLOWING LOOP, WHICH ENDS AT LINE 60, BY USING A WHILE LOOP
C     FIXES THE PROBLEM REGARDLESS OF ALL OTHER LINES WHICH MUST EXIST IN ORDER
C     FOR THE PROBLEM TO MANIFEST ITSELF.  THIS LOOP ONLY SEEMS TO FAIL IN CODE
C     COMPILED WITH g77 (VERSION: 2.95.3 19991030 (prerelease)) USING -02 OR HIGHER 
C     OPTIMIZATION.  ALSO THE CODE "I1=I+1" FOLLOWING THIS LOOP MUST ALSO EXIST FOR 
C     THIS FAILURE TO MANIFEST ITSELF.
      DO 10 I = 1, 6
 
          I1 = I + 1
C      PRINT *,I !UNCOMMENTING THIS DEBUG LINE FIXES PROBLEM (PRINT *, I1 WORKS TOO)
 
          IF (TIN .LT. ARRAY(I1)) THEN
C     LOGICALLY, ARRAY(I) & ARRAY(I1) SHOULD NEVER BE EQUAL. 
C     CALCULATIONS RELYING ON THEM IN REAL CODE WILL THEN BE WRONG
              PRINT *, "IF THESE TWO NUMBERS ARE EQUAL, THE CODE IS BAD:
     *",ARRAY(I), ARRAY(I1)
C      PRINT *, I !UNCOMMENTING THIS DEBUG LINE FIXES PROBLEM (PRINT *, I1 WORKS TOO)
              GOTO 20
 
          ENDIF
 
 10   CONTINUE
 
      I = 6 !INCONSEQUENTIAL
 
 20   CONTINUE
C     END OF PROBLEMATIC LOOP

      I1 = I + 1 !COMMENTING OUT THIS LINE FIXES PROBLEM

C      PRINT *,I !UNCOMMENTING THIS DEBUG LINE FIXES PROBLEM (PRINT *, I1 WORKS TOO)

      STOP
      END
      

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]