diff options
author | Richard Biener <rguenther@suse.de> | 2018-08-01 12:03:29 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2018-08-01 12:03:29 +0000 |
commit | e4837aa9fbb91803585f038de67b0d62d256b654 (patch) | |
tree | deef5cb331e8d14f935a347904cbb33a90b96455 /gcc | |
parent | 42c4ccce729ae19954160339aa2f20e9663408a5 (diff) | |
download | gcc-e4837aa9fbb91803585f038de67b0d62d256b654.zip gcc-e4837aa9fbb91803585f038de67b0d62d256b654.tar.gz gcc-e4837aa9fbb91803585f038de67b0d62d256b654.tar.bz2 |
tree-ssa-sccvn.c (visit_phi): Compare invariant addresses as base and offset.
2018-08-01 Richard Biener <rguenther@suse.de>
* tree-ssa-sccvn.c (visit_phi): Compare invariant addresses
as base and offset.
* gcc.dg/tree-ssa/ssa-fre-68.c: New testcase.
From-SVN: r263206
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-68.c | 28 | ||||
-rw-r--r-- | gcc/tree-ssa-sccvn.c | 19 |
4 files changed, 56 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 477b245..0d10e95 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2018-08-01 Richard Biener <rguenther@suse.de> + + * tree-ssa-sccvn.c (visit_phi): Compare invariant addresses + as base and offset. + 2018-08-01 Martin Liska <mliska@suse.cz> * value-prof.c (gimple_divmod_fixed_value_transform): Unify diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0743b95..7fcc05d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2018-08-01 Richard Biener <rguenther@suse.de> + + * gcc.dg/tree-ssa/ssa-fre-68.c: New testcase. + 2018-08-01 Uros Bizjak <ubizjak@gmail.com> * gcc.dg/plugin/poly-int-07_plugin.c (dg-options): Use -O0. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-68.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-68.c new file mode 100644 index 0000000..d9f07bd --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-68.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-fre1" } */ + +struct S { char a[3]; char b[5]; } s = { "abc", "defg" }; + +__SIZE_TYPE__ +foo (struct S s, int a, int b) +{ + char *p = (char *) &s.a[0]; + if (a) + p = (char *) &s.a; + else if (b) + p = (char *) &s; + return __builtin_strlen (p); +} + +__SIZE_TYPE__ +bar (int a, int b) +{ + char *p = (char *) &s.a[0]; + if (a) + p = (char *) &s.a; + else if (b) + p = (char *) &s; + return __builtin_strlen (p); +} + +/* { dg-final { scan-tree-dump-times "strlen \\\(&s" 2 "fre1" } } */ diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index 833291a..43f3313 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -3941,6 +3941,8 @@ static bool visit_phi (gimple *phi) { tree result, sameval = VN_TOP, seen_undef = NULL_TREE; + tree sameval_base = NULL_TREE; + poly_int64 soff, doff; unsigned n_executable = 0; bool allsame = true; edge_iterator ei; @@ -3971,6 +3973,23 @@ visit_phi (gimple *phi) sameval = def; else if (!expressions_equal_p (def, sameval)) { + /* We know we're arriving only with invariant addresses here, + try harder comparing them. We can do some caching here + which we cannot do in expressions_equal_p. */ + if (TREE_CODE (def) == ADDR_EXPR + && TREE_CODE (sameval) == ADDR_EXPR + && sameval_base != (void *)-1) + { + if (!sameval_base) + sameval_base = get_addr_base_and_unit_offset + (TREE_OPERAND (sameval, 0), &soff); + if (!sameval_base) + sameval_base = (tree)(void *)-1; + else if ((get_addr_base_and_unit_offset + (TREE_OPERAND (def, 0), &doff) == sameval_base) + && known_eq (soff, doff)) + continue; + } allsame = false; break; } |