https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101173
--- Comment #5 from bin cheng <amker at gcc dot gnu.org> --- (In reply to Richard Biener from comment #3) > So we're exchanging the inner two loops > > a[1][3] = 8; > for (int b = 1; b <= 5; b++) > for (int d = 0; d <= 5; d++) > for (c = 0; c <= 5; c++) > a[b][c] = a[b][c + 2] & 216; > > to > > a[1][3] = 8; > for (int b = 1; b <= 5; b++) > for (c = 0; c <= 5; c++) > for (int d = 0; d <= 5; d++) > a[b][c] = a[b][c + 2] & 216; > > but that looks wrong from a dependence analysis perspective. We have > > (compute_affine_dependence > ref_a: a[b_33][_1], stmt_a: _2 = a[b_33][_1]; > ref_b: a[b_33][c.3_32], stmt_b: a[b_33][c.3_32] = _3; > (analyze_overlapping_iterations > (chrec_a = {2, +, 1}_5) > (chrec_b = {0, +, 1}_5) > (analyze_siv_subscript > (analyze_subscript_affine_affine > (overlaps_a = [0 + 1 * x_1]) > (overlaps_b = [2 + 1 * x_1])) > ) > (overlap_iterations_a = [0 + 1 * x_1]) > (overlap_iterations_b = [2 + 1 * x_1])) > (analyze_overlapping_iterations > (chrec_a = {1, +, 1}_1) > (chrec_b = {1, +, 1}_1) > (overlap_iterations_a = [0]) > (overlap_iterations_b = [0])) > (analyze_overlapping_iterations > (chrec_a = {0, +, 1}_5) > (chrec_b = {2, +, 1}_5) > (analyze_siv_subscript > (analyze_subscript_affine_affine > (overlaps_a = [2 + 1 * x_1]) > (overlaps_b = [0 + 1 * x_1])) > ) > (overlap_iterations_a = [2 + 1 * x_1]) > (overlap_iterations_b = [0 + 1 * x_1])) > (analyze_overlapping_iterations > (chrec_a = {1, +, 1}_1) > (chrec_b = {1, +, 1}_1) > (overlap_iterations_a = [0]) > (overlap_iterations_b = [0])) > (build_classic_dist_vector > dist_vector = ( 0 0 2 > ) > ) > ) > > I don't see anything wrong with that at a first glance so the bug must be in > tree_loop_interchange::valid_data_dependences it checks > > /* Be conservative, skip case if either direction at i_idx/o_idx > levels is not '=' or '<'. */ > if (dist_vect[i_idx] < 0 || dist_vect[o_idx] < 0) > return false; > > dist_vect is [0 0 2], i_idx 2 and o_idx 1 but I think that dist_vect[o_idx] > should exclude zero, thus > > diff --git a/gcc/gimple-loop-interchange.cc b/gcc/gimple-loop-interchange.cc > index f45b9364644..265e36c48d4 100644 > --- a/gcc/gimple-loop-interchange.cc > +++ b/gcc/gimple-loop-interchange.cc > @@ -1043,8 +1043,8 @@ tree_loop_interchange::valid_data_dependences > (unsigned i_idx, unsigned o_idx, > continue; > > /* Be conservative, skip case if either direction at i_idx/o_idx > - levels is not '=' or '<'. */ > - if (dist_vect[i_idx] < 0 || dist_vect[o_idx] < 0) > + levels is not '=' (for the inner loop) or '<'. */ > + if (dist_vect[i_idx] < 0 || dist_vect[o_idx] <= 0) > return false; > } > } > > Bin - does this analysis look sound? Hi Richard, Thanks very much for helping on this. Sorry I would need a bit more time to answer this question. Thanks again.