+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
+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.
--- /dev/null
+/* { 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];
+}
--- /dev/null
+! { 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
--- /dev/null
+! { 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
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 ())
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;
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))
(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,