From 4f0a0218d6df34ec612a61aef50b95d79cd8d17f Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 1 Dec 2015 14:24:54 +0000 Subject: [PATCH] re PR tree-optimization/68379 (BB vectorization: definition in block 13 follows the use for SSA_NAME) 2015-12-01 Richard Biener 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 | 8 ++++++ gcc/testsuite/ChangeLog | 7 +++++ gcc/testsuite/gcc.dg/torture/pr68379.c | 12 +++++++++ gcc/testsuite/gfortran.dg/pr68379-1.f90 | 35 +++++++++++++++++++++++++ gcc/testsuite/gfortran.dg/pr68379-2.f | 24 +++++++++++++++++ gcc/tree-vect-data-refs.c | 5 ++++ gcc/tree-vect-stmts.c | 27 +++++++++++++++++-- 7 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr68379.c create mode 100644 gcc/testsuite/gfortran.dg/pr68379-1.f90 create mode 100644 gcc/testsuite/gfortran.dg/pr68379-2.f diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 79d8d92700b..8c8718b2b30 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2015-12-01 Richard Biener + + 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 PR middle-end/68590 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9e9511df46c..e786fd887ed 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2015-12-01 Richard Biener + + 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 * 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 index 00000000000..6a3be7b5f5f --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr68379.c @@ -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 index 00000000000..2deaca03219 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr68379-1.f90 @@ -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 index 00000000000..e26520e133b --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr68379-2.f @@ -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 diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index 7962e360fb9..b59b40cf8d5 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -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 ()) diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 5bb2289ada0..db46eec46f2 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -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, -- 2.30.2