On Mon, Oct 6, 2025 at 10:08 PM Andrew Pinski
<[email protected]> wrote:
>
> On Sun, Oct 5, 2025 at 11:20 PM Richard Biener
> <[email protected]> wrote:
> >
> > 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)
>
> Actually since we already have the ptrdifftype, I am just going to use that.
> So the pattern becomes:
> ```
> (simplify
> (negate (nop_convert? (pointer_diff@2 @0 @1)))
> (if (ANY_INTEGRAL_TYPE_P (type) && !TYPE_OVERFLOW_SANITIZED (type))
> (with { tree ptrdifftype = TREE_TYPE (@2); }
> (convert (pointer_diff:ptrdifftype @1 @0)))))
> ```
Ah, of course.
> I actually captured the pointer_diff in the old patch as I was trying
> to figure out what the best choice was for the type was and then saw
> ssizetype being used below (though I had missed the check that you
> mentioned). We check to make sure both @0 and @1 are the same mode in
> tree-cfg and I assume for pointers we always have the same precision
> as the mode's precision too; that is PSI mode if we have say 20bit
> pointers.
> For the other pattern that has :ssizetype, we only check if one of the
> pointers is the same precision as ssizetype and NOT both so using
> ptrdifftype here should be ok too.
>
> I suspect we are not allowing different precision pointers for
> pointer_diff indirectly via the mode check too.
I think the important part is to get the IL clear of ptr_mode vs. Pmode
differences and POINTERS_EXTEND_UNSIGNED (which isn't
address-space specific...), and not have POINTER_DIFF_EXPR as
a way around to only allow int<->ptr type conversions that do not
change the precision in GIMPLE (aka use p - (void *)0 to get an integer p).
Richard.
> Thanks,
> Andrew
>
>
>
> >
> > 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
> > >