On Thu, Aug 28, 2025 at 9:18 AM Andrew Pinski
<andrew.pin...@oss.qualcomm.com> wrote:
>
> On Thu, Aug 28, 2025 at 4:25 AM Richard Biener
> <richard.guent...@gmail.com> wrote:
> >
> > On Wed, Aug 27, 2025 at 6:12 PM Andrew Pinski
> > <andrew.pin...@oss.qualcomm.com> wrote:
> > >
> > > Currently the code rejects:
> > > ```
> > > tmp = *a;
> > > *b = tmp;
> > > ```
> > > (unless *a == *b). This can be improved such that if a and b are known to
> > > share the same base, then only reject it if they overlap; that is the
> > > difference of the offsets (from the base) is maybe less than the size.
> > >
> > > This fixes the testcase in comment #0 of PR 107051.
> > >
> > >         PR tree-optimization/107051
> > >
> > > gcc/ChangeLog:
> > >
> > >         * tree-ssa-forwprop.cc (optimize_agr_copyprop_1): Allow for
> > >         memory sharing the same base if they known not to overlap over
> > >         the size.
> > >
> > > gcc/testsuite/ChangeLog:
> > >
> > >         * gcc.dg/tree-ssa/copy-prop-aggregate-union-1.c: New test.
> > >
> > > Signed-off-by: Andrew Pinski <andrew.pin...@oss.qualcomm.com>
> > > ---
> > >  .../tree-ssa/copy-prop-aggregate-union-1.c    | 24 +++++++++++++++++
> > >  gcc/tree-ssa-forwprop.cc                      | 27 ++++++++++++++++++-
> > >  2 files changed, 50 insertions(+), 1 deletion(-)
> > >  create mode 100644 
> > > gcc/testsuite/gcc.dg/tree-ssa/copy-prop-aggregate-union-1.c
> > >
> > > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/copy-prop-aggregate-union-1.c 
> > > b/gcc/testsuite/gcc.dg/tree-ssa/copy-prop-aggregate-union-1.c
> > > new file mode 100644
> > > index 00000000000..206f6e1be55
> > > --- /dev/null
> > > +++ b/gcc/testsuite/gcc.dg/tree-ssa/copy-prop-aggregate-union-1.c
> > > @@ -0,0 +1,24 @@
> > > +/* { dg-do compile } */
> > > +/* { dg-options "-O1 -fdump-tree-forwprop1-details" } */
> > > +/* PR tree-optimization/107051 */
> > > +
> > > +
> > > +union U2 {
> > > +   unsigned  f0;
> > > +   char * f1;
> > > +};
> > > +
> > > +/* Since g_284[0] and g_284[1] are known not overlap,
> > > +   copy prop can happen.  */
> > > +union U2 g_284[2] = {{0UL},{0xC2488F72L}};
> > > +
> > > +int e;
> > > +void func_1() {
> > > +       union U2 c = {7};
> > > +       int *d[2];
> > > +       for (; e;)
> > > +               *d[1] = 0;
> > > +       g_284[0] = c = g_284[1];
> > > +}
> > > +
> > > +/* { dg-final { scan-tree-dump-times "after previous" 1 "forwprop1" } } 
> > > */
> > > diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc
> > > index e0f25a12f34..82344f4020d 100644
> > > --- a/gcc/tree-ssa-forwprop.cc
> > > +++ b/gcc/tree-ssa-forwprop.cc
> > > @@ -1455,7 +1455,32 @@ optimize_agr_copyprop_1 (gimple *stmt, gimple 
> > > *use_stmt,
> > >       */
> > >    if (!operand_equal_p (dest2, src, 0)
> > >        && !DECL_P (dest2) && !DECL_P (src))
> > > -    return false;
> > > +    {
> > > +      /* If *a and *b have the same base see if
> > > +         the offset between the two is greater than
> > > +        or equal to the size of the type. */
> > > +      poly_int64 offset1, offset2;
> > > +      tree len = TYPE_SIZE_UNIT (TREE_TYPE (src));
> > > +      if (len == NULL_TREE
> > > +         || !tree_fits_poly_int64_p (len))
> > > +       return false;
> > > +      tree base1 = get_addr_base_and_unit_offset (dest2, &offset1);
> > > +      if (!base1)
> > > +       return false;
> > > +      tree base2 = get_addr_base_and_unit_offset (src, &offset2);
> > > +      if (!base2)
> > > +       return false;
> > > +      if (!operand_equal_p (base1, base2))
> >
> > I'll note that exact overlap, thus
> >
> >  b = a;
> >  tmp = *a;
> >  *b = tmp;
> >
> > is fine.  VN uses alignment as additional non-partial overlap test,
> > so when !operand_equal_p here you could see whether
> > get_object_alignment () for both is > size (mostly interesting for
> > small sizes, of course).  With -fstrict-aliasing if both have the
> > same type then partial overlaps also cannot happen (but this
> > condition is a bit difficult to apply I think).
>
> Let me look into this further; I was trying to be as conservative as possible.
>
> >
> > > +       return false;
> > > +      poly_int64 size = tree_to_poly_int64 (len);
> > > +      /* Make sure [offset1, offset1 + len - 1] does
> > > +        not overlap with [offset2, offset2 + len - 1]
> > > +        or overlaps fully. */
> >
> > There's ranges_may_overlap_p you might want to use here.
>
> There is ranges_overlap_p but that is for HWI while here we have
> poly_int64 (which is int64 for most targets; aarch64 and riscv are the
> exceptions at this stage). I could make a poly_int version though.

Oh I see the function suggested now: ranges_maybe_overlap_p. Will
change that over to use that.

Thanks,
Andrew

>
> Thanks,
> Andrew
>
> >
> > Richard.
> >
> > > +      if (!known_eq (offset2, offset1)
> > > +         && !known_ge (offset2 - offset1, size)
> > > +         && !known_ge (offset1 - offset2, size))
> > > +        return false;
> > > +    }
> > >
> > >    if (dump_file && (dump_flags & TDF_DETAILS))
> > >      {
> > > --
> > > 2.43.0
> > >

Reply via email to