This is the mail archive of the gcc-patches@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]
Other format: [Raw text]

[PATCH] Fortran testuite, fixes problem in testcase equiv_6


Hi F90 friends!

I was debugging test case ...testsuite/gfortran.dg/equiv_6.f90 which
failed on s390 and think that the problem is whithin the test case
itself.

The problem is subroutine set_arrays:

  subroutine set_arrays (listpr, lisbit)
    dimension listpr(20),lisbit(10)
    listpr = 0
    lisbit = (/(i, i = 1, 10)/)
    lisbit((/3,4/)) = 0
  end

When optimizing with O2 and above, gcc found it advantageous to
exchange the order of statements and to perform the assignment to
listpr at the end of the routine. Then, however, the intended
overwriting of values does not occur as expected and the test case
fails for this reason.

The optimization is allowed because the optimizer is told that the
formal paramaters are guaranteed not to be aliases of anything else in
the program, as the following lines in gcc/common.opt say:

  ; This flag is only tested if alias checking is enabled.
  ; 0 if pointer arguments may alias each other.  True in C.
  ; 1 if pointer arguments may not alias each other but may alias
  ;   global variables.
  ; 2 if pointer arguments may not alias each other and may not
  ;   alias global variables.
  ; 3 if pointer arguments may not alias anything.  True in Fortran.
  ;   Set by the front end.
  fargument-alias
  Common Report Var(flag_argument_noalias,0) Optimization
  Specify that arguments may alias each other and globals

  fargument-noalias
  Common Report Var(flag_argument_noalias,1) VarExists Optimization
  Assume arguments may alias globals but not each other

  fargument-noalias-global
  Common Report Var(flag_argument_noalias,2) VarExists Optimization
  Assume arguments alias neither each other nor globals

  fargument-noalias-anything
  Common Report Var(flag_argument_noalias,3) VarExists Optimization
  Assume arguments alias no other storage

This agrees with the Fortran standard. I do not have a recent copy but
recall that any programs depending on effects of parameter-induced
aliasing are considered as "erroneous", basically meaning that the
semantics of such programs is not defined (or, at least, not fully
defined).

This is exactly the problem found in the test case: all calls to
subroutine set_arrays pass global variables listpr and lisbit as
actual parameters. These two variables, however, are aliases because
of the EQUIVALENCE declarations.

The test case succeeds when compiled with option -fargument-alias
which overrides the above-mentioned flag settings and suggests that
all arguments might be aliases of eachother.

The bug fix I propose is to have two separate subroutines for
initializing the two arrays.

With best regards,

  Wolfgang Gellerich



---
Dr. Wolfgang Gellerich
IBM Deutschland Entwicklung GmbH
Schönaicher Strasse 220
71032 Böblingen, Germany
Tel. +49 / 7031 / 162598
gellerich@de.ibm.com

=======================

IBM Deutschland Entwicklung GmbH
Vorsitzender des Aufsichtsrats: Johann Weihen 
Geschäftsführung: Herbert Kircher 
Sitz der Gesellschaft: Böblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294


-----------------------

Changelog:


2007-04-24  Wolfgang Gellerich  <gellerich@de.ibm.com>

	* gfortran.dg/equiv_6.f90 (set_arrays): Replaced subroutine
	with two new subroutines to avoid parameter-induced aliasing.
	* gfortran.dg/equiv_6.f90 (set_array_listpr): New.
	* gfortran.dg/equiv_6.f90 (set_array_lisbit): New.
 

-----------------------

Index: gfortran.dg/equiv_6.f90
===================================================================
--- gfortran.dg/equiv_6.f90	(Revision 124097)
+++ gfortran.dg/equiv_6.f90	(Arbeitskopie)
@@ -14,7 +14,13 @@
               (lispat(1),listpr(10))
   lischk = (/0, 0, 0, 0, 0, 0, 0, 0, 0, 1, &
              2, 0, 0, 5, 6, 7, 8, 9,10, 0/)
-  call set_arrays (listpr, lisbit)
+
+! These two calls replace the previously made call to subroutine
+! set_arrays which was erroneous because of parameter-induced 
+! aliasing.
+  call set_array_listpr (listpr)
+  call set_array_lisbit (lisbit)
+
   if (any (listpr.ne.lischk)) call abort ()
   call sub1
   call sub2
@@ -28,7 +34,8 @@
   equivalence (listpr(10),lisbit(1)), &
               (listpr(10),mwkx(10)),  &
               (listpr(10),lispat(1))
-  call set_arrays (listpr, lisbit)
+  call set_array_listpr (listpr)
+  call set_array_lisbit (lisbit)
   if (any (listpr .ne. lischk)) call abort ()
 end
 !
@@ -41,7 +48,8 @@
   dimension    listpr(20),lisbit(10),lispat(8)
   equivalence (lispat(1),listpr(10)), &
               (mwkx(10),lisbit(1),listpr(10))
-  call set_arrays (listpr, lisbit)
+  call set_array_listpr (listpr)
+  call set_array_lisbit (lisbit)
   if (any (listpr .ne. lischk)) call abort ()
 end
 ! This gave correct results because the order in which the
@@ -52,12 +60,18 @@
   dimension    listpr(20),lisbit(10),lispat(8)
   equivalence (listpr(10),lisbit(1),mwkx(10)), &
               (lispat(1),listpr(10))
-  call set_arrays (listpr, lisbit)
+  call set_array_listpr (listpr)
+  call set_array_lisbit (lisbit)
   if (any (listpr .ne. lischk)) call abort ()
 end
-subroutine set_arrays (listpr, lisbit)
-  dimension listpr(20),lisbit(10)
+
+subroutine set_array_listpr (listpr)
+  dimension listpr(20)
   listpr = 0
+end
+
+subroutine set_array_lisbit (lisbit)
+  dimension lisbit(10)
   lisbit = (/(i, i = 1, 10)/)
   lisbit((/3,4/)) = 0
 end


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