Bug 18518 - equivalenced variables are not saved
Summary: equivalenced variables are not saved
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.0.0
: P2 normal
Target Milestone: 4.0.3
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on:
Blocks: 19292 20405
  Show dependency treegraph
 
Reported: 2004-11-16 10:34 UTC by Thomas Koenig
Modified: 2005-09-29 21:32 UTC (History)
2 users (show)

See Also:
Host: ia64-unknown-linux-gnu
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2005-09-18 05:16:29


Attachments
test case (2.25 KB, text/plain)
2004-11-16 10:35 UTC, Thomas Koenig
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Koenig 2004-11-16 10:34:54 UTC
For source code see attachment. The source came
from http://www.netlib.org/blas/d1mach.f .

For new code, this should not be an ussue, because
these numbers are supplied by the front end.  Old
code from sources like netlib relies on these routines,
and it's a pain to have to change them.

$ gfortran -v
Reading specs from /home/zfkts/lib/gcc/ia64-unknown-linux-gnu/4.0.0/specs
Configured with: ../gcc-4.0-20041107/configure --prefix=/home/zfkts
--enable-languages=c,c++,f95
Thread model: posix
gcc version 4.0.0 20041107 (experimental)
$ gfortran d1mach.f && ./a.out
  2.225073858507201E-308
   0.00000000000000
  3.182993687584259E-313
  2.121995792447469E-314
  0.301029995663981
$ g77 d1mach.f && ./a.out
  2.22507386E-308
  1.79769313E+308
  1.11022302E-16
  2.22044605E-16
  0.301029996
$ ifort d1mach.f && ./a.out
  2.225073858507201E-308
  1.797693134862316E+308
  1.110223024625157E-016
  2.220446049250313E-016
  0.301029995663981
Comment 1 Thomas Koenig 2004-11-16 10:35:58 UTC
Created attachment 7553 [details]
test case
Comment 2 Carsten Lemmen 2004-11-17 08:46:06 UTC
On AMD x32 the correct result is obtained with g77. g95 and pgfortran work as
expected, only gfortran stops:

> gfortran d1mach.f && ./a.out
  2.225073858507201E-308
At line 215 of file d1mach.f
STOP 778

Comment 3 Thomas Koenig 2004-11-18 09:02:33 UTC
(In reply to comment #2)
> On AMD x32 the correct result is obtained with g77. g95 and pgfortran work as
> expected, only gfortran stops:
> 
> > gfortran d1mach.f && ./a.out
>   2.225073858507201E-308
> At line 215 of file d1mach.f
> STOP 778

Same result here, with the same processor.  There is different
(but not correct) behavior with -ffloat-store:

$ gfortran -ffloat-store d1mach.f && ./a.out
  2.225073858507201E-308
  4.882199637915989E-270
  5.092789898316654E-312
  4.925696698649795E-270
   2.79357004253718
Comment 4 Thomas Koenig 2004-11-18 18:53:02 UTC
It appears that equivalenced variables are not
saved.

Here's a simplified test case:

$ cat pr18518-test.f90
program main
  call foo
  call bar
  call foo
end program main

subroutine foo
  integer i,g,h
  data i/0/
  equivalence (g,h)
  save g
  if (i == 0) then
     i = 1
     h = 12345
  end if
  print *,h
end subroutine foo

subroutine bar
  integer a(10)
  a = 34
end subroutine bar
$ gfortran pr18518-test.f90 && ./a.out
       12345
          34
Comment 5 Toon Moene 2004-11-20 12:10:13 UTC
Hmmm, I do not get this on my powerpc-unknown-linux-gnu:

toon@book:~/g95-bugs$ /usr/snp/bin/gfortran -O2 18518.f90
toon@book:~/g95-bugs$ (LD_LIBRARY_PATH=/usr/snp/lib export LD_LIBRARY_PATH; ./a.out)
       12345
       12345
toon@book:~/g95-bugs$ /usr/snp/bin/gfortran -v
Reading specs from /usr/snp/lib/gcc/powerpc-unknown-linux-gnu/4.0.0/specs
Configured with: ../gcc/configure --prefix=/usr/snp --disable-nls --disable-multilib
Thread model: posix
gcc version 4.0.0 20041119 (experimental)
Comment 6 Thomas Koenig 2004-11-20 13:19:58 UTC
> Hmmm, I do not get this on my powerpc-unknown-linux-gnu:

Here's a reduced assembly output:

$ gfortran -v
Reading specs from /home/ig25/lib/gcc/i686-pc-linux-gnu/4.0.0/specs
Configured with: ../gcc/configure --prefix=/home/ig25 --enable-languages=c,c++,f95
Thread model: posix
gcc version 4.0.0 20041120 (experimental)
$ cat pr18518-test2.f90
subroutine foo
  integer i,g,h
  data i/0/
  equivalence (g,h)
  save g
  if (i == 0) then
     i = 1
     h = 12345
  end if
  print *,h
end subroutine foo
$ gfortran -S pr18518-test2.f90
$ cat pr18518-test2.s
        .file   "pr18518-test2.f90"
        .local  i.456
        .comm   i.456,4,4
        .section        .rodata
.LC0:
        .string "pr18518-test2.f90"
        .text
.globl foo_
        .type   foo_, @function
foo_:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $24, %esp
        movl    i.456, %eax
        testl   %eax, %eax
        jne     .L2
        movl    $1, i.456
        movl    $12345, -4(%ebp)
.L2:
        movl    $.LC0, _gfortran_filename
        movl    $10, _gfortran_line
        movl    $6, _gfortran_ioparm
        movl    $1, _gfortran_ioparm+16
        call    _gfortran_st_write
        movl    $4, 4(%esp)
        leal    -4(%ebp), %eax
        movl    %eax, (%esp)
        call    _gfortran_transfer_integer
        call    _gfortran_st_write_done
        leave
        ret
        .size   foo_, .-foo_
        .ident  "GCC: (GNU) 4.0.0 20041120 (experimental)"
        .section        .note.GNU-stack,"",@progbits
$ 
The "movl $12345, -4(%ebp)" above is clearly wrong - it loads the
value of 12345 into a stack location, not a saved location.

It would be good to check assembly output on your machine to
see wether the same problem occurs (even if the test example
doesn't show it).
Comment 7 Thomas Koenig 2004-11-22 12:29:57 UTC
(In reply to comment #5)
> Hmmm, I do not get this on my powerpc-unknown-linux-gnu:

I am also not getting this with -O on ia64-unknown-linux-gnu .  Apparently,
the array assignment in bar is commented away, and the stack isn't clobbered.

Here is another testcase, which causes the bug to be exposed (for me,
at least):

$ gfortran -v
Reading specs from /home/zfkts/lib/gcc/ia64-unknown-linux-gnu/4.0.0/specs
Configured with: ../gcc-4.0-20041107/configure --prefix=/home/zfkts
--enable-languages=c,c++,f95
Thread model: posix
gcc version 4.0.0 20041107 (experimental)
$ cat foobar.f90
program main
  call foo
  call bar(i)
  call foo
end program main

subroutine foo
  integer i,g,h
  data i/0/
  equivalence (g,h)
  save g
  if (i == 0) then
     i = 1
     h = 12345
  end if
  print *,h
end subroutine foo

subroutine bar(n)
  integer a(10)
  a = (/ (i, i=1,10) /)
  n = sum(a)
end subroutine bar
$ gfortran foobar.f90 && ./a.out
       12345
          55
$ gfortran -O foobar.f90 && ./a.out
       12345
           7
Comment 8 Tobias Schlüter 2004-11-30 15:17:52 UTC
Verified.

Indeed, we forget that variables in an equivalence set are SAVEd, and therefore
don't save the equivalence set.

I tried adding a path to build_equiv_decl where TREE_STATIC is set even if
there's no initialization. UNfortunately that lead to a segfault in the compiler.
Comment 9 CVS Commits 2005-09-27 21:46:55 UTC
Subject: Bug 18518

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	jakub@gcc.gnu.org	2005-09-27 21:46:15

Modified files:
	gcc/testsuite  : ChangeLog 
	gcc/fortran    : ChangeLog 
	gcc/fortran    : trans-common.c 
Added files:
	gcc/testsuite/gfortran.fortran-torture/execute: save_2.f90 

Log message:
	PR fortran/18518
	* trans-common.c (build_equiv_decl): Add IS_SAVED argument.
	If it is true, set TREE_STATIC on the decl.
	(create_common): If any symbol in equivalence has SAVE attribute,
	pass true as last argument to build_equiv_decl.
	
	* gfortran.fortran-torture/execute/save_2.f90: New decl.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.6108&r2=1.6109
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/fortran/ChangeLog.diff?cvsroot=gcc&r1=1.571&r2=1.572
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/fortran/trans-common.c.diff?cvsroot=gcc&r1=1.31&r2=1.32
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gfortran.fortran-torture/execute/save_2.f90.diff?cvsroot=gcc&r1=NONE&r2=1.1

Comment 10 CVS Commits 2005-09-29 21:30:11 UTC
Subject: Bug 18518

CVSROOT:	/cvs/gcc
Module name:	gcc
Branch: 	gcc-4_0-branch
Changes by:	jakub@gcc.gnu.org	2005-09-29 21:30:01

Modified files:
	gcc/fortran    : ChangeLog 
	gcc/testsuite  : ChangeLog 
	gcc/fortran    : trans-common.c 
Added files:
	gcc/testsuite/gfortran.fortran-torture/execute: save_2.f90 

Log message:
	PR fortran/18518
	* trans-common.c (build_equiv_decl): Add IS_SAVED argument.
	If it is true, set TREE_STATIC on the decl.
	(create_common): If any symbol in equivalence has SAVE attribute,
	pass true as last argument to build_equiv_decl.
	
	* gfortran.fortran-torture/execute/save_2.f90: New decl.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/fortran/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.335.2.122&r2=1.335.2.123
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.5084.2.417&r2=1.5084.2.418
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/fortran/trans-common.c.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.23.2.5&r2=1.23.2.6
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gfortran.fortran-torture/execute/save_2.f90.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=NONE&r2=1.1.4.1

Comment 11 Andrew Pinski 2005-09-29 21:32:55 UTC
Fixed.