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 > > >