The two users of tree-data-ref's runtime alias checks both canonicalise the order of the dr_with_seg_lens in a pair before passing them to prune_runtime_alias_test_list. It's more convenient for later patches if prune_runtime_alias_test_list does that itself.
2019-11-11 Richard Sandiford <richard.sandif...@arm.com> gcc/ * tree-data-ref.c (prune_runtime_alias_test_list): Sort the two accesses in each dr_with_seg_len_pair_t before trying to combine separate dr_with_seg_len_pair_ts. * tree-loop-distribution.c (compute_alias_check_pairs): Don't do that here. * tree-vect-data-refs.c (vect_prune_runtime_alias_test_list): Likewise. Index: gcc/tree-data-ref.c =================================================================== --- gcc/tree-data-ref.c 2019-07-18 09:22:13.893767915 +0100 +++ gcc/tree-data-ref.c 2019-11-11 18:30:43.203244558 +0000 @@ -1487,13 +1487,32 @@ comp_dr_with_seg_len_pair (const void *p prune_runtime_alias_test_list (vec<dr_with_seg_len_pair_t> *alias_pairs, poly_uint64) { + /* Canonicalize each pair so that the base components are ordered wrt + data_ref_compare_tree. This allows the loop below to merge more + cases. */ + unsigned int i; + dr_with_seg_len_pair_t *alias_pair; + FOR_EACH_VEC_ELT (*alias_pairs, i, alias_pair) + { + data_reference_p dr_a = alias_pair->first.dr; + data_reference_p dr_b = alias_pair->second.dr; + int comp_res = data_ref_compare_tree (DR_BASE_ADDRESS (dr_a), + DR_BASE_ADDRESS (dr_b)); + if (comp_res == 0) + comp_res = data_ref_compare_tree (DR_OFFSET (dr_a), DR_OFFSET (dr_b)); + if (comp_res == 0) + comp_res = data_ref_compare_tree (DR_INIT (dr_a), DR_INIT (dr_b)); + if (comp_res > 0) + std::swap (alias_pair->first, alias_pair->second); + } + /* Sort the collected data ref pairs so that we can scan them once to combine all possible aliasing checks. */ alias_pairs->qsort (comp_dr_with_seg_len_pair); /* Scan the sorted dr pairs and check if we can combine alias checks of two neighboring dr pairs. */ - for (size_t i = 1; i < alias_pairs->length (); ++i) + for (i = 1; i < alias_pairs->length (); ++i) { /* Deal with two ddrs (dr_a1, dr_b1) and (dr_a2, dr_b2). */ dr_with_seg_len *dr_a1 = &(*alias_pairs)[i-1].first, Index: gcc/tree-loop-distribution.c =================================================================== --- gcc/tree-loop-distribution.c 2019-07-10 19:41:20.539944929 +0100 +++ gcc/tree-loop-distribution.c 2019-11-11 18:30:43.207244530 +0000 @@ -2457,12 +2457,6 @@ compute_alias_check_pairs (class loop *l struct data_reference *dr_a = DDR_A (ddr); struct data_reference *dr_b = DDR_B (ddr); tree seg_length_a, seg_length_b; - int comp_res = data_ref_compare_tree (DR_BASE_ADDRESS (dr_a), - DR_BASE_ADDRESS (dr_b)); - - if (comp_res == 0) - comp_res = data_ref_compare_tree (DR_OFFSET (dr_a), DR_OFFSET (dr_b)); - gcc_assert (comp_res != 0); if (latch_dominated_by_data_ref (loop, dr_a)) seg_length_a = data_ref_segment_size (dr_a, niters_plus_one); @@ -2485,10 +2479,6 @@ compute_alias_check_pairs (class loop *l (dr_with_seg_len (dr_a, seg_length_a, access_size_a, align_a), dr_with_seg_len (dr_b, seg_length_b, access_size_b, align_b)); - /* Canonicalize pairs by sorting the two DR members. */ - if (comp_res > 0) - std::swap (dr_with_seg_len_pair.first, dr_with_seg_len_pair.second); - comp_alias_pairs->safe_push (dr_with_seg_len_pair); } Index: gcc/tree-vect-data-refs.c =================================================================== --- gcc/tree-vect-data-refs.c 2019-11-08 16:06:18.948980179 +0000 +++ gcc/tree-vect-data-refs.c 2019-11-11 18:30:43.207244530 +0000 @@ -3478,7 +3478,6 @@ vect_prune_runtime_alias_test_list (loop /* First, we collect all data ref pairs for aliasing checks. */ FOR_EACH_VEC_ELT (may_alias_ddrs, i, ddr) { - int comp_res; poly_uint64 lower_bound; tree segment_length_a, segment_length_b; unsigned HOST_WIDE_INT access_size_a, access_size_b; @@ -3594,14 +3593,11 @@ vect_prune_runtime_alias_test_list (loop align_a = vect_vfa_align (dr_info_a); align_b = vect_vfa_align (dr_info_b); - comp_res = data_ref_compare_tree (DR_BASE_ADDRESS (dr_info_a->dr), - DR_BASE_ADDRESS (dr_info_b->dr)); - if (comp_res == 0) - comp_res = data_ref_compare_tree (DR_OFFSET (dr_info_a->dr), - DR_OFFSET (dr_info_b->dr)); - /* See whether the alias is known at compilation time. */ - if (comp_res == 0 + if (operand_equal_p (DR_BASE_ADDRESS (dr_info_a->dr), + DR_BASE_ADDRESS (dr_info_b->dr), 0) + && operand_equal_p (DR_OFFSET (dr_info_a->dr), + DR_OFFSET (dr_info_b->dr), 0) && TREE_CODE (DR_STEP (dr_info_a->dr)) == INTEGER_CST && TREE_CODE (DR_STEP (dr_info_b->dr)) == INTEGER_CST && poly_int_tree_p (segment_length_a) @@ -3640,10 +3636,6 @@ vect_prune_runtime_alias_test_list (loop dr_with_seg_len (dr_info_b->dr, segment_length_b, access_size_b, align_b)); - /* Canonicalize pairs by sorting the two DR members. */ - if (comp_res > 0) - std::swap (dr_with_seg_len_pair.first, dr_with_seg_len_pair.second); - comp_alias_ddrs.safe_push (dr_with_seg_len_pair); }