For PR52621 we analyze a loop nest (for prefetching) and end up with {(integer(kind=8)) {0, +, {2, +, 2}_2}_2, +, 1}_3 which we pass to various predicates in analyze_overlapping_iterations (the loop nest has loop->num == 1, 2 and 3 are nested in it).
First, evolution_function_is_univariate_p returns true for it because of bogus default cases (the outermost default case looks wrong, too, but fixing it is not required to fix this bug). Second, evolution_function_is_affine_multivariate_p returns true for it - something that is not true either - it's not affine after all. And the culprit here is evolution_function_is_invariant_rec_p which does not consider varying in nested loops properly. Bootstrap and regtest pending on x86_64-unknown-linux-gnu. I'm not terribly familiar with the SCEV notation nor its code and unfortunately Sebastian is not responding :/ So I'm going to take the bootstrap & regtest result as hint on whether I am right. Richard. 2012-04-11 Richard Guenther <rguent...@suse.de> PR middle-end/52621 * tree-chrec.c (evolution_function_is_invariant_rec_p): Properly consider loop nesting. (evolution_function_is_univariate_p): Properly check the remainder for chrecs. * gfortran.dg/pr52621.f90: New testcase. Index: gcc/tree-chrec.c =================================================================== *** gcc/tree-chrec.c (revision 186302) --- gcc/tree-chrec.c (working copy) *************** evolution_function_is_invariant_rec_p (t *** 1011,1016 **** --- 1029,1036 ---- if (TREE_CODE (chrec) == POLYNOMIAL_CHREC) { if (CHREC_VARIABLE (chrec) == (unsigned) loopnum + || flow_loop_nested_p (get_loop (loopnum), + get_loop (CHREC_VARIABLE (chrec))) || !evolution_function_is_invariant_rec_p (CHREC_RIGHT (chrec), loopnum) || !evolution_function_is_invariant_rec_p (CHREC_LEFT (chrec), *************** evolution_function_is_univariate_p (cons *** 1114,1119 **** --- 1134,1141 ---- break; default: + if (tree_contains_chrecs (CHREC_LEFT (chrec), NULL)) + return false; break; } *************** evolution_function_is_univariate_p (cons *** 1127,1132 **** --- 1149,1156 ---- break; default: + if (tree_contains_chrecs (CHREC_RIGHT (chrec), NULL)) + return false; break; } Index: gcc/testsuite/gfortran.dg/pr52621.f90 =================================================================== *** gcc/testsuite/gfortran.dg/pr52621.f90 (revision 0) --- gcc/testsuite/gfortran.dg/pr52621.f90 (revision 0) *************** *** 0 **** --- 1,20 ---- + ! { dg-do compile } + ! { dg-options "-O2 -fprefetch-loop-arrays" } + + SUBROUTINE GHDSYM(IZ,IS,LMMAX,S,LMS,Y,L2M,DRL,NLAY2,K0,DCUT)!, + ! + COMPLEX Y(L2M,L2M),H(33),S(LMS) + COMPLEX RU,CI,CZ,K0,FF,Z,Z1,Z2,Z3,ST + ! + DO 140 KK=1,4 + DO 130 L=1,L2M + L1=L*L-L + DO 120 M=1,L + IPM=L1+M + IMM=L1-M+2 + S(IPM)=S(IPM)+Z3*Y(L,M) + IF (M.NE.1) S(IMM)=S(IMM)+Z3*Y(M-1,L)*CSGN + 120 CONTINUE + 130 CONTINUE + 140 CONTINUE + END