aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/match.pd21
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr107699.c15
2 files changed, 28 insertions, 8 deletions
diff --git a/gcc/match.pd b/gcc/match.pd
index f48cbd9..127cef9 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 0000000..4bf864d
--- /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" } } */