re PR tree-optimization/68379 (BB vectorization: definition in block 13 follows the...
authorRichard Biener <rguenther@suse.de>
Tue, 1 Dec 2015 14:24:54 +0000 (14:24 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 1 Dec 2015 14:24:54 +0000 (14:24 +0000)
2015-12-01  Richard Biener  <rguenther@suse.de>

PR tree-optimization/68379
* tree-vect-stmts.c (vectorizable_load): For BB vectorization
always base loads on the first used DR of a group.
* tree-vect-data-refs.c (vect_slp_analyze_and_verify_node_alignment):
Compute alignment of the first scalar element unconditionally.

* gcc.dg/torture/pr68379.c: New testcase.
* gfortran.dg/pr68379-1.f90: Likewise.
* gfortran.dg/pr68379-2.f: Likewise.

From-SVN: r231111

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr68379.c [new file with mode: 0644]
gcc/testsuite/gfortran.dg/pr68379-1.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/pr68379-2.f [new file with mode: 0644]
gcc/tree-vect-data-refs.c
gcc/tree-vect-stmts.c

index 79d8d92700b53e0ee280d99e80bb6a23dc15b9f2..8c8718b2b304b1e0981db4a60b90db436fe00ec8 100644 (file)
@@ -1,3 +1,11 @@
+2015-12-01  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/68379
+       * tree-vect-stmts.c (vectorizable_load): For BB vectorization
+       always base loads on the first used DR of a group.
+       * tree-vect-data-refs.c (vect_slp_analyze_and_verify_node_alignment):
+       Compute alignment of the first scalar element unconditionally.
+
 2015-12-01  Richard Biener  <rguenther@suse.de>
 
        PR middle-end/68590
index 9e9511df46c3fa0c6f2692abc9fa65050560f888..e786fd887ed379534dca4febd119cb4a1328ed31 100644 (file)
@@ -1,3 +1,10 @@
+2015-12-01  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/68379
+       * gcc.dg/torture/pr68379.c: New testcase.
+       * gfortran.dg/pr68379-1.f90: Likewise.
+       * gfortran.dg/pr68379-2.f: Likewise.
+
 2015-12-01  Christophe Lyon  <christophe.lyon@linaro.org>
 
        * gcc.dg/pr46032.c: Add dg-require-effective-target fopenmp.
diff --git a/gcc/testsuite/gcc.dg/torture/pr68379.c b/gcc/testsuite/gcc.dg/torture/pr68379.c
new file mode 100644 (file)
index 0000000..6a3be7b
--- /dev/null
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+
+int a, b[3], c[3][5];
+
+void
+fn1 ()
+{
+  int e;
+  for (a = 2; a >= 0; a--)
+    for (e = 0; e < 4; e++)
+      c[a][e] = b[a];
+}
diff --git a/gcc/testsuite/gfortran.dg/pr68379-1.f90 b/gcc/testsuite/gfortran.dg/pr68379-1.f90
new file mode 100644 (file)
index 0000000..2deaca0
--- /dev/null
@@ -0,0 +1,35 @@
+! { dg-do compile }
+! { dg-options "-O3" }
+MODULE qs_efield_berry
+  TYPE cp_error_type
+  END TYPE
+  INTEGER, PARAMETER :: dp=8
+  TYPE qs_energy_type
+    REAL(KIND=dp), POINTER :: efield
+  END TYPE
+  TYPE qs_environment_type
+  END TYPE
+  INTERFACE 
+    SUBROUTINE foo(qs_env,energy,error)
+       IMPORT 
+       TYPE(qs_environment_type), POINTER :: qs_env
+       TYPE(cp_error_type)      :: error
+       TYPE(qs_energy_type), POINTER   :: energy
+    END SUBROUTINE
+  END INTERFACE
+CONTAINS
+  SUBROUTINE qs_efield_mo_derivatives()
+    TYPE(qs_environment_type), POINTER :: qs_env
+    TYPE(cp_error_type)  :: error
+    COMPLEX(dp)          ::   zi(3), zphase(3)
+    REAL(dp)             :: ci(3)
+    TYPE(qs_energy_type), POINTER      :: energy
+    CALL foo(qs_env, energy, error)
+    zi = zi * zphase
+    ci = AIMAG(LOG(zi))
+    DO idir=1,3
+       ener_field=ener_field+ci(idir)*fieldfac(idir)
+    END DO
+    energy%efield=ener_field
+  END SUBROUTINE qs_efield_mo_derivatives
+END MODULE qs_efield_berry
diff --git a/gcc/testsuite/gfortran.dg/pr68379-2.f b/gcc/testsuite/gfortran.dg/pr68379-2.f
new file mode 100644 (file)
index 0000000..e26520e
--- /dev/null
@@ -0,0 +1,24 @@
+! { dg-do compile }
+! { dg-additional-options "-Ofast" }
+! { dg-additional-options "-mavx" { target x86_64-*-* i?86-*-* } }
+
+      SUBROUTINE PASSB4 (IDO,L1,CC,CH,WA1,WA2,WA3)
+      IMPLICIT REAL(4) (A-H, O-Z)
+      DIMENSION CC(IDO,4,L1), CH(IDO,L1,4), WA1(*), WA2(*), WA3(*)
+  102 DO 104 K=1,L1
+         DO 103 I=2,IDO,2
+            TI1 = CC(I,1,K)-CC(I,3,K)
+            TI2 = CC(I,1,K)+CC(I,3,K)
+            TI3 = CC(I,2,K)+CC(I,4,K)
+            TR2 = CC(I-1,1,K)+CC(I-1,3,K)
+            TI4 = CC(I-1,2,K)-CC(I-1,4,K)
+            TR3 = CC(I-1,2,K)+CC(I-1,4,K)
+            CH(I-1,K,1) = TR2+TR3
+            CH(I,K,1) = TI2+TI3
+            CI4 = TI1-TI4
+            CH(I-1,K,4) = CI4
+            CH(I,K,4) = CI4
+  103    CONTINUE
+  104 CONTINUE
+      RETURN
+      END
index 7962e360fb9f5d9b0bc7473df223ff360c4de35c..b59b40cf8d53e054b1d110c5bb8d58078d5003eb 100644 (file)
@@ -2102,11 +2102,16 @@ vect_slp_analyze_and_verify_node_alignment (slp_tree node)
      the node is permuted in which case we start from the first
      element in the group.  */
   gimple *first_stmt = SLP_TREE_SCALAR_STMTS (node)[0];
+  data_reference_p first_dr = STMT_VINFO_DATA_REF (vinfo_for_stmt (first_stmt));
   if (SLP_TREE_LOAD_PERMUTATION (node).exists ())
     first_stmt = GROUP_FIRST_ELEMENT (vinfo_for_stmt (first_stmt));
 
   data_reference_p dr = STMT_VINFO_DATA_REF (vinfo_for_stmt (first_stmt));
   if (! vect_compute_data_ref_alignment (dr)
+      /* For creating the data-ref pointer we need alignment of the
+        first element anyway.  */
+      || (dr != first_dr
+         && ! vect_compute_data_ref_alignment (first_dr))
       || ! verify_data_ref_alignment (dr))
     {
       if (dump_enabled_p ())
index 5bb2289ada08b86433f51ebf7ae740c284b61fc3..db46eec46f288642d9cdb61106d24a2f8219ef2b 100644 (file)
@@ -6148,6 +6148,7 @@ vectorizable_load (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt,
   bool grouped_load = false;
   bool load_lanes_p = false;
   gimple *first_stmt;
+  gimple *first_stmt_for_drptr = NULL;
   bool inv_p;
   bool negative = false;
   bool compute_in_loop = false;
@@ -6751,10 +6752,14 @@ vectorizable_load (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt,
   if (grouped_load)
     {
       first_stmt = GROUP_FIRST_ELEMENT (stmt_info);
-      /* For BB vectorization we directly vectorize a subchain
+      /* For SLP vectorization we directly vectorize a subchain
          without permutation.  */
       if (slp && ! SLP_TREE_LOAD_PERMUTATION (slp_node).exists ())
-        first_stmt = SLP_TREE_SCALAR_STMTS (slp_node)[0];
+       first_stmt = SLP_TREE_SCALAR_STMTS (slp_node)[0];
+      /* For BB vectorization always use the first stmt to base
+        the data ref pointer on.  */
+      if (bb_vinfo)
+       first_stmt_for_drptr = SLP_TREE_SCALAR_STMTS (slp_node)[0];
 
       /* Check if the chain of loads is already vectorized.  */
       if (STMT_VINFO_VEC_STMT (vinfo_for_stmt (first_stmt))
@@ -6966,6 +6971,24 @@ vectorizable_load (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt,
                                              (DR_REF (first_dr)), 0);
              inv_p = false;
            }
+         else if (first_stmt_for_drptr
+                  && first_stmt != first_stmt_for_drptr)
+           {
+             dataref_ptr
+               = vect_create_data_ref_ptr (first_stmt_for_drptr, aggr_type,
+                                           at_loop, offset, &dummy, gsi,
+                                           &ptr_incr, simd_lane_access_p,
+                                           &inv_p, byte_offset);
+             /* Adjust the pointer by the difference to first_stmt.  */
+             data_reference_p ptrdr
+               = STMT_VINFO_DATA_REF (vinfo_for_stmt (first_stmt_for_drptr));
+             tree diff = fold_convert (sizetype,
+                                       size_binop (MINUS_EXPR,
+                                                   DR_INIT (first_dr),
+                                                   DR_INIT (ptrdr)));
+             dataref_ptr = bump_vector_ptr (dataref_ptr, ptr_incr, gsi,
+                                            stmt, diff);
+           }
          else
            dataref_ptr
              = vect_create_data_ref_ptr (first_stmt, aggr_type, at_loop,