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.

        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

Reply via email to