On Mon, Oct 6, 2025 at 2:15 AM Andrew Pinski
<[email protected]> wrote:
>
> When I tried to fix this before I didn't realize there was already a pattern 
> for
> `-(a ptrdiff b) -> (b ptrdiff a)`, I had added a complex pattern to match 
> `ptr0 - (ptr0 - ptr1)`.
> But with there being a pattern for `-(a ptrdiff b)`, we just need to extend 
> the pattern
> to support a nop conversion inbetween the negative and the ptrdiff.
> Also the check for TYPE_OVERFLOW_UNDEFINED was wrong, in the case of `-(a - 
> b) -> (b - a)`, the check
> is !TYPE_OVERFLOW_SANITIZED so this pattern should use the same check.
>
>         PR tree-optimization/121921
>
> gcc/ChangeLog:
>
>         * match.pd (`-(a ptrdiff b)`): Extend for a nop_convert
>         between the neg and ptrdiff.
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.dg/pr121921-1.c: New test.
>
> Signed-off-by: Andrew Pinski <[email protected]>
> ---
>  gcc/match.pd                      |  6 +++---
>  gcc/testsuite/gcc.dg/pr121921-1.c | 15 +++++++++++++++
>  2 files changed, 18 insertions(+), 3 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/pr121921-1.c
>
> diff --git a/gcc/match.pd b/gcc/match.pd
> index 6f896aa7961..a2353be099f 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -2133,9 +2133,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>           && !HONOR_SIGNED_ZEROS (type)))
>    (minus @1 @0)))
>  (simplify
> - (negate (pointer_diff @0 @1))
> - (if (TYPE_OVERFLOW_UNDEFINED (type))
> -  (pointer_diff @1 @0)))
> + (negate (nop_convert? (pointer_diff@2 @0 @1)))
> + (if (ANY_INTEGRAL_TYPE_P (type) && !TYPE_OVERFLOW_SANITIZED (type))
> +  (convert (pointer_diff:ssizetype @1 @0))))

The patch is OK, but is this technically OK when @1 is from a
named address-space with smaller pointers?  The gimple
verifier requires the same precision on the difference and the
pointer, so I guess a more defensive variant would be

  (with { tree ptrdifft = signed_type_for (TREE_TYPE (@0)); }
   (convert  (pointer_diff:ptrdifft @1 @0))))

?  I realize there's at least one other place using pointer_diff:ssizetype
but that guards against this with TYPE_PRECISION (TREE_TYPE (@0)) ==
TYPE_PRECISION (sizetype)

Richard.

>
>  /* A - B -> A + (-B) if B is easily negatable.  */
>  (simplify
> diff --git a/gcc/testsuite/gcc.dg/pr121921-1.c 
> b/gcc/testsuite/gcc.dg/pr121921-1.c
> new file mode 100644
> index 00000000000..828472abbd5
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/pr121921-1.c
> @@ -0,0 +1,15 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O -fdump-tree-cddce1" } */
> +
> +/* PR tree-optimization/121921 */
> +
> +int *
> +fx (int *b, int *e)
> +{
> +  __SIZE_TYPE__ p = b - e;
> +  /* The first forwprop pass should optimize this to return e;  */
> +  return b - p;
> +}
> +
> +/* { dg-final { scan-tree-dump "return e" "cddce1" } } */
> +
> --
> 2.43.0
>

Reply via email to