]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR fortran/81773 ([Coarray] Get with vector index on lhs leads to incorrect caf_ge...
authorAndre Vehreschild <vehre@gcc.gnu.org>
Sat, 14 Apr 2018 14:45:59 +0000 (16:45 +0200)
committerAndre Vehreschild <vehre@gcc.gnu.org>
Sat, 14 Apr 2018 14:45:59 +0000 (16:45 +0200)
gcc/fortran/ChangeLog:

2018-04-14  Andre Vehreschild  <vehre@gcc.gnu.org>

PR fortran/81773
PR fortran/83606
* dependency.c (gfc_dep_resolver): Coarray indexes are to be ignored
during dependency computation.  They define no data dependency.
* trans-array.c (conv_array_index_offset): The stride can not be set
here, prevent fail.
* trans-intrinsic.c (conv_caf_send): Add creation of temporary array
for caf_get's result and copying to the array with vectorial
indexing.

gcc/testsuite/ChangeLog:

2018-04-14  Andre Vehreschild  <vehre@gcc.gnu.org>

PR fortran/81773
PR fortran/83606
* gfortran.dg/coarray/get_to_indexed_array_1.f90: New test.
* gfortran.dg/coarray/get_to_indirect_array.f90: New test.

From-SVN: r259385

gcc/fortran/ChangeLog
gcc/fortran/dependency.c
gcc/fortran/trans-array.c
gcc/fortran/trans-intrinsic.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/coarray/get_to_indexed_array_1.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/coarray/get_to_indirect_array.f90 [new file with mode: 0644]

index c6ec69e86c0c7f73daf799de09780592582c8327..9d126868cc9ea6536e7a21726335b9b5c46185ac 100644 (file)
@@ -1,3 +1,15 @@
+2018-04-14  Andre Vehreschild  <vehre@gcc.gnu.org>
+
+       PR fortran/81773
+       PR fortran/83606
+       * dependency.c (gfc_dep_resolver): Coarray indexes are to be ignored
+       during dependency computation.  They define no data dependency.
+       * trans-array.c (conv_array_index_offset): The stride can not be set
+       here, prevent fail.
+       * trans-intrinsic.c (conv_caf_send): Add creation of temporary array
+       for caf_get's result and copying to the array with vectorial
+       indexing.
+
 2018-04-14  Thomas Koenig  <tkoenig@gcc.gnu.org>
 
        PR fortran/85387
index a0bbd584947fb49371862f8554b8760c56af7fc1..3e14ddc25d86300a19fb844f0deee618b890a609 100644 (file)
@@ -2238,8 +2238,9 @@ gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gfc_reverse *reverse)
            break;
 
          /* Exactly matching and forward overlapping ranges don't cause a
-            dependency.  */
-         if (fin_dep < GFC_DEP_BACKWARD)
+            dependency, when they are not part of a coarray ref.  */
+         if (fin_dep < GFC_DEP_BACKWARD
+             && lref->u.ar.codimen == 0 && rref->u.ar.codimen == 0)
            return 0;
 
          /* Keep checking.  We only have a dependency if
index bd731689031811a0d0353755b12d6a19e2c40b7b..b68e77d52818c32603cd642c80d54ef75328e91a 100644 (file)
@@ -3215,7 +3215,7 @@ conv_array_index_offset (gfc_se * se, gfc_ss * ss, int dim, int i,
     }
 
   /* Multiply by the stride.  */
-  if (!integer_onep (stride))
+  if (stride != NULL && !integer_onep (stride))
     index = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
                             index, stride);
 
index a45aec708fb97b33c38ee07032730e221e129978..00edd447bb2a1d6f6980eefe0c6c32a230709dda 100644 (file)
@@ -1907,34 +1907,124 @@ conv_caf_send (gfc_code *code) {
     }
   else
     {
-      /* If has_vector, pass descriptor for whole array and the
-         vector bounds separately.  */
-      gfc_array_ref *ar, ar2;
-      bool has_vector = false;
+      bool has_vector = gfc_has_vector_subscript (lhs_expr);
 
-      if (gfc_is_coindexed (lhs_expr) && gfc_has_vector_subscript (lhs_expr))
+      if (gfc_is_coindexed (lhs_expr) || !has_vector)
        {
-          has_vector = true;
-          ar = gfc_find_array_ref (lhs_expr);
-         ar2 = *ar;
-         memset (ar, '\0', sizeof (*ar));
-         ar->as = ar2.as;
-         ar->type = AR_FULL;
+         /* If has_vector, pass descriptor for whole array and the
+            vector bounds separately.  */
+         gfc_array_ref *ar, ar2;
+         bool has_tmp_lhs_array = false;
+         if (has_vector)
+           {
+             has_tmp_lhs_array = true;
+             ar = gfc_find_array_ref (lhs_expr);
+             ar2 = *ar;
+             memset (ar, '\0', sizeof (*ar));
+             ar->as = ar2.as;
+             ar->type = AR_FULL;
+           }
+         lhs_se.want_pointer = 1;
+         gfc_conv_expr_descriptor (&lhs_se, lhs_expr);
+         /* Using gfc_conv_expr_descriptor, we only get the descriptor, but
+            that has the wrong type if component references are done.  */
+         lhs_type = gfc_typenode_for_spec (&lhs_expr->ts);
+         tmp = build_fold_indirect_ref_loc (input_location, lhs_se.expr);
+         gfc_add_modify (&lhs_se.pre, gfc_conv_descriptor_dtype (tmp),
+                         gfc_get_dtype_rank_type (has_vector ? ar2.dimen
+                                                             : lhs_expr->rank,
+                                                  lhs_type));
+         if (has_tmp_lhs_array)
+           {
+             vec = conv_caf_vector_subscript (&block, lhs_se.expr, &ar2);
+             *ar = ar2;
+           }
        }
-      lhs_se.want_pointer = 1;
-      gfc_conv_expr_descriptor (&lhs_se, lhs_expr);
-      /* Using gfc_conv_expr_descriptor, we only get the descriptor, but that
-         has the wrong type if component references are done.  */
-      lhs_type = gfc_typenode_for_spec (&lhs_expr->ts);
-      tmp = build_fold_indirect_ref_loc (input_location, lhs_se.expr);
-      gfc_add_modify (&lhs_se.pre, gfc_conv_descriptor_dtype (tmp),
-                      gfc_get_dtype_rank_type (has_vector ? ar2.dimen
-                                                         : lhs_expr->rank,
-                     lhs_type));
-      if (has_vector)
+      else
        {
-         vec = conv_caf_vector_subscript (&block, lhs_se.expr, &ar2);
-         *ar = ar2;
+         /* Special casing for arr1 ([...]) = arr2[...], i.e. caf_get to
+            indexed array expression.  This is rewritten to:
+
+            tmp_array = arr2[...]
+            arr1 ([...]) = tmp_array
+
+            because using the standard gfc_conv_expr (lhs_expr) did the
+            assignment with lhs and rhs exchanged.  */
+
+         gfc_ss *lss_for_tmparray, *lss_real;
+         gfc_loopinfo loop;
+         gfc_se se;
+         stmtblock_t body;
+         tree tmparr_desc, src;
+         tree index = gfc_index_zero_node;
+         tree stride = gfc_index_zero_node;
+         int n;
+
+         /* Walk both sides of the assignment, once to get the shape of the
+            temporary array to create right.  */
+         lss_for_tmparray = gfc_walk_expr (lhs_expr);
+         /* And a second time to be able to create an assignment of the
+            temporary to the lhs_expr.  gfc_trans_create_temp_array replaces
+            the tree in the descriptor with the one for the temporary
+            array.  */
+         lss_real = gfc_walk_expr (lhs_expr);
+         gfc_init_loopinfo (&loop);
+         gfc_add_ss_to_loop (&loop, lss_for_tmparray);
+         gfc_add_ss_to_loop (&loop, lss_real);
+         gfc_conv_ss_startstride (&loop);
+         gfc_conv_loop_setup (&loop, &lhs_expr->where);
+         lhs_type = gfc_typenode_for_spec (&lhs_expr->ts);
+         gfc_trans_create_temp_array (&lhs_se.pre, &lhs_se.post,
+                                      lss_for_tmparray, lhs_type, NULL_TREE,
+                                      false, true, false,
+                                      &lhs_expr->where);
+         tmparr_desc = lss_for_tmparray->info->data.array.descriptor;
+         gfc_start_scalarized_body (&loop, &body);
+         gfc_init_se (&se, NULL);
+         gfc_copy_loopinfo_to_se (&se, &loop);
+         se.ss = lss_real;
+         gfc_conv_expr (&se, lhs_expr);
+         gfc_add_block_to_block (&body, &se.pre);
+
+         /* Walk over all indexes of the loop.  */
+         for (n = loop.dimen - 1; n > 0; --n)
+           {
+             tmp = loop.loopvar[n];
+             tmp = fold_build2_loc (input_location, MINUS_EXPR,
+                                    gfc_array_index_type, tmp, loop.from[n]);
+             tmp = fold_build2_loc (input_location, PLUS_EXPR,
+                                    gfc_array_index_type, tmp, index);
+
+             stride = fold_build2_loc (input_location, MINUS_EXPR,
+                                       gfc_array_index_type,
+                                       loop.to[n - 1], loop.from[n - 1]);
+             stride = fold_build2_loc (input_location, PLUS_EXPR,
+                                       gfc_array_index_type,
+                                       stride, gfc_index_one_node);
+
+             index = fold_build2_loc (input_location, MULT_EXPR,
+                                      gfc_array_index_type, tmp, stride);
+           }
+
+         index = fold_build2_loc (input_location, MINUS_EXPR,
+                                  gfc_array_index_type,
+                                  index, loop.from[0]);
+
+         index = fold_build2_loc (input_location, PLUS_EXPR,
+                                  gfc_array_index_type,
+                                  loop.loopvar[0], index);
+
+         src = build_fold_indirect_ref (gfc_conv_array_data (tmparr_desc));
+         src = gfc_build_array_ref (src, index, NULL);
+         /* Now create the assignment of lhs_expr = tmp_array.  */
+         gfc_add_modify (&body, se.expr, src);
+         gfc_add_block_to_block (&body, &se.post);
+         lhs_se.expr = gfc_build_addr_expr (NULL_TREE, tmparr_desc);
+         gfc_trans_scalarizing_loops (&loop, &body);
+         gfc_add_block_to_block (&loop.pre, &loop.post);
+         gfc_add_expr_to_block (&lhs_se.post, gfc_finish_block (&loop.pre));
+         gfc_free_ss (lss_for_tmparray);
+         gfc_free_ss (lss_real);
        }
     }
 
index 4c9fdf7bac7f73e5c062ddf6a8d26492372061f3..1369288a803f53eeafe33613673ee776c602e05b 100644 (file)
@@ -1,3 +1,10 @@
+2018-04-14  Andre Vehreschild  <vehre@gcc.gnu.org>
+
+       PR fortran/81773
+       PR fortran/83606
+       * gfortran.dg/coarray/get_to_indexed_array_1.f90: New test.
+       * gfortran.dg/coarray/get_to_indirect_array.f90: New test.
+
 2018-04-14  Thomas Koenig  <tkoenig@gcc.gnu.org>
 
        PR fortran/85387
diff --git a/gcc/testsuite/gfortran.dg/coarray/get_to_indexed_array_1.f90 b/gcc/testsuite/gfortran.dg/coarray/get_to_indexed_array_1.f90
new file mode 100644 (file)
index 0000000..0471471
--- /dev/null
@@ -0,0 +1,32 @@
+! { dg-do run }
+
+! Test that index vector on lhs of caf-expression works correctly.
+
+program pr81773
+
+  integer, parameter :: ndim = 5
+  integer :: i
+  integer :: vec(ndim) = -1
+  integer :: res(ndim)[*] = [ (i, i=1, ndim) ]
+  type T
+    integer :: padding
+    integer :: dest(ndim)
+    integer :: src(ndim)
+  end type
+
+  type(T) :: dest
+  type(T), allocatable :: caf[:]
+
+  vec([ndim, 3, 1]) = res(1:3)[1]
+  if (any (vec /= [ 3, -1, 2, -1, 1])) stop 1
+
+  dest = T(42, [ ( -1, i = 1, ndim ) ], [ ( i - 2, i = ndim, 1, -1) ] )
+  dest%dest([ 4,3,2 ]) = res(3:5)[1]
+  if (any (dest%dest /= [-1, 5, 4, 3, -1])) stop 2
+
+  vec(:) = -1
+  allocate(caf[*], source = T(42, [ ( -1, i = 1, ndim ) ], [ ( i - 2, i = ndim, 1, -1) ] ))
+  vec([ 5,3,2 ]) = caf[1]%src(2:4)
+  if (any (vec /= [ -1, 0, 1, -1, 2])) stop 3
+end
+
diff --git a/gcc/testsuite/gfortran.dg/coarray/get_to_indirect_array.f90 b/gcc/testsuite/gfortran.dg/coarray/get_to_indirect_array.f90
new file mode 100644 (file)
index 0000000..efb7835
--- /dev/null
@@ -0,0 +1,28 @@
+! { dg-do run }
+!
+! Test that pr81773/fortran is fixed.
+
+program get_to_indexed_array
+
+  integer, parameter :: ndim = 5
+  integer :: i
+  integer :: vec(1:ndim) = 0
+  integer :: indx(1:2) = [3, 2]
+  integer :: mat(1:ndim, 1:ndim) = 0
+  integer :: res(1:ndim)[*]=[ (i, i=1, ndim) ]
+
+  ! No sync needed, because this test always is running on single image
+  vec([ndim , 1]) = res(1:2)[1]
+  if (vec(1) /= res(2) .or. vec(ndim) /= res(1)) then
+    print *,"vec: ", vec, " on image: ", this_image()
+    stop 1
+  end if
+
+  mat(2:3,[indx(:)]) = reshape(res(1:4)[1], [2, 2])
+  if (any(mat(2:3, 3:2:-1) /= reshape(res(1:4), [2,2]))) then
+    print *, "mat: ", mat, " on image: ", this_image()
+    stop 2
+  end if
+end
+
+! vim:ts=2:sts=2:sw=2: