https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120817

--- Comment #15 from Tamar Christina <tnfchris at gcc dot gnu.org> ---
(In reply to Richard Biener from comment #13)
> (In reply to Tamar Christina from comment #12)
> > Looks like the problem is that during ao_ref_init_from_ptr_and_range when
> > initializing vectp_target.14_54 = &targetD.4595 + _55;
> > 
> > we don't enter the block splitting apart POINTER_PLUS_EXPR.
> > 
> > So it ends up creating a ref with the base being MEM_REF <&targetD.4595 +
> > _55>
> > 
> > later on when checking of &targetD.4595 and MEM_REF <&targetD.4595 + _55>
> > could alias in refs_may_alias_p it doesn't think these two can alias, even
> > though
> > 
> >   # _38 = PHI <niters_vector_mult_vf.6_33(6), 0(3)>
> >   # RANGE [irange] sizetype [0, 0][32, 4294967264] MASK 0xffffffe0 VALUE 0x0
> >   _55 = (sizetype) _38;
> > 
> > 
> > so clearly they can alias. Need to look into how tree-ssa-alias normally
> > handles PHI offsets.
> 
> The problem is that _55 is negative.  But the alias oracle does not consider
> negative offsets but only the 8B positive offset which makes the access
> clearly out of bounds of &targetD.4595.
> 
> Do not use POINTER_PLUS_EXPR to "advance" a pointer to sth outside of
> [&object, &object + sizeof(object)], since such a pointer is UB.

Why do you think _55 is negative? It's 0 or 32. It's the amount of bytes
processed in the earlier loops. So can't be negative.

The problem to me seems that we build a MEM_REF over the POINTER_PLUS_EXPR as a
whole when the offset
isn't a constant.

This fixes it for me

diff --git a/gcc/tree-ssa-alias.cc b/gcc/tree-ssa-alias.cc
index 9dd1780867d..b3cd4fa65a5 100644
--- a/gcc/tree-ssa-alias.cc
+++ b/gcc/tree-ssa-alias.cc
@@ -890,11 +890,11 @@ ao_ref_init_from_ptr_and_range (ao_ref *ref, tree ptr,
          && gimple_assign_rhs_code (stmt) == ADDR_EXPR)
        ptr = gimple_assign_rhs1 (stmt);
       else if (is_gimple_assign (stmt)
-              && gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR
-              && ptrdiff_tree_p (gimple_assign_rhs2 (stmt), &extra_offset))
+              && gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
        {
          ptr = gimple_assign_rhs1 (stmt);
-         extra_offset *= BITS_PER_UNIT;
+         if (ptrdiff_tree_p (gimple_assign_rhs2 (stmt), &extra_offset))
+           extra_offset *= BITS_PER_UNIT;
        }
     }

because it allows alias analysis to compare &object and &object + _55
correctly.
With the bolded MEM_REF it compares &object and MEM<&object +_55> and so
doesn't check the components of the address.

Reply via email to