On Sun, Sep 14, 2025 at 8:17 PM Andrew Pinski <andrew.pin...@oss.qualcomm.com> wrote: > > This pattern shows up with some C++ code (std::vector<bool>) where we get: > ``` > _9 = _201 - _36; > _10 = (long unsigned int) _9; > _11 = -_10; > _12 = _201 + _11; > ``` > > In the original code it was `end - (end - begin)` but with inlined functions > so it > is not direct fixable. > > This patch adds a new amtch pattern like what was added in > r0-128019-g77574c353464b3 (and then moved to match with > r5-4705-ga499aac5dfa5d9). > > Bootstrapped and tested on x86_64-linux-gnu.
I wonder, if in general, -(ptr1 - ptr2) can be changed to (ptr2 - ptr1). I think this should be OK? Of course with the unsigned conversion in the way it's (long unsigned int)(ptr2 - ptr2)? Thanks, Richard. > PR tree-optimization/121921 > gcc/ChangeLog: > > * match.pd (`eptr - (eptr - bptr)`): New patterns. > > gcc/testsuite/ChangeLog: > * gcc.dg/pr121921-1.c: New testcase. > > Signed-off-by: Andrew Pinski <andrew.pin...@oss.qualcomm.com> > --- > gcc/match.pd | 24 ++++++++++++++++++++++++ > gcc/testsuite/gcc.dg/pr121921-1.c | 14 ++++++++++++++ > 2 files changed, 38 insertions(+) > create mode 100644 gcc/testsuite/gcc.dg/pr121921-1.c > > diff --git a/gcc/match.pd b/gcc/match.pd > index dbbb7b51275..5dea74aabe2 100644 > --- a/gcc/match.pd > +++ b/gcc/match.pd > @@ -3047,6 +3047,30 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > (if (TYPE_PRECISION (TREE_TYPE (@2)) >= TYPE_PRECISION (TREE_TYPE (@3))) > (convert @1))) > > +/* Likewise but with an additional negate here > + to swap the order of the subtraction. */ > +/* Pattern match > + tem1 = (long) ptr1; > + tem2 = (long) ptr2; > + tem3 = tem1 - tem2; > + tem4 = (unsigned long) tem3; > + tem5 = -tem3; > + tem5 = ptr1 + tem5; > + and produce > + tem5 = ptr2; */ > +(simplify > + (pointer_plus @0 (negate (convert?@2 (minus@3 (convert @0) (convert @1))))) > + /* Conditionally look through a sign-changing conversion. */ > + (if (TYPE_PRECISION (TREE_TYPE (@2)) == TYPE_PRECISION (TREE_TYPE (@3)) > + && ((GIMPLE && useless_type_conversion_p (type, TREE_TYPE (@1))) > + || (GENERIC && type == TREE_TYPE (@1)))) > + @1)) > +/* ptr0 - (ptr0 - ptr1) -> ptr1 */ > +(simplify > + (pointer_plus @0 (negate (convert?@2 (pointer_diff@3 @@0 @1)))) > + (if (TYPE_PRECISION (TREE_TYPE (@2)) >= TYPE_PRECISION (TREE_TYPE (@3))) > + (convert @1))) > + > /* Pattern match > tem = (sizetype) ptr; > tem = tem & algn; > diff --git a/gcc/testsuite/gcc.dg/pr121921-1.c > b/gcc/testsuite/gcc.dg/pr121921-1.c > new file mode 100644 > index 00000000000..b11afc819da > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/pr121921-1.c > @@ -0,0 +1,14 @@ > +/* { 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 >