On Thu, Sep 4, 2025 at 3:08 AM Andrew Pinski
<[email protected]> 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.

OK.

Thanks,
Richard.

> Changes since v1:
> * v2: Use ranges_maybe_overlap_p instead of manually checking the overlap.
>       Allow for the case where the alignment is known to be greater than
>       the size.
>
>         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 <[email protected]>
> ---
>  .../tree-ssa/copy-prop-aggregate-union-1.c    | 24 ++++++++++++
>  gcc/tree-ssa-forwprop.cc                      | 37 ++++++++++++++++++-
>  2 files changed, 60 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 df876f7db0a..59b1878a68f 100644
> --- a/gcc/tree-ssa-forwprop.cc
> +++ b/gcc/tree-ssa-forwprop.cc
> @@ -1455,7 +1455,42 @@ 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);
> +      tree base2 = get_addr_base_and_unit_offset (src, &offset2);
> +      poly_int64 size = tree_to_poly_int64 (len);
> +      /* If we can't figure out the base or the bases are
> +        not equal then fall back to an alignment check.  */
> +      if (!base1
> +         || !base2
> +         || !operand_equal_p (base1, base2))
> +       {
> +         unsigned int align1 = get_object_alignment (src);
> +         unsigned int align2 = get_object_alignment (dest2);
> +         align1 /= BITS_PER_UNIT;
> +         align2 /= BITS_PER_UNIT;
> +         /* If the alignment of either object is less
> +            than the size then there is a possibility
> +            of overlapping.  */
> +         if (maybe_lt (align1, size)
> +             || maybe_lt (align2, size))
> +           return false;
> +       }
> +      /* Make sure [offset1, offset1 + len - 1] does
> +        not overlap with [offset2, offset2 + len - 1],
> +        it is ok if they are at the same location though.  */
> +      else if (ranges_maybe_overlap_p (offset1, size, offset2, size)
> +         && !known_eq (offset2, offset1))
> +       return false;
> +    }
>
>    if (dump_file && (dump_flags & TDF_DETAILS))
>      {
> --
> 2.43.0
>

Reply via email to