Bug 19294 - intrinsic_transpose.f90 runtime crash
Summary: intrinsic_transpose.f90 runtime crash
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.0.0
: P2 normal
Target Milestone: 4.0.0
Assignee: James A. Morrison
URL:
Keywords: patch, wrong-code
Depends on:
Blocks:
 
Reported: 2005-01-06 17:23 UTC by Francois-Xavier Coudert
Modified: 2005-01-23 17:10 UTC (History)
3 users (show)

See Also:
Host: sparc*-*-*
Target: sparc*-*-*
Build: sparc*-*-*
Known to work:
Known to fail:
Last reconfirmed: 2005-01-06 18:16:10


Attachments
Use generic transpose/reshape complex numbers (640 bytes, patch)
2005-01-15 00:53 UTC, James A. Morrison
Details | Diff
Make transpose_c[48] functions (3.09 KB, patch)
2005-01-20 03:35 UTC, James A. Morrison
Details | Diff
m4 for transpose_c[48] (1.27 KB, text/plain)
2005-01-20 03:36 UTC, James A. Morrison
Details
Generated transpose_c4.c (1.25 KB, text/plain)
2005-01-20 03:37 UTC, James A. Morrison
Details
Generated transpose_c8.c (1.25 KB, text/plain)
2005-01-20 03:38 UTC, James A. Morrison
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Francois-Xavier Coudert 2005-01-06 17:23:43 UTC
From my test logs on sparc-sun-solaris2.9, I see:
FAIL: gfortran.fortran-torture/execute/intrinsic_transpose.f90 execution,  -O1 

This does happen only with -O1 (neither -O0, -O2 nor -O3). I tried to determine
more precisely the cause by including all optimization switches indicated in the
texinfo doc as being part of the -O1 set, but it didn't work (that is: it didn't
fail):

$ ~/irun/bin/gfortran intrinsic_transpose.f90 -static -O0 && ./a.out
$ ~/irun/bin/gfortran intrinsic_transpose.f90 -static -O1 && ./a.out
zsh: bus error  ./a.out
$ ~/irun/bin/gfortran intrinsic_transpose.f90 -static -O2 && ./a.out
$ ~/irun/bin/gfortran intrinsic_transpose.f90 -static -O3 && ./a.out
$ ~/irun/bin/gfortran intrinsic_transpose.f90 -static -fdefer-pop
-fmerge-constants -fthread-jumps -floop-optimize -fif-conversion
-fif-conversion2 -fdelayed-branch -fguess-branch-probability -fcprop-registers
-fomit-frame-pointer && ./a.out
$ ~/irun/bin/gfortran -O1 intrinsic_transpose.f90 -static -fdefer-pop
-fmerge-constants -fthread-jumps -floop-optimize -fif-conversion
-fif-conversion2 -fdelayed-branch -fguess-branch-probability -fcprop-registers
-fomit-frame-pointer && ./a.out
zsh: bus error  ./a.out


Here is the gdb output:
Program received signal SIGSEGV, Segmentation fault.
*_gfortran_transpose_8 (ret=Variable "ret" is not available.
)
    at ../../../gcc/libgfortran/generated/transpose_i8.c:81
81      ../../../gcc/libgfortran/generated/transpose_i8.c: No such file or
directory.
        in ../../../gcc/libgfortran/generated/transpose_i8.c


I can reproduce this behaviour on sparc-sun-solaris2.8 using this solaris2.9
compiler. I can give more details if someone see how to debug this. In
particular, if someone knows the list of -O1 enabled optimization switches, I
could locate the crucial one.
Comment 1 Eric Botcazou 2005-01-06 18:16:10 UTC
Confirmed on Solaris 8 and 9.  Interestingly, on Solaris 2.5.1, 2.6 and 7, it
also fails at -O0.
Comment 2 Eric Botcazou 2005-01-06 18:19:37 UTC
> I can reproduce this behaviour on sparc-sun-solaris2.8 using this solaris2.9
> compiler. I can give more details if someone see how to debug this. In
> particular, if someone knows the list of -O1 enabled optimization switches, I
> could locate the crucial one.

Try compiling with -fverbose-asm.
Comment 3 Francois-Xavier Coudert 2005-01-06 21:52:20 UTC
Playing with this test case to produce a minimal example, I found lots of
differents sources that crash at runtime, for different levels of optimization
(some at 1 and 2 but not 0 and 3, some only for 0, etc). The following code may
be the easiest to debug:

program intrinsic_transpose
   integer, dimension (3, 3) :: b
   complex(kind=4), dimension (2, 2) :: e

   b = reshape ((/1, 2, 3, 4, 5, 6, 7, 8, 9/), (/3, 3/))
   e = reshape ((/(1.0,2.0), (3.0, 4.0), (5.0, 6.0), (7.0, 8.0)/), (/2, 2/))
   e = transpose (e);
end program


This ones crashes with -O0 and -O1, but not -O2. Typical of a memory corruption
problem, if you remove the 'b = ...' line (or if the compiler removes it for
you, as I guess is done for -O2), the problem disappears. I can reproduce it on
solaris2.8 too (but not for -O0, though... how I hate memory corruption!)

GDB backtrace is still the same:
Starting program: /users/01/chimie/coudert/tmp/a.out 

Program received signal SIGSEGV, Segmentation fault.
*_gfortran_transpose_8 (ret=Variable "ret" is not available.
)
    at ../../../gcc/libgfortran/generated/transpose_i8.c:81
81      ../../../gcc/libgfortran/generated/transpose_i8.c: No such file or
directory.
        in ../../../gcc/libgfortran/generated/transpose_i8.c

As optimiztion is not in cause any more, I guess looking at flags will be no
use. I don't know if gdb is to be believed, but the code around line 81 in
transpose_i8.c is:

  rptr = ret->data;
  sptr = source->data;

  for (y=0; y < ycount; y++)
    {
      for (x=0; x < xcount; x++)
        {
          *rptr = *sptr; /* This is line 81 */

          sptr += sxstride;
          rptr += rystride;
        }
        sptr += systride - (sxstride * xcount);
        rptr += rxstride - (rystride * xcount);
    }

Looks like it could be that. I'll be running a modified version of the library
to determine if it's at that point later tonight. As I have absolutely no
knowledge about compilers, please feel free to help!
Comment 4 Francois-Xavier Coudert 2005-01-06 23:12:08 UTC
Debugging with puts statements, I confirm that the previously isolated code is
the place where the segfault happens. Replacing:

          *rptr = *sptr;

with:
          puts ("Before");  foo = *sptr; puts ("After");
          puts ("Before");  *rptr = foo; puts ("After");
          *rptr = *sptr;

now gives the following output:

$ LD_PRELOAD=/usr/local/lib/libefence.so ./a.out
Before
After
Before
zsh: bus error  LD_PRELOAD=/usr/local/lib/libefence.so ./a.out

That's the further I can go. If someone has something I can test you, please
mention it.
Comment 5 Andrew Pinski 2005-01-06 23:15:26 UTC
(In reply to comment #4)
> Debugging with puts statements, I confirm that the previously isolated code is
> the place where the segfault happens. Replacing:

This smell like the alignment is wrong ...

Comment 6 James A. Morrison 2005-01-12 01:58:23 UTC
 This patch fixes the testcase on sparc-linux
--- intrinsic_transpose.f90.old 2005-01-11 20:48:30.498247968 -0500
+++ intrinsic_transpose.f90     2005-01-11 20:45:38.026467664 -0500
@@ -2,7 +2,7 @@
 program intrinsic_transpose
    integer, dimension (3, 3) :: a, b
    complex(kind=8), dimension (2, 2) :: c, d
-   complex(kind=4), dimension (2, 2) :: e
+   complex(kind=4), dimension (2, 2) :: e, f

    a = 0
    b = reshape ((/1, 2, 3, 4, 5, 6, 7, 8, 9/), (/3, 3/))
@@ -17,8 +17,8 @@ program intrinsic_transpose
     call abort ();

    e = reshape ((/(1.0,2.0), (3.0, 4.0), (5.0, 6.0), (7.0, 8.0)/), (/2, 2/))
-   e = transpose (e);
-   if (any (e .ne. reshape ((/(1.0, 2.0), (5.0, 6.0), &
+   f = transpose (e);
+   if (any (f .ne. reshape ((/(1.0, 2.0), (5.0, 6.0), &
                               (3.0, 4.0), (7.0, 8.0)/), (/2, 2/)))) &
     call abort ();
 end program
Comment 7 James A. Morrison 2005-01-12 02:15:42 UTC
 Here is some more filler.
The main difference between the optimized dumps at -O1 is
original:
  atmp.40.dtype = 546;
  atmp.40.dim[0].stride = 1;
  atmp.40.dim[0].lbound = 0;
  atmp.40.dim[0].ubound = 1;
  atmp.40.dim[1].stride = 2;
  atmp.40.dim[1].lbound = 0;
  atmp.40.dim[1].ubound = 1;
  A.57 = (complex4[0:] *) &A.41;
  atmp.40.data = A.57;
  atmp.40.offset = 0;
[...]
  _gfortran_transpose_8 (&atmp.40, &parm.42);
  D.687 = atmp.40.data;

Explicit temporary:
  parm.40.dtype = 546;
  parm.40.dim[0].lbound = 1;
  parm.40.dim[0].ubound = 2;
  parm.40.dim[0].stride = 1;
  parm.40.dim[1].lbound = 1;
  parm.40.dim[1].ubound = 2;
  parm.40.dim[1].stride = 2;
  D.674 = (complex4[0:] *) &f[0];
  parm.40.data = D.674;
  parm.40.offset = 0;
[...]
  _gfortran_transpose_8 (&parm.40, &parm.41);
  SR.110 = (complex4[0:] *) &A.44;
  __builtin_memcpy (&(*SR.110)[0], &data.46, 32);
Comment 8 James A. Morrison 2005-01-15 00:53:10 UTC
Created attachment 7962 [details]
Use generic transpose/reshape complex numbers

 This patch fixes the two failures found in the testsuite.  I've bootstrapped
this patch and regtested up until gfortran.  There were no new gfortran
failures.  Unfortunatly, my system has gone a bit nuts and the testing was
taking at least twice as long as it should have.
Comment 9 Francois-Xavier Coudert 2005-01-19 12:38:46 UTC
I tested the patch from comment #8. Bootstrapped and regtested on
sparc-sun-solaris2.9. This fixes the intrinsic_transpose.f90 failure all right.
Comment 10 James A. Morrison 2005-01-20 03:35:33 UTC
Created attachment 7999 [details]
Make transpose_c[48] functions
Comment 11 James A. Morrison 2005-01-20 03:36:45 UTC
Created attachment 8000 [details]
m4 for transpose_c[48]
Comment 12 James A. Morrison 2005-01-20 03:37:22 UTC
Created attachment 8001 [details]
Generated transpose_c4.c
Comment 13 James A. Morrison 2005-01-20 03:38:36 UTC
Created attachment 8002 [details]
Generated transpose_c8.c

The attached files and patch fixes intrinsic_transpose.f90 on sparc-linux. 
These files have also been tested on powerpc-linux.
Comment 14 Andrew Pinski 2005-01-20 04:37:20 UTC
Newest patch posted here: <http://gcc.gnu.org/ml/gcc-patches/2005-01/msg01288.html>.
Comment 15 GCC Commits 2005-01-23 17:01:13 UTC
Subject: Bug 19294

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	pbrook@gcc.gnu.org	2005-01-23 17:01:00

Modified files:
	gcc/fortran    : ChangeLog iresolve.c 
	libgfortran    : ChangeLog Makefile.am Makefile.in 
	libgfortran/generated: transpose_i4.c transpose_i8.c 
	libgfortran/intrinsics: cshift0.c 
	libgfortran/m4 : transpose.m4 
Added files:
	libgfortran/generated: transpose_c4.c transpose_c8.c 

Log message:
	2005-01-23  James A. Morrison  <phython@gcc.gnu.org>
	Paul Brook  <paul@codesourcery.com>
	
	PR fortran/19294
	* iresolve.c (gfc_resolve_transpose): Resolve to transpose_c4 or
	transpose_c8 for complex types.
	libgfortran/
	* Makefile.am: Add transpose_c4.c and transpose_c8.c.
	* intrinsics/cshift0.c: Use separate optimized loops for complex types.
	* m4/transpose.m4: Include type letter in function name.
	* Makefile.in: Regenerate.
	* generated/transpose_*.c: Regenerate.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/fortran/ChangeLog.diff?cvsroot=gcc&r1=1.311&r2=1.312
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/fortran/iresolve.c.diff?cvsroot=gcc&r1=1.30&r2=1.31
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libgfortran/ChangeLog.diff?cvsroot=gcc&r1=1.152&r2=1.153
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libgfortran/Makefile.am.diff?cvsroot=gcc&r1=1.28&r2=1.29
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libgfortran/Makefile.in.diff?cvsroot=gcc&r1=1.29&r2=1.30
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libgfortran/generated/transpose_c4.c.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libgfortran/generated/transpose_c8.c.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libgfortran/generated/transpose_i4.c.diff?cvsroot=gcc&r1=1.8&r2=1.9
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libgfortran/generated/transpose_i8.c.diff?cvsroot=gcc&r1=1.8&r2=1.9
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libgfortran/intrinsics/cshift0.c.diff?cvsroot=gcc&r1=1.9&r2=1.10
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libgfortran/m4/transpose.m4.diff?cvsroot=gcc&r1=1.8&r2=1.9

Comment 16 Paul Brook 2005-01-23 17:08:57 UTC
Fixed.