data-ref: Improve non-loop disambiguation [PR106019]
When dr_may_alias_p is called without a loop context, it tries to use the tree-affine interface to calculate the difference between the two addresses and use that difference to check whether the gap between the accesses is known at compile time. However, as the example in the PR shows, this doesn't expand SSA_NAMEs and so can easily be defeated by things like reassociation. One fix would have been to use aff_combination_expand to expand the SSA_NAMEs, but we'd then need some way of maintaining the associated cache. This patch instead reuses the innermost_loop_behavior fields (which exist even when no loop context is provided). It might still be useful to do the aff_combination_expand thing too, if an example turns out to need it. gcc/ PR tree-optimization/106019 * tree-data-ref.cc (dr_may_alias_p): Try using the innermost_loop_behavior to disambiguate non-loop queries. gcc/testsuite/ PR tree-optimization/106019 * gcc.dg/vect/bb-slp-pr106019.c: New test.
This commit is contained in:
parent
98b6e62cf5
commit
038b077689
15
gcc/testsuite/gcc.dg/vect/bb-slp-pr106019.c
Normal file
15
gcc/testsuite/gcc.dg/vect/bb-slp-pr106019.c
Normal file
@ -0,0 +1,15 @@
|
||||
/* { dg-do compile } */
|
||||
|
||||
void f(double *p, long i)
|
||||
{
|
||||
p[i+0] += 1;
|
||||
p[i+1] += 1;
|
||||
}
|
||||
void g(double *p, long i)
|
||||
{
|
||||
double *q = p + i;
|
||||
q[0] += 1;
|
||||
q[1] += 1;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-not "can't determine dependence" slp2 } } */
|
@ -2968,6 +2968,25 @@ dr_may_alias_p (const struct data_reference *a, const struct data_reference *b,
|
||||
disambiguation. */
|
||||
if (!loop_nest)
|
||||
{
|
||||
tree tree_size_a = TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (a)));
|
||||
tree tree_size_b = TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (b)));
|
||||
|
||||
if (DR_BASE_ADDRESS (a)
|
||||
&& DR_BASE_ADDRESS (b)
|
||||
&& operand_equal_p (DR_BASE_ADDRESS (a), DR_BASE_ADDRESS (b))
|
||||
&& operand_equal_p (DR_OFFSET (a), DR_OFFSET (b))
|
||||
&& poly_int_tree_p (tree_size_a)
|
||||
&& poly_int_tree_p (tree_size_b)
|
||||
&& !ranges_maybe_overlap_p (wi::to_widest (DR_INIT (a)),
|
||||
wi::to_widest (tree_size_a),
|
||||
wi::to_widest (DR_INIT (b)),
|
||||
wi::to_widest (tree_size_b)))
|
||||
{
|
||||
gcc_assert (integer_zerop (DR_STEP (a))
|
||||
&& integer_zerop (DR_STEP (b)));
|
||||
return false;
|
||||
}
|
||||
|
||||
aff_tree off1, off2;
|
||||
poly_widest_int size1, size2;
|
||||
get_inner_reference_aff (DR_REF (a), &off1, &size1);
|
||||
|
Loading…
Reference in New Issue
Block a user