From b1259d34e96d27a830254cf19bb7c921cd14e4c6 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 4 Jun 2014 11:55:29 +0000 Subject: [PATCH] tree-ssa-alias.c (stmt_may_clobber_ref_p): Improve handling of accesses with non-invariant address. 2014-06-04 Richard Biener * tree-ssa-alias.c (stmt_may_clobber_ref_p): Improve handling of accesses with non-invariant address. * gcc.dg/tree-ssa/ssa-dse-16.c: New testcase. From-SVN: r211223 --- gcc/ChangeLog | 5 ++ gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-16.c | 18 +++++++ gcc/tree-ssa-alias.c | 56 +++++++++++++++++++--- 4 files changed, 76 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-16.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e892d70035c..d82234cf2b1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2014-06-04 Richard Biener + + * tree-ssa-alias.c (stmt_may_clobber_ref_p): Improve handling + of accesses with non-invariant address. + 2014-06-04 Martin Liska * cgraph.h (cgraph_make_wrapper): New function introduced. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4146bde92b7..b3e39d37df6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2014-06-04 Richard Biener + + * gcc.dg/tree-ssa/ssa-dse-16.c: New testcase. + 2014-06-04 Igor Zamyatin PR c/58942 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-16.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-16.c new file mode 100644 index 00000000000..1cc512c020f --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-16.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-dse1-details" } */ + +struct X { struct A { int a[2]; } b[10]; }; +void foo (struct X *x, int i) +{ + struct A a; + /* Confuse SRA here with using a variable index, otherwise it will mess + with the IL too much. */ + a.a[i] = 3; + a.a[1] = 0; + /* The following store is dead. */ + x->b[i].a[0] = 1; + x->b[i] = a; +} + +/* { dg-final { scan-tree-dump "Deleted dead store" "dse1" } } */ +/* { dg-final { cleanup-tree-dump "dse1" } } */ diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index 0371070a67e..f18cb486f20 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -2174,11 +2174,7 @@ stmt_may_clobber_ref_p (gimple stmt, tree ref) static bool stmt_kills_ref_p_1 (gimple stmt, ao_ref *ref) { - /* For a must-alias check we need to be able to constrain - the access properly. - FIXME: except for BUILTIN_FREE. */ - if (!ao_ref_base (ref) - || ref->max_size == -1) + if (!ao_ref_base (ref)) return false; if (gimple_has_lhs (stmt) @@ -2191,9 +2187,51 @@ stmt_kills_ref_p_1 (gimple stmt, ao_ref *ref) might throw as well. */ && !stmt_can_throw_internal (stmt)) { - tree base, lhs = gimple_get_lhs (stmt); + tree lhs = gimple_get_lhs (stmt); + /* If LHS is literally a base of the access we are done. */ + if (ref->ref) + { + tree base = ref->ref; + if (handled_component_p (base)) + { + tree saved_lhs0 = NULL_TREE; + if (handled_component_p (lhs)) + { + saved_lhs0 = TREE_OPERAND (lhs, 0); + TREE_OPERAND (lhs, 0) = integer_zero_node; + } + do + { + /* Just compare the outermost handled component, if + they are equal we have found a possible common + base. */ + tree saved_base0 = TREE_OPERAND (base, 0); + TREE_OPERAND (base, 0) = integer_zero_node; + bool res = operand_equal_p (lhs, base, 0); + TREE_OPERAND (base, 0) = saved_base0; + if (res) + break; + /* Otherwise drop handled components of the access. */ + base = saved_base0; + } + while (handled_component_p (base)); + if (saved_lhs0) + TREE_OPERAND (lhs, 0) = saved_lhs0; + } + /* Finally check if lhs is equal or equal to the base candidate + of the access. */ + if (operand_equal_p (lhs, base, 0)) + return true; + } + + /* Now look for non-literal equal bases with the restriction of + handling constant offset and size. */ + /* For a must-alias check we need to be able to constrain + the access properly. */ + if (ref->max_size == -1) + return false; HOST_WIDE_INT size, offset, max_size, ref_offset = ref->offset; - base = get_ref_base_and_extent (lhs, &offset, &size, &max_size); + tree base = get_ref_base_and_extent (lhs, &offset, &size, &max_size); /* We can get MEM[symbol: sZ, index: D.8862_1] here, so base == ref->base does not always hold. */ if (base != ref->base) @@ -2261,6 +2299,10 @@ stmt_kills_ref_p_1 (gimple stmt, ao_ref *ref) case BUILT_IN_MEMMOVE_CHK: case BUILT_IN_MEMSET_CHK: { + /* For a must-alias check we need to be able to constrain + the access properly. */ + if (ref->max_size == -1) + return false; tree dest = gimple_call_arg (stmt, 0); tree len = gimple_call_arg (stmt, 2); if (!tree_fits_shwi_p (len))