From d132c59b10ac8ee35d2e48c0b598160d5bdabf46 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Fri, 12 Jul 2019 16:56:57 +0000 Subject: [PATCH] tree-ssa-alias.c (same_tmr_indexing_p): Break out from ... * tree-ssa-alias.c (same_tmr_indexing_p): Break out from ... (indirect_refs_may_alias_p): ... here. (nonoverlapping_component_refs_since_match_p): Support also non-trivial mem refs in the access paths. * gcc.dg/tree-ssa/alias-access-path-9.c: New testcase. From-SVN: r273451 --- gcc/ChangeLog | 8 ++++ gcc/testsuite/ChangeLog | 4 ++ .../gcc.dg/tree-ssa/alias-access-path-9.c | 44 +++++++++++++++++++ gcc/tree-ssa-alias.c | 43 +++++++++--------- 4 files changed, 76 insertions(+), 23 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-9.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8923216198c..37b5eafa598 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2019-07-12 Jan Hubicka + + * tree-ssa-alias.c (same_tmr_indexing_p): Break out from ... + (indirect_refs_may_alias_p): ... here. + (nonoverlapping_component_refs_since_match_p): Support also non-trivial + mem refs in the access paths. + 2019-07-12 Jiangning Liu PR tree-optimization/89430 @@ -21,6 +28,7 @@ rather than this_state as the lowering context for the ELSE seq in a GIMPLE_EH_ELSE. +>>>>>>> .r273450 2019-07-12 Richard Sandiford * vector-builder.h (vector_builder::elt): Allow already-supplied diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 71813089358..4d6eb0ff648 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-07-12 Jan Hubicka + + * gcc.dg/tree-ssa/alias-access-path-9.c: New testcase. + 2019-07-08 Jiangning Liu PR tree-optimization/89430 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-9.c b/gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-9.c new file mode 100644 index 00000000000..fdc478922d5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-9.c @@ -0,0 +1,44 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-fre1" } */ + +/* This testcase tests nonoverlapping_component_refs_since_match_p in presence + of non-trivial mem-refs. */ +struct a {int a,b;}; +struct b {struct a a[10];}; +struct c {int c; struct b b;} c, *cptr; + +void +set_a(struct a *a, int p) +{ + a->a=p; +} +void +set_b(struct a *a, int p) +{ + a->b=p; +} +int +get_a(struct a *a) +{ + return a->a; +} + +int +test(int i, int j) +{ + struct b *bptr = &c.b; + set_a (&bptr->a[i], 123); + set_b (&bptr->a[j], 124); + return get_a (&bptr->a[i]); +} + +int +test2(int i, int j) +{ + struct b *bptr = &cptr->b; + set_a (&bptr->a[i], 125); + set_b (&bptr->a[j], 126); + return get_a (&bptr->a[i]); +} +/* { dg-final { scan-tree-dump-times "return 123" 1 "fre1"} } */ +/* { dg-final { scan-tree-dump-times "return 125" 1 "fre1"} } */ diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index 54e3a541271..e1ea30744de 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -1265,20 +1265,6 @@ nonoverlapping_component_refs_since_match_p (tree match1, tree ref1, component_refs1.safe_push (ref1); ref1 = TREE_OPERAND (ref1, 0); } - if (TREE_CODE (ref1) == MEM_REF && ref1 != match1) - { - if (!integer_zerop (TREE_OPERAND (ref1, 1))) - { - ++alias_stats.nonoverlapping_component_refs_since_match_p_may_alias; - return -1; - } - } - /* TODO: Handle TARGET_MEM_REF later. */ - if (TREE_CODE (ref1) == TARGET_MEM_REF && ref1 != match1) - { - ++alias_stats.nonoverlapping_component_refs_since_match_p_may_alias; - return -1; - } /* Create the stack of handled components for REF2. */ while (handled_component_p (ref2) && ref2 != match2) @@ -1290,20 +1276,31 @@ nonoverlapping_component_refs_since_match_p (tree match1, tree ref1, component_refs2.safe_push (ref2); ref2 = TREE_OPERAND (ref2, 0); } - if (TREE_CODE (ref2) == MEM_REF && ref2 != match2) - { - if (!integer_zerop (TREE_OPERAND (ref2, 1))) - { - ++alias_stats.nonoverlapping_component_refs_since_match_p_may_alias; - return -1; - } - } - if (TREE_CODE (ref2) == TARGET_MEM_REF && ref2 != match2) + + bool mem_ref1 = TREE_CODE (ref1) == MEM_REF && ref1 != match1; + bool mem_ref2 = TREE_CODE (ref2) == MEM_REF && ref2 != match2; + + /* If only one of access path starts with MEM_REF check that offset is 0 + so the addresses stays the same after stripping it. + TODO: In this case we may walk the other access path until we get same + offset. + + If both starts with MEM_REF, offset has to be same. */ + if ((mem_ref1 && !mem_ref2 && !integer_zerop (TREE_OPERAND (ref1, 1))) + || (mem_ref2 && !mem_ref1 && !integer_zerop (TREE_OPERAND (ref2, 1))) + || (mem_ref1 && mem_ref2 + && !tree_int_cst_equal (TREE_OPERAND (ref1, 1), + TREE_OPERAND (ref2, 1)))) { ++alias_stats.nonoverlapping_component_refs_since_match_p_may_alias; return -1; } + /* TARGET_MEM_REF are never wrapped in handled components, so we do not need + to handle them here at all. */ + gcc_checking_assert (TREE_CODE (ref1) != TARGET_MEM_REF + && TREE_CODE (ref2) != TARGET_MEM_REF); + /* Pop the stacks in parallel and examine the COMPONENT_REFs of the same rank. This is sufficient because we start from the same DECL and you cannot reference several fields at a time with COMPONENT_REFs (unlike -- 2.30.2