diff mbox series

Enable nonoverallping_component_refs even after the base pointers are equivalent

Message ID 20190702091448.jeum2qlk33d7ddl4@kam.mff.cuni.cz
State New
Headers show
Series Enable nonoverallping_component_refs even after the base pointers are equivalent | expand

Commit Message

Jan Hubicka July 2, 2019, 9:14 a.m. UTC
Hi,
this patch adds the shortcut for must aliases discussed earlier and enables
access path even if bases are proved to be equivalent - it could still do
useful job for arrays etc.

tramp3d stats go from:

Alias oracle query stats:
  refs_may_alias_p: 4421560 disambiguations, 4781790 queries
  ref_maybe_used_by_call_p: 6790 disambiguations, 4447962 queries
  call_may_clobber_ref_p: 883 disambiguations, 883 queries
  nonoverlapping_component_refs_p: 0 disambiguations, 9272 queries
  nonoverlapping_component_refs_since_match_p: 31 disambiguations, 39391 queries
  aliasing_component_refs_p: 918 disambiguations, 30889 queries
  TBAA oracle: 1924468 disambiguations 3851145 queries
               774336 are in alias set 0
               714019 queries asked about the same object
               0 queries asked about the same alias set
               0 access volatile
               282546 are dependent in the DAG
               155776 are aritificially in conflict with void *

to

Alias oracle query stats:
  refs_may_alias_p: 4421611 disambiguations, 4781828 queries
  ref_maybe_used_by_call_p: 6790 disambiguations, 4448013 queries
  call_may_clobber_ref_p: 883 disambiguations, 883 queries
  nonoverlapping_component_refs_p: 0 disambiguations, 8964 queries
  nonoverlapping_component_refs_since_match_p: 66 disambiguations, 18470 queries
  aliasing_component_refs_p: 918 disambiguations, 30371 queries
  TBAA oracle: 1924492 disambiguations 3849967 queries
               774336 are in alias set 0
               714095 queries asked about the same object
               0 queries asked about the same alias set
               0 access volatile
               281268 are dependent in the DAG
               155776 are aritificially in conflict with void *

PTA query stats:
  pt_solution_includes: 906632 disambiguations, 1214744 queries
  pt_solutions_intersect: 121330 disambiguations, 553172 queries

So twice as many nonoverlapping_component_refs_since_match_p disambiguations,
half of querries.

We can miss some of disambiguations where addresses are same but types
are different, but I think those are not useful - this is the case where
memory type was dynamically changed.  If we walk with TBAA enabled and
see the prevoius use, we got kind of lost anyway and propagating even
older values seems to have no use.

Note that i tried to implement ranges_must_overlap_p predicate which could
save us from more tests but got lost in polyints and I think it is not worth
the effort since these cases are quite borderline.

Similar test would make sense in aliasing_component_refs_p but I think
it may make more sense to reorder the tests there. Right now we do:

  get_ref_base_and_extent (match2, &offadj, &sztmp, &msztmp, &reverse);
  offset2 -= offadj;
  get_ref_base_and_extent (match1, &offadj, &sztmp, &msztmp, &reverse);
  offset1 -= offadj;
  if (!ranges_maybe_overlap_p (offset1, max_size1, offset2, max_size2))

First I think that one get_ref_base_and_extent is always redundant since either
match1 or match2 is base so we could pass it down.

However it seems to me that perhaps doing
nonoverlapping_component_refs_since_match_p would be cheaper and one can do the
range check only after this one returns -1 saving quite many
get_ref_base_and_extent calls.

Bootstrapped/regtested x86_64-linux, OK?

Honza

Comments

Richard Biener July 3, 2019, 12:39 p.m. UTC | #1
On Tue, 2 Jul 2019, Jan Hubicka wrote:

> Hi,
> this patch adds the shortcut for must aliases discussed earlier and enables
> access path even if bases are proved to be equivalent - it could still do
> useful job for arrays etc.
> 
> tramp3d stats go from:
> 
> Alias oracle query stats:
>   refs_may_alias_p: 4421560 disambiguations, 4781790 queries
>   ref_maybe_used_by_call_p: 6790 disambiguations, 4447962 queries
>   call_may_clobber_ref_p: 883 disambiguations, 883 queries
>   nonoverlapping_component_refs_p: 0 disambiguations, 9272 queries
>   nonoverlapping_component_refs_since_match_p: 31 disambiguations, 39391 queries
>   aliasing_component_refs_p: 918 disambiguations, 30889 queries
>   TBAA oracle: 1924468 disambiguations 3851145 queries
>                774336 are in alias set 0
>                714019 queries asked about the same object
>                0 queries asked about the same alias set
>                0 access volatile
>                282546 are dependent in the DAG
>                155776 are aritificially in conflict with void *
> 
> to
> 
> Alias oracle query stats:
>   refs_may_alias_p: 4421611 disambiguations, 4781828 queries
>   ref_maybe_used_by_call_p: 6790 disambiguations, 4448013 queries
>   call_may_clobber_ref_p: 883 disambiguations, 883 queries
>   nonoverlapping_component_refs_p: 0 disambiguations, 8964 queries
>   nonoverlapping_component_refs_since_match_p: 66 disambiguations, 18470 queries
>   aliasing_component_refs_p: 918 disambiguations, 30371 queries
>   TBAA oracle: 1924492 disambiguations 3849967 queries
>                774336 are in alias set 0
>                714095 queries asked about the same object
>                0 queries asked about the same alias set
>                0 access volatile
>                281268 are dependent in the DAG
>                155776 are aritificially in conflict with void *
> 
> PTA query stats:
>   pt_solution_includes: 906632 disambiguations, 1214744 queries
>   pt_solutions_intersect: 121330 disambiguations, 553172 queries
> 
> So twice as many nonoverlapping_component_refs_since_match_p disambiguations,
> half of querries.
> 
> We can miss some of disambiguations where addresses are same but types
> are different, but I think those are not useful - this is the case where
> memory type was dynamically changed.  If we walk with TBAA enabled and
> see the prevoius use, we got kind of lost anyway and propagating even
> older values seems to have no use.
> 
> Note that i tried to implement ranges_must_overlap_p predicate which could
> save us from more tests but got lost in polyints and I think it is not worth
> the effort since these cases are quite borderline.
> 
> Similar test would make sense in aliasing_component_refs_p but I think
> it may make more sense to reorder the tests there. Right now we do:
> 
>   get_ref_base_and_extent (match2, &offadj, &sztmp, &msztmp, &reverse);
>   offset2 -= offadj;
>   get_ref_base_and_extent (match1, &offadj, &sztmp, &msztmp, &reverse);
>   offset1 -= offadj;
>   if (!ranges_maybe_overlap_p (offset1, max_size1, offset2, max_size2))
> 
> First I think that one get_ref_base_and_extent is always redundant since either
> match1 or match2 is base so we could pass it down.
> 
> However it seems to me that perhaps doing
> nonoverlapping_component_refs_since_match_p would be cheaper and one can do the
> range check only after this one returns -1 saving quite many
> get_ref_base_and_extent calls.

Yeah, that sounds worthwhile (this function is the worst offender
compile-time wise)

> Bootstrapped/regtested x86_64-linux, OK?
> 
> Honza
> 
> Index: testsuite/gcc.dg/tree-ssa/alias-access-path-3.c
> ===================================================================
> --- testsuite/gcc.dg/tree-ssa/alias-access-path-3.c	(nonexistent)
> +++ testsuite/gcc.dg/tree-ssa/alias-access-path-3.c	(working copy)
> @@ -0,0 +1,22 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-fre1" } */
> +struct a {int v1;
> +	  int v2;};
> +struct b {struct a a[0];};
> +
> +int
> +test (struct b *bptr1, struct b *bptr2, int i, int j)
> +{
> +  bptr1->a[i].v1=123;
> +  bptr2->a[j].v2=1;
> +  return bptr1->a[i].v1;
> +}
> +int
> +test2 (struct b *bptr1, struct b *bptr2, int i, int j)
> +{
> +  bptr1->a[i].v1=123;
> +  bptr2->a[j].v1=1;
> +  return bptr1->a[i].v1;
> +}
> +/* test should be optimized, while test2 should not.  */
> +/* { dg-final { scan-tree-dump-times "return 123" 1 "fre1"} } */
> Index: testsuite/gcc.dg/tree-ssa/alias-access-path-8.c
> ===================================================================
> --- testsuite/gcc.dg/tree-ssa/alias-access-path-8.c	(nonexistent)
> +++ testsuite/gcc.dg/tree-ssa/alias-access-path-8.c	(working copy)
> @@ -0,0 +1,21 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-fre3" } */
> +struct a {
> +  int val;
> +};
> +struct b {
> +  struct a a[10],a2[10];
> +};
> +struct c {
> +  struct b b[10];
> +} *cptr,*cptr2;
> +
> +
> +int
> +test (int i, int j, int k, int l)
> +{
> +  cptr->b[i].a[j].val=123;
> +  cptr2->b[k].a2[l].val=2;
> +  return cptr->b[i].a[j].val;
> +}
> +/* { dg-final { scan-tree-dump-times "return 123" 1 "fre3"} } */

Why does this only happen in fre3?!

Otherwise OK.

Thanks,
Richard.

> Index: tree-ssa-alias.c
> ===================================================================
> --- tree-ssa-alias.c	(revision 272927)
> +++ tree-ssa-alias.c	(working copy)
> @@ -1452,8 +1452,10 @@ nonoverlapping_component_refs_p (const_t
>  static bool
>  decl_refs_may_alias_p (tree ref1, tree base1,
>  		       poly_int64 offset1, poly_int64 max_size1,
> +		       poly_int64 size1,
>  		       tree ref2, tree base2,
> -		       poly_int64 offset2, poly_int64 max_size2)
> +		       poly_int64 offset2, poly_int64 max_size2,
> +		       poly_int64 size2)
>  {
>    gcc_checking_assert (DECL_P (base1) && DECL_P (base2));
>  
> @@ -1466,6 +1468,10 @@ decl_refs_may_alias_p (tree ref1, tree b
>    if (!ranges_maybe_overlap_p (offset1, max_size1, offset2, max_size2))
>      return false;
>  
> +  /* If there is must alias, there is no use disambiguating further.  */
> +  if (known_eq (size1, max_size1) && known_eq (size2, max_size2))
> +    return true;
> +
>    /* For components with variable position, the above test isn't sufficient,
>       so we disambiguate component references manually.  */
>    if (ref1 && ref2
> @@ -1487,10 +1493,12 @@ decl_refs_may_alias_p (tree ref1, tree b
>  static bool
>  indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
>  			       poly_int64 offset1, poly_int64 max_size1,
> +			       poly_int64 size1,
>  			       alias_set_type ref1_alias_set,
>  			       alias_set_type base1_alias_set,
>  			       tree ref2 ATTRIBUTE_UNUSED, tree base2,
>  			       poly_int64 offset2, poly_int64 max_size2,
> +			       poly_int64 size2,
>  			       alias_set_type ref2_alias_set,
>  			       alias_set_type base2_alias_set, bool tbaa_p)
>  {
> @@ -1598,7 +1606,19 @@ indirect_ref_may_alias_decl_p (tree ref1
>        && (TREE_CODE (TREE_TYPE (base1)) != ARRAY_TYPE
>  	  || (TYPE_SIZE (TREE_TYPE (base1))
>  	      && TREE_CODE (TYPE_SIZE (TREE_TYPE (base1))) == INTEGER_CST)))
> -    return ranges_maybe_overlap_p (doffset1, max_size1, doffset2, max_size2);
> +    {
> +      if (!ranges_maybe_overlap_p (doffset1, max_size1, doffset2, max_size2))
> +	return false;
> +      if (!ref1 || !ref2
> +	  /* If there is must alias, there is no use disambiguating further.  */
> +	  || (known_eq (size1, max_size1) && known_eq (size2, max_size2)))
> +	return true;
> +      int res = nonoverlapping_component_refs_since_match_p (base1, ref1,
> +							     base2, ref2);
> +      if (res == -1)
> +	return !nonoverlapping_component_refs_p (ref1, ref2);
> +      return !res;
> +    }
>  
>    /* Do access-path based disambiguation.  */
>    if (ref1 && ref2
> @@ -1623,10 +1643,12 @@ indirect_ref_may_alias_decl_p (tree ref1
>  static bool
>  indirect_refs_may_alias_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
>  			   poly_int64 offset1, poly_int64 max_size1,
> +			   poly_int64 size1,
>  			   alias_set_type ref1_alias_set,
>  			   alias_set_type base1_alias_set,
>  			   tree ref2 ATTRIBUTE_UNUSED, tree base2,
>  			   poly_int64 offset2, poly_int64 max_size2,
> +			   poly_int64 size2,
>  			   alias_set_type ref2_alias_set,
>  			   alias_set_type base2_alias_set, bool tbaa_p)
>  {
> @@ -1671,6 +1693,9 @@ indirect_refs_may_alias_p (tree ref1 ATT
>        if (!ranges_maybe_overlap_p (offset1 + moff1, max_size1,
>  				   offset2 + moff2, max_size2))
>  	return false;
> +      /* If there is must alias, there is no use disambiguating further.  */
> +      if (known_eq (size1, max_size1) && known_eq (size2, max_size2))
> +	return true;
>        if (ref1 && ref2)
>  	{
>  	  int res = nonoverlapping_component_refs_since_match_p (NULL, ref1,
> @@ -1717,7 +1742,18 @@ indirect_refs_may_alias_p (tree ref1 ATT
>           can overlap by an exact multiple of their element size.
>           See gcc.dg/torture/alias-2.c.  */
>        && TREE_CODE (TREE_TYPE (ptrtype1)) != ARRAY_TYPE)
> -    return ranges_maybe_overlap_p (offset1, max_size1, offset2, max_size2);
> +    {
> +      if (!ranges_maybe_overlap_p (offset1, max_size1, offset2, max_size2))
> +	return false;
> +      if (!ref1 || !ref2
> +	  || (known_eq (size1, max_size1) && known_eq (size2, max_size2)))
> +	return true;
> +      int res = nonoverlapping_component_refs_since_match_p (base1, ref1,
> +							     base2, ref2);
> +      if (res == -1)
> +	return !nonoverlapping_component_refs_p (ref1, ref2);
> +      return !res;
> +    }
>  
>    /* Do access-path based disambiguation.  */
>    if (ref1 && ref2
> @@ -1802,7 +1838,9 @@ refs_may_alias_p_2 (ao_ref *ref1, ao_ref
>    var2_p = DECL_P (base2);
>    if (var1_p && var2_p)
>      return decl_refs_may_alias_p (ref1->ref, base1, offset1, max_size1,
> -				  ref2->ref, base2, offset2, max_size2);
> +				  ref1->size,
> +				  ref2->ref, base2, offset2, max_size2,
> +				  ref2->size);
>  
>    /* Handle restrict based accesses.
>       ???  ao_ref_base strips inner MEM_REF [&decl], recover from that
> @@ -1870,21 +1908,21 @@ refs_may_alias_p_2 (ao_ref *ref1, ao_ref
>    /* Dispatch to the pointer-vs-decl or pointer-vs-pointer disambiguators.  */
>    if (var1_p && ind2_p)
>      return indirect_ref_may_alias_decl_p (ref2->ref, base2,
> -					  offset2, max_size2,
> +					  offset2, max_size2, ref2->size,
>  					  ao_ref_alias_set (ref2),
>  					  ao_ref_base_alias_set (ref2),
>  					  ref1->ref, base1,
> -					  offset1, max_size1,
> +					  offset1, max_size1, ref1->size,
>  					  ao_ref_alias_set (ref1),
>  					  ao_ref_base_alias_set (ref1),
>  					  tbaa_p);
>    else if (ind1_p && ind2_p)
>      return indirect_refs_may_alias_p (ref1->ref, base1,
> -				      offset1, max_size1,
> +				      offset1, max_size1, ref1->size,
>  				      ao_ref_alias_set (ref1),
>  				      ao_ref_base_alias_set (ref1),
>  				      ref2->ref, base2,
> -				      offset2, max_size2,
> +				      offset2, max_size2, ref2->size,
>  				      ao_ref_alias_set (ref2),
>  				      ao_ref_base_alias_set (ref2),
>  				      tbaa_p);
>
Jan Hubicka July 4, 2019, 12:46 p.m. UTC | #2
> 
> Why does this only happen in fre3?!
After fre1 we have

test (int i, int j, int k, int l)
{ 
  struct c * cptr.0_1;
  struct c * cptr2.1_2;
  int _11;

  <bb 2> :
  cptr.0_1 = cptr;
  cptr.0_1->b[i_5(D)].a[j_6(D)].val = 123;
  cptr2.1_2 = cptr2;
  cptr2.1_2->b[k_8(D)].a2[l_9(D)].val = 2;
  _11 = cptr.0_1->b[i_5(D)].a[j_6(D)].val;
  return _11;
}

I think it is the same issue with AO querries not being valueized
you fixed for the other testcase and later reverted.

Honza
Richard Biener July 5, 2019, 11:09 a.m. UTC | #3
On Thu, Jul 4, 2019 at 2:47 PM Jan Hubicka <hubicka@ucw.cz> wrote:
>
> >
> > Why does this only happen in fre3?!
> After fre1 we have
>
> test (int i, int j, int k, int l)
> {
>   struct c * cptr.0_1;
>   struct c * cptr2.1_2;
>   int _11;
>
>   <bb 2> :
>   cptr.0_1 = cptr;
>   cptr.0_1->b[i_5(D)].a[j_6(D)].val = 123;
>   cptr2.1_2 = cptr2;
>   cptr2.1_2->b[k_8(D)].a2[l_9(D)].val = 2;
>   _11 = cptr.0_1->b[i_5(D)].a[j_6(D)].val;
>   return _11;
> }
>
> I think it is the same issue with AO querries not being valueized
> you fixed for the other testcase and later reverted.

Ah, yes - there's now a quite easy way to fix those.  Mind open a bugreport
so I remember?

Thanks,
Richard.

> Honza
diff mbox series

Patch

Index: testsuite/gcc.dg/tree-ssa/alias-access-path-3.c
===================================================================
--- testsuite/gcc.dg/tree-ssa/alias-access-path-3.c	(nonexistent)
+++ testsuite/gcc.dg/tree-ssa/alias-access-path-3.c	(working copy)
@@ -0,0 +1,22 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-fre1" } */
+struct a {int v1;
+	  int v2;};
+struct b {struct a a[0];};
+
+int
+test (struct b *bptr1, struct b *bptr2, int i, int j)
+{
+  bptr1->a[i].v1=123;
+  bptr2->a[j].v2=1;
+  return bptr1->a[i].v1;
+}
+int
+test2 (struct b *bptr1, struct b *bptr2, int i, int j)
+{
+  bptr1->a[i].v1=123;
+  bptr2->a[j].v1=1;
+  return bptr1->a[i].v1;
+}
+/* test should be optimized, while test2 should not.  */
+/* { dg-final { scan-tree-dump-times "return 123" 1 "fre1"} } */
Index: testsuite/gcc.dg/tree-ssa/alias-access-path-8.c
===================================================================
--- testsuite/gcc.dg/tree-ssa/alias-access-path-8.c	(nonexistent)
+++ testsuite/gcc.dg/tree-ssa/alias-access-path-8.c	(working copy)
@@ -0,0 +1,21 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-fre3" } */
+struct a {
+  int val;
+};
+struct b {
+  struct a a[10],a2[10];
+};
+struct c {
+  struct b b[10];
+} *cptr,*cptr2;
+
+
+int
+test (int i, int j, int k, int l)
+{
+  cptr->b[i].a[j].val=123;
+  cptr2->b[k].a2[l].val=2;
+  return cptr->b[i].a[j].val;
+}
+/* { dg-final { scan-tree-dump-times "return 123" 1 "fre3"} } */
Index: tree-ssa-alias.c
===================================================================
--- tree-ssa-alias.c	(revision 272927)
+++ tree-ssa-alias.c	(working copy)
@@ -1452,8 +1452,10 @@  nonoverlapping_component_refs_p (const_t
 static bool
 decl_refs_may_alias_p (tree ref1, tree base1,
 		       poly_int64 offset1, poly_int64 max_size1,
+		       poly_int64 size1,
 		       tree ref2, tree base2,
-		       poly_int64 offset2, poly_int64 max_size2)
+		       poly_int64 offset2, poly_int64 max_size2,
+		       poly_int64 size2)
 {
   gcc_checking_assert (DECL_P (base1) && DECL_P (base2));
 
@@ -1466,6 +1468,10 @@  decl_refs_may_alias_p (tree ref1, tree b
   if (!ranges_maybe_overlap_p (offset1, max_size1, offset2, max_size2))
     return false;
 
+  /* If there is must alias, there is no use disambiguating further.  */
+  if (known_eq (size1, max_size1) && known_eq (size2, max_size2))
+    return true;
+
   /* For components with variable position, the above test isn't sufficient,
      so we disambiguate component references manually.  */
   if (ref1 && ref2
@@ -1487,10 +1493,12 @@  decl_refs_may_alias_p (tree ref1, tree b
 static bool
 indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
 			       poly_int64 offset1, poly_int64 max_size1,
+			       poly_int64 size1,
 			       alias_set_type ref1_alias_set,
 			       alias_set_type base1_alias_set,
 			       tree ref2 ATTRIBUTE_UNUSED, tree base2,
 			       poly_int64 offset2, poly_int64 max_size2,
+			       poly_int64 size2,
 			       alias_set_type ref2_alias_set,
 			       alias_set_type base2_alias_set, bool tbaa_p)
 {
@@ -1598,7 +1606,19 @@  indirect_ref_may_alias_decl_p (tree ref1
       && (TREE_CODE (TREE_TYPE (base1)) != ARRAY_TYPE
 	  || (TYPE_SIZE (TREE_TYPE (base1))
 	      && TREE_CODE (TYPE_SIZE (TREE_TYPE (base1))) == INTEGER_CST)))
-    return ranges_maybe_overlap_p (doffset1, max_size1, doffset2, max_size2);
+    {
+      if (!ranges_maybe_overlap_p (doffset1, max_size1, doffset2, max_size2))
+	return false;
+      if (!ref1 || !ref2
+	  /* If there is must alias, there is no use disambiguating further.  */
+	  || (known_eq (size1, max_size1) && known_eq (size2, max_size2)))
+	return true;
+      int res = nonoverlapping_component_refs_since_match_p (base1, ref1,
+							     base2, ref2);
+      if (res == -1)
+	return !nonoverlapping_component_refs_p (ref1, ref2);
+      return !res;
+    }
 
   /* Do access-path based disambiguation.  */
   if (ref1 && ref2
@@ -1623,10 +1643,12 @@  indirect_ref_may_alias_decl_p (tree ref1
 static bool
 indirect_refs_may_alias_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
 			   poly_int64 offset1, poly_int64 max_size1,
+			   poly_int64 size1,
 			   alias_set_type ref1_alias_set,
 			   alias_set_type base1_alias_set,
 			   tree ref2 ATTRIBUTE_UNUSED, tree base2,
 			   poly_int64 offset2, poly_int64 max_size2,
+			   poly_int64 size2,
 			   alias_set_type ref2_alias_set,
 			   alias_set_type base2_alias_set, bool tbaa_p)
 {
@@ -1671,6 +1693,9 @@  indirect_refs_may_alias_p (tree ref1 ATT
       if (!ranges_maybe_overlap_p (offset1 + moff1, max_size1,
 				   offset2 + moff2, max_size2))
 	return false;
+      /* If there is must alias, there is no use disambiguating further.  */
+      if (known_eq (size1, max_size1) && known_eq (size2, max_size2))
+	return true;
       if (ref1 && ref2)
 	{
 	  int res = nonoverlapping_component_refs_since_match_p (NULL, ref1,
@@ -1717,7 +1742,18 @@  indirect_refs_may_alias_p (tree ref1 ATT
          can overlap by an exact multiple of their element size.
          See gcc.dg/torture/alias-2.c.  */
       && TREE_CODE (TREE_TYPE (ptrtype1)) != ARRAY_TYPE)
-    return ranges_maybe_overlap_p (offset1, max_size1, offset2, max_size2);
+    {
+      if (!ranges_maybe_overlap_p (offset1, max_size1, offset2, max_size2))
+	return false;
+      if (!ref1 || !ref2
+	  || (known_eq (size1, max_size1) && known_eq (size2, max_size2)))
+	return true;
+      int res = nonoverlapping_component_refs_since_match_p (base1, ref1,
+							     base2, ref2);
+      if (res == -1)
+	return !nonoverlapping_component_refs_p (ref1, ref2);
+      return !res;
+    }
 
   /* Do access-path based disambiguation.  */
   if (ref1 && ref2
@@ -1802,7 +1838,9 @@  refs_may_alias_p_2 (ao_ref *ref1, ao_ref
   var2_p = DECL_P (base2);
   if (var1_p && var2_p)
     return decl_refs_may_alias_p (ref1->ref, base1, offset1, max_size1,
-				  ref2->ref, base2, offset2, max_size2);
+				  ref1->size,
+				  ref2->ref, base2, offset2, max_size2,
+				  ref2->size);
 
   /* Handle restrict based accesses.
      ???  ao_ref_base strips inner MEM_REF [&decl], recover from that
@@ -1870,21 +1908,21 @@  refs_may_alias_p_2 (ao_ref *ref1, ao_ref
   /* Dispatch to the pointer-vs-decl or pointer-vs-pointer disambiguators.  */
   if (var1_p && ind2_p)
     return indirect_ref_may_alias_decl_p (ref2->ref, base2,
-					  offset2, max_size2,
+					  offset2, max_size2, ref2->size,
 					  ao_ref_alias_set (ref2),
 					  ao_ref_base_alias_set (ref2),
 					  ref1->ref, base1,
-					  offset1, max_size1,
+					  offset1, max_size1, ref1->size,
 					  ao_ref_alias_set (ref1),
 					  ao_ref_base_alias_set (ref1),
 					  tbaa_p);
   else if (ind1_p && ind2_p)
     return indirect_refs_may_alias_p (ref1->ref, base1,
-				      offset1, max_size1,
+				      offset1, max_size1, ref1->size,
 				      ao_ref_alias_set (ref1),
 				      ao_ref_base_alias_set (ref1),
 				      ref2->ref, base2,
-				      offset2, max_size2,
+				      offset2, max_size2, ref2->size,
 				      ao_ref_alias_set (ref2),
 				      ao_ref_base_alias_set (ref2),
 				      tbaa_p);