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.

Reply via email to