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.
Bootstrapped and tested on x86_64-linux-gnu.
Changes since v1:
* v2: Use the old type of the pointer_diff rather than ssizetype.
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 <andrew.pinski@oss.qualcomm.com>
&& !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))
+ (with { tree ptrdifftype = TREE_TYPE (@2); }
+ (convert (pointer_diff:ptrdifftype @1 @0)))))
/* A - B -> A + (-B) if B is easily negatable. */
(simplify
--- /dev/null
+/* { 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" } } */
+