From: Andrew Pinski <apin...@marvell.com> These two testcases have been failing since GCC 5 but things have improved such that adding a simplification to match.pd for this case is easier than before. In the end we have the following IR: .... _5 = &a[1] + _4; _7 = &a + _13; if (_5 != _7)
So we can fold the _5 != _7 into: (&a[1] - &a) + _4 != _13 The subtraction is folded into constant by ptr_difference_const. In this case, the full expression gets folded into a constant and we are able to remove the if statement. OK? Bootstrapped and tested on aarch64-linux-gnu with no regressions. gcc/ChangeLog: * match.pd: Add simplification of pointer_diff of two pointer_plus with addr_expr in the first operand of each pointer_plus. Add simplificatoin of ne/eq of two pointer_plus with addr_expr in the first operand of each pointer_plus. gcc/testsuite/ChangeLog: * c-c++-common/pr19807-2.c: Enable for all targets and remove the xfail. * c-c++-common/pr19807-3.c: Likewise. --- gcc/match.pd | 15 +++++++++++++++ gcc/testsuite/c-c++-common/pr19807-2.c | 5 ++--- gcc/testsuite/c-c++-common/pr19807-3.c | 5 ++--- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/gcc/match.pd b/gcc/match.pd index f920bc4b7c1..cc7809dfe0f 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -2063,6 +2063,21 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (if (ptr_difference_const (@0, @1, &diff)) { build_int_cst_type (type, diff); })))) +/* (&a+b) - (&a[1] + c) -> sizeof(a[0]) + (b - c) */ +(simplify + (pointer_diff (pointer_plus ADDR_EXPR@0 @1) (pointer_plus ADDR_EXPR@2 @3)) + (with { poly_int64 diff; } + (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/c-c++-common/pr19807-2.c b/gcc/testsuite/c-c++-common/pr19807-2.c index d2c010140d0..529b9c97322 100644 --- a/gcc/testsuite/c-c++-common/pr19807-2.c +++ b/gcc/testsuite/c-c++-common/pr19807-2.c @@ -1,5 +1,4 @@ -/* Some targets can optimize this on RTL. */ -/* { dg-do link { target { x86_64-*-* i?86-*-* } } } */ +/* { dg-do link } */ /* { dg-options "-O -fdump-tree-optimized" } */ extern void link_error(void); @@ -12,4 +11,4 @@ int main() return 0; } -/* { dg-final { scan-tree-dump-not "link_error" "optimized" { xfail *-*-* } } } */ +/* { dg-final { scan-tree-dump-not "link_error" "optimized" } } */ diff --git a/gcc/testsuite/c-c++-common/pr19807-3.c b/gcc/testsuite/c-c++-common/pr19807-3.c index bb7f9827725..31c88f3b850 100644 --- a/gcc/testsuite/c-c++-common/pr19807-3.c +++ b/gcc/testsuite/c-c++-common/pr19807-3.c @@ -1,5 +1,4 @@ -/* Some targets can optimize this on RTL. */ -/* { dg-do link { target { x86_64-*-* i?86-*-* } } } */ +/* { dg-do link } */ /* { dg-options "-O -fdump-tree-optimized" } */ extern void link_error(void); @@ -12,4 +11,4 @@ int main() return 0; } -/* { dg-final { scan-tree-dump-not "link_error" "optimized" { xfail *-*-* } } } */ +/* { dg-final { scan-tree-dump-not "link_error" "optimized" } } */ -- 2.17.1