diff options
author | Andrew Pinski <apinski@marvell.com> | 2021-09-06 00:52:18 +0000 |
---|---|---|
committer | Andrew Pinski <apinski@marvell.com> | 2021-09-06 07:45:06 +0000 |
commit | 564efbf40077c25623cdd6ce2f911c56b5b08f6c (patch) | |
tree | 8bf0eedcb74c2c09f50af6cac6a39fff122e7e42 | |
parent | 637dfcf43cfd2f01f4757abfd84d376d4011b0b2 (diff) | |
download | gcc-564efbf40077c25623cdd6ce2f911c56b5b08f6c.zip gcc-564efbf40077c25623cdd6ce2f911c56b5b08f6c.tar.gz gcc-564efbf40077c25623cdd6ce2f911c56b5b08f6c.tar.bz2 |
Fix PR tree-optimization/63184: add simplification of (& + A) != (& + B)
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:
PR tree-optimization/63184
* 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:
PR tree-optimization/63184
* c-c++-common/pr19807-2.c: Enable for all targets and remove the xfail.
* c-c++-common/pr19807-3.c: Likewise.
-rw-r--r-- | gcc/match.pd | 15 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/pr19807-2.c | 5 | ||||
-rw-r--r-- | 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 f920bc4..cc7809d 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 d2c0101..529b9c9 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 bb7f982..31c88f3 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" } } */ |