The testcase shows that we rely on consistently rejecting all group members from vect_analyze_data_ref_access but that isn't done reliably when they are not in the same loop level (and thus nested_in_vect_loop_p doesn't return the same answer for all group elements). Of course such groups are hardly useful thus the following patch fixes group detection for this (and not the still somewhat fragile 'mark this as non-group' code in vect_analyze_data_ref_access).
Bootstrapped on x86_64-unknown-linux-gnu, testing in progress. Richard. 2015-12-02 Richard Biener <rguent...@suse.de> PR tree-optimization/68639 * tree-vect-data-refs.c (dr_group_sort_cmp): Split groups belonging to different loops. (vect_analyze_data_ref_accesses): Likewise. * gfortran.fortran-torture/compile/pr68639.f90: New testcase. Index: gcc/tree-vect-data-refs.c =================================================================== --- gcc/tree-vect-data-refs.c (revision 231163) +++ gcc/tree-vect-data-refs.c (working copy) @@ -2597,6 +2597,12 @@ dr_group_sort_cmp (const void *dra_, con if (dra == drb) return 0; + /* DRs in different loops never belong to the same group. */ + loop_p loopa = gimple_bb (DR_STMT (dra))->loop_father; + loop_p loopb = gimple_bb (DR_STMT (drb))->loop_father; + if (loopa != loopb) + return loopa->num < loopb->num ? -1 : 1; + /* Ordering of DRs according to base. */ if (!operand_equal_p (DR_BASE_ADDRESS (dra), DR_BASE_ADDRESS (drb), 0)) { @@ -2688,6 +2694,12 @@ vect_analyze_data_ref_accesses (vec_info matters we can push those to a worklist and re-iterate over them. The we can just skip ahead to the next DR here. */ + /* DRs in a different loop should not be put into the same + interleaving group. */ + if (gimple_bb (DR_STMT (dra))->loop_father + != gimple_bb (DR_STMT (drb))->loop_father) + break; + /* Check that the data-refs have same first location (except init) and they are both either store or load (not load and store, not masked loads or stores). */ Index: gcc/testsuite/gfortran.fortran-torture/compile/pr68639.f90 =================================================================== --- gcc/testsuite/gfortran.fortran-torture/compile/pr68639.f90 (revision 0) +++ gcc/testsuite/gfortran.fortran-torture/compile/pr68639.f90 (working copy) @@ -0,0 +1,22 @@ + SUBROUTINE makeCoulE0(natorb,Coul) + INTEGER, PARAMETER :: dp=8 + REAL(KIND=dp), PARAMETER :: fourpi=432.42, oorootpi=13413.3142 + INTEGER :: natorb + REAL(KIND=dp), DIMENSION(45, 45), & + INTENT(OUT) :: Coul + INTEGER :: gpt, imA, imB, k1, k2, k3, & + k4, lp, mp, np + REAL(KIND=dp) :: alpha, d2f(3,3), & + d4f(3,3,3,3), f, ff, w + REAL(KIND=dp), DIMENSION(3, 45) :: M1A + REAL(KIND=dp), DIMENSION(45) :: M0A + DO imA=1, (natorb*(natorb+1))/2 + DO imB=1, (natorb*(natorb+1))/2 + w= M0A(imA)*M0A(imB) + DO k1=1,3 + w=w+ M1A(k1,imA)*M1A(k1,imB) + ENDDO + Coul(imA,imB)=Coul(imA,imB)-4.0_dp*alpha**3*oorootpi*w/3.0_dp + ENDDO + ENDDO + END SUBROUTINE makeCoulE0