re PR tree-optimization/49957 (Fails to SLP in 410.bwaves)
authorRichard Guenther <rguenther@suse.de>
Thu, 4 Aug 2011 12:22:42 +0000 (12:22 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 4 Aug 2011 12:22:42 +0000 (12:22 +0000)
2011-08-04  Richard Guenther  <rguenther@suse.de>

PR fortran/49957
* trans-array.c (add_to_offset): New function.
(gfc_conv_array_ref): Build the array index expression in optimally
associated order.
(gfc_walk_variable_expr): Adjust for the backward walk.

* gfortran.dg/vect/O3-pr49957.f: New testcase.

From-SVN: r177368

gcc/fortran/ChangeLog
gcc/fortran/trans-array.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/vect/O3-pr49957.f [new file with mode: 0644]

index 912c011ba0a781bf38d0678641ba12b9b03944e9..d794d14ace006a6964241661071db6d14093111d 100644 (file)
@@ -1,3 +1,11 @@
+2011-08-04  Richard Guenther  <rguenther@suse.de>
+
+       PR fortran/49957
+       * trans-array.c (add_to_offset): New function.
+       (gfc_conv_array_ref): Build the array index expression in optimally
+       associated order.
+       (gfc_walk_variable_expr): Adjust for the backward walk.
+
 2011-08-02  Daniel Kraft  <d@domob.eu>
 
        PR fortran/49885
index 85acf0cfbd033f9cb179362664610dae483c51fd..3a756584933dc859c26547619d1d2649b6aff9c0 100644 (file)
@@ -2622,6 +2622,22 @@ gfc_conv_tmp_array_ref (gfc_se * se)
   gfc_advance_se_ss_chain (se);
 }
 
+/* Add T to the offset pair *OFFSET, *CST_OFFSET.  */
+
+static void
+add_to_offset (tree *cst_offset, tree *offset, tree t)
+{
+  if (TREE_CODE (t) == INTEGER_CST)
+    *cst_offset = int_const_binop (PLUS_EXPR, *cst_offset, t);
+  else
+    {
+      if (!integer_zerop (*offset))
+       *offset = fold_build2_loc (input_location, PLUS_EXPR,
+                                  gfc_array_index_type, *offset, t);
+      else
+       *offset = t;
+    }
+}
 
 /* Build an array reference.  se->expr already holds the array descriptor.
    This should be either a variable, indirect variable reference or component
@@ -2634,7 +2650,7 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_symbol * sym,
                    locus * where)
 {
   int n;
-  tree index;
+  tree offset, cst_offset;
   tree tmp;
   tree stride;
   gfc_se indexse;
@@ -2669,10 +2685,12 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_symbol * sym,
       return;
     }
 
-  index = gfc_index_zero_node;
+  cst_offset = offset = gfc_index_zero_node;
+  add_to_offset (&cst_offset, &offset, gfc_conv_array_offset (se->expr));
 
-  /* Calculate the offsets from all the dimensions.  */
-  for (n = 0; n < ar->dimen; n++)
+  /* Calculate the offsets from all the dimensions.  Make sure to associate
+     the final offset so that we form a chain of loop invariant summands.  */
+  for (n = ar->dimen - 1; n >= 0; n--)
     {
       /* Calculate the index for this dimension.  */
       gfc_init_se (&indexse, se);
@@ -2741,19 +2759,17 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_symbol * sym,
                             indexse.expr, stride);
 
       /* And add it to the total.  */
-      index = fold_build2_loc (input_location, PLUS_EXPR,
-                              gfc_array_index_type, index, tmp);
+      add_to_offset (&cst_offset, &offset, tmp);
     }
 
-  tmp = gfc_conv_array_offset (se->expr);
-  if (!integer_zerop (tmp))
-    index = fold_build2_loc (input_location, PLUS_EXPR,
-                            gfc_array_index_type, index, tmp);
+  if (!integer_zerop (cst_offset))
+    offset = fold_build2_loc (input_location, PLUS_EXPR,
+                             gfc_array_index_type, offset, cst_offset);
 
   /* Access the calculated element.  */
   tmp = gfc_conv_array_data (se->expr);
   tmp = build_fold_indirect_ref (tmp);
-  se->expr = gfc_build_array_ref (tmp, index, sym->backend_decl);
+  se->expr = gfc_build_array_ref (tmp, offset, sym->backend_decl);
 }
 
 
@@ -7575,7 +7591,7 @@ gfc_walk_variable_expr (gfc_ss * ss, gfc_expr * expr)
       switch (ar->type)
        {
        case AR_ELEMENT:
-         for (n = 0; n < ar->dimen + ar->codimen; n++)
+         for (n = ar->dimen + ar->codimen - 1; n >= 0; n--)
            {
              newss = gfc_get_ss ();
              newss->type = GFC_SS_SCALAR;
index d1d45698917d755261cbb9b7ffbafa21eb18fe9c..9145186a53e20b9bc2fe6600b46264382303fe8e 100644 (file)
@@ -1,3 +1,8 @@
+2011-08-04  Richard Guenther  <rguenther@suse.de>
+
+       PR fortran/49957
+       * gfortran.dg/vect/O3-pr49957.f: New testcase.
+
 2011-08-04  Ian Bolton  <ian.bolton@arm.com>
 
        * gcc.target/arm/vfp-1.c: no large negative offsets on Thumb2.
diff --git a/gcc/testsuite/gfortran.dg/vect/O3-pr49957.f b/gcc/testsuite/gfortran.dg/vect/O3-pr49957.f
new file mode 100644 (file)
index 0000000..a973567
--- /dev/null
@@ -0,0 +1,16 @@
+! { dg-do compile }
+! { dg-require-effective-target vect_double }
+      subroutine shell(nx,ny,nz,q,dq)
+      implicit none
+      integer i,j,k,l,nx,ny,nz
+      real*8 q(5,nx,ny),dq(5,nx,ny)
+         do j=1,ny
+            do i=1,nx
+               do l=1,5
+                  q(l,i,j)=q(l,i,j)+dq(l,i,j)
+               enddo
+            enddo
+         enddo
+      return
+      end
+! { dg-final { scan-tree-dump "vectorized 1 loops" "vect" { xfail vect_no_align } } }