tree-optimization/107699 - missed &data._M_elems + _1 != &data._M_elems folding

Message ID nycvar.YFH.7.77.849.2212081053400.17722@jbgna.fhfr.qr
State Committed
Commit 892e8c520be37d0a0f14e2ae375103c5303ed549
Headers
Series tree-optimization/107699 - missed &data._M_elems + _1 != &data._M_elems folding |

Commit Message

Richard Biener Dec. 8, 2022, 10:54 a.m. UTC
  The following addresses a missed folding noticed in PR107699 that can
be fixed amending the existing &x + a != &x + b pattern to also handle
the case of only one side having a pointer plus.  I'm moving the
patterns next to related simpifications showing there'd be an existing
pattern matching this if it were not gated with an explicit single_use
constraint.  Note the new pattern also handles &x.a + a != &x.b, but
this hints at some unification / generalization opportunities here.

Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.

	PR tree-optimization/107699
	* match.pd (&a !=/== &a.b + c -> (&a - &a.b) !=/== c): New
	pattern variant.

	* gcc.dg/tree-ssa/pr107699.c: New testcase.
---
 gcc/match.pd                             | 21 +++++++++++++--------
 gcc/testsuite/gcc.dg/tree-ssa/pr107699.c | 15 +++++++++++++++
 2 files changed, 28 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr107699.c
  

Patch

diff --git a/gcc/match.pd b/gcc/match.pd
index f48cbd9b73b..127cef9a610 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -2260,6 +2260,19 @@  DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
        && (CONSTANT_CLASS_P (@1) || (single_use (@2) && single_use (@3))))
    (op @1 { build_zero_cst (TREE_TYPE (@1)); }))))
 
+/* (&a + b) !=/== (&a[1] + c) -> (&a[0] - &a[1]) + b !=/== c */
+(for neeq (ne eq)
+ (simplify
+  (neeq:c ADDR_EXPR@0 (pointer_plus ADDR_EXPR@2 @3))
+   (with { poly_int64 diff; tree inner_type = TREE_TYPE (@3);}
+    (if (ptr_difference_const (@0, @2, &diff))
+     (neeq { build_int_cst_type (inner_type, diff); } @3))))
+ (simplify
+  (neeq (pointer_plus ADDR_EXPR@0 @1) (pointer_plus ADDR_EXPR@2 @3))
+   (with { poly_int64 diff; tree inner_type = TREE_TYPE (@1);}
+    (if (ptr_difference_const (@0, @2, &diff))
+     (neeq (plus { build_int_cst_type (inner_type, diff); } @1) @3)))))
+
 /* X - Y < X is the same as Y > 0 when there is no overflow.
    For equality, this is also true with wrapping overflow.  */
 (for op (simple_comparison)
@@ -2439,14 +2452,6 @@  DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
    (if (ptr_difference_const (@0, @2, &diff))
     (plus { build_int_cst_type (type, diff); } (convert (minus @1 @3))))))
 
-/* (&a+b) !=/== (&a[1] + c) ->  sizeof(a[0]) + b !=/== c */
-(for neeq (ne eq)
- (simplify
-  (neeq (pointer_plus ADDR_EXPR@0 @1) (pointer_plus ADDR_EXPR@2 @3))
-   (with { poly_int64 diff; tree inner_type = TREE_TYPE (@1);}
-    (if (ptr_difference_const (@0, @2, &diff))
-     (neeq (plus { build_int_cst_type (inner_type, diff); } @1) @3)))))
-
 /* Canonicalize (T *)(ptr - ptr-cst) to &MEM[ptr + -ptr-cst].  */
 (simplify
  (convert (pointer_diff @0 INTEGER_CST@1))
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr107699.c b/gcc/testsuite/gcc.dg/tree-ssa/pr107699.c
new file mode 100644
index 00000000000..4bf864dfd72
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr107699.c
@@ -0,0 +1,15 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-forwprop1" } */
+
+struct { int data[16]; } x;
+
+int foo (int n)
+{
+  int *p = x.data + n;
+  /* Should simplify this to n * 4 != 0.  */
+  if ((void *)&x != (void *)p)
+    return 1;
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump " != 0" "forwprop1" } } */