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] PR35946 and PR35947 - [4.3, 4.4 regression] wrong results with array constructor as arguments


:ADDPATCH fortran:

The need for this patch comes about because the scalarizer is now,
sometimes, not zero basing loops containing variable array
constructors.  The consequence of this is that the dimensions and
bounds of the temporary get messed up and that the references to it
are not offset correctly.  I tried to fix this in
gfc_trans_create_temp_array but so many regressions were caused that I
could not see how to do it.  Whilst the attached patch is a bit
inelegant, it does the job.  Note that only 1D arrays are affected so
there is no need to work out complicated offsets.

Bootstrapped and regtested on x86_ia64 - OK for trunk and 4.3?

If it is OK with everybody, I will commit this tonight.  I am away for
a bit and might find it difficult to do for a couple of weeks.

Paul

2008-04-19  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/35946
	PR fortran/35947
	* trans_array.c (gfc_trans_array_constructor): Temporarily
	realign loop, if loop->from is not zero, before creating
	the temporary array and provide an offset.

2008-04-19  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/35946
	PR fortran/35947
	* gfortran.dg/array_constructor_23.f: New test.


-- 
The knack of flying is learning how to throw yourself at the ground and miss.
       --Hitchhikers Guide to the Galaxy
Index: gcc/fortran/trans-array.c
===================================================================
*** gcc/fortran/trans-array.c	(revision 134362)
--- gcc/fortran/trans-array.c	(working copy)
*************** gfc_trans_array_constructor (gfc_loopinf
*** 1679,1684 ****
--- 1679,1685 ----
    tree offsetvar;
    tree desc;
    tree type;
+   tree loopfrom;
    bool dynamic;
  
    if (flag_bounds_check && ss->expr->ts.type == BT_CHARACTER)
*************** gfc_trans_array_constructor (gfc_loopinf
*** 1757,1765 ****
--- 1758,1791 ----
  	}
      }
  
+   /* Temporarily reset the loop variables, so that the returned temporary
+      has the right size and bounds.  This seems only to be necessary for
+      1D arrays.  */
+   if (!integer_zerop (loop->from[0]) && loop->dimen == 1)
+     {
+       loopfrom = loop->from[0];
+       loop->from[0] = gfc_index_zero_node;
+       loop->to[0] = fold_build2 (MINUS_EXPR, gfc_array_index_type,
+ 				 loop->to[0], loopfrom);
+     }
+   else
+     loopfrom = NULL_TREE;
+ 
    gfc_trans_create_temp_array (&loop->pre, &loop->post, loop, &ss->data.info,
  			       type, dynamic, true, false);
  
+   if (loopfrom != NULL_TREE)
+     {
+       loop->from[0] = loopfrom;
+       loop->to[0] = fold_build2 (PLUS_EXPR, gfc_array_index_type,
+ 				 loop->to[0], loopfrom);
+       /* In the case of a non-zero from, the temporary needs an offset
+ 	 so that subsequent indexing is correct.  */
+       ss->data.info.offset = fold_build1 (NEGATE_EXPR,
+ 					  gfc_array_index_type,
+ 					  loop->from[0]);
+     }
+ 
    desc = ss->data.info.descriptor;
    offset = gfc_index_zero_node;
    offsetvar = gfc_create_var_np (gfc_array_index_type, "offset");
Index: gcc/testsuite/gfortran.dg/array_constructor_23.f
===================================================================
*** gcc/testsuite/gfortran.dg/array_constructor_23.f	(revision 0)
--- gcc/testsuite/gfortran.dg/array_constructor_23.f	(revision 0)
***************
*** 0 ****
--- 1,31 ----
+ ! { dg-do run }
+ ! Tests the fix for PR35946/7, in which the variable array constructors below
+ ! were incorrectly translated and wrong code was produced.
+ !
+ ! Contributed by Dick Hendrickson <dick.hendrickson@gmail.com>
+ !
+       program try_fa6013
+       call fa6013 (10, 1, -1)
+       call fa6077 (10, 1, -1, (/1,2,3,4,5,6,7,8,9,10/))
+       end program
+ 
+       subroutine  FA6013 (nf10, nf1, mf1)
+       integer, parameter :: kv = 4
+       REAL(KV) DDA1(10)
+       REAL(KV) DDA2(10)
+       REAL(KV) DDA(10), dval
+       dda = (/1,2,3,4,5,6,7,8,9,10/)
+       DDA1 = ATAN2 ((/(REAL(J1,KV),J1=1,10)/),
+      $                 REAL((/(J1,J1=nf10,nf1,mf1)/), KV))   !fails
+       DDA2 = ATAN2 (DDA, DDA(10:1:-1))
+       if (any (DDA1 .ne. DDA2)) call abort ()
+       END
+ 
+       subroutine FA6077 (nf10,nf1,mf1, ida)
+       INTEGER IDA1(10)
+       INTEGER IDA2(10), ida(10)
+       IDA1 = IEOR((/1,2,3,4,5,6,7,8,9,10/),
+      $            (/(IDA(J1),J1=10,1,-1)/) )
+       IDA2 = IEOR ((/1,2,3,4,5,6,7,8,9,10/), (/10,9,8,7,6,5,4,3,2,1/) )
+       if (any (ida1 .ne. ida2)) call abort ()
+       END SUBROUTINE

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