On Wed, Oct 27, 2021 at 12:00 PM apinski--- via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > From: Andrew Pinski <apin...@marvell.com> > > The problem here is tree-ssa-forwprop.c likes to produce > &MEM <const char *> [(void *)_4 + 152B] which is the same as > _4 p+ 152 which the rest of GCC likes better. > This implements this transformation back to pointer plus to > improve better code generation later on.
Why do you think so? Can you pin-point the transform that now fixes the new testcase? Comments below > OK? Bootstrapped and tested on aarch64-linux-gnu. > > Changes from v1: > * v2: Add comments. > > gcc/ChangeLog: > > PR tree-optimization/102216 > * tree-ssa-forwprop.c (rewrite_assign_addr): New function. > (forward_propagate_addr_expr_1): Use rewrite_assign_addr > when rewriting into the addr_expr into an assignment. > > gcc/testsuite/ChangeLog: > > PR tree-optimization/102216 > * g++.dg/tree-ssa/pr102216.C: New test. > --- > gcc/testsuite/g++.dg/tree-ssa/pr102216.C | 22 +++++++++ > gcc/tree-ssa-forwprop.c | 58 ++++++++++++++++++------ > 2 files changed, 67 insertions(+), 13 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/tree-ssa/pr102216.C > > diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr102216.C > b/gcc/testsuite/g++.dg/tree-ssa/pr102216.C > new file mode 100644 > index 00000000000..b903e4eb57d > --- /dev/null > +++ b/gcc/testsuite/g++.dg/tree-ssa/pr102216.C > @@ -0,0 +1,22 @@ > +/* { dg-options "-O2 -fdump-tree-optimized" } */ > +void link_error (); > +void g () > +{ > + const char **language_names; > + > + language_names = new const char *[6]; > + > + const char **language_names_p = language_names; > + > + language_names_p++; > + language_names_p++; > + language_names_p++; > + > + if ( (language_names_p) - (language_names+3) != 0) > + link_error(); > + delete[] language_names; > +} > +/* We should have removed the link_error on the gimple level as GCC should > + be able to tell that language_names_p is the same as language_names+3. */ > +/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized" } } */ > + > diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c > index a830bab78ba..e4331c60525 100644 > --- a/gcc/tree-ssa-forwprop.c > +++ b/gcc/tree-ssa-forwprop.c > @@ -637,6 +637,47 @@ forward_propagate_into_cond (gimple_stmt_iterator *gsi_p) > return 0; > } > > +/* Rewrite the DEF_RHS as needed into the (plain) use statement. */ > + > +static void > +rewrite_assign_addr (gimple_stmt_iterator *use_stmt_gsi, tree def_rhs) > +{ > + tree def_rhs_base; > + poly_int64 def_rhs_offset; > + > + /* Get the base and offset. */ > + if ((def_rhs_base = get_addr_base_and_unit_offset (TREE_OPERAND (def_rhs, > 0), > + &def_rhs_offset))) So this will cause us to rewrite &MEM[p_1].a.b.c; to a pointer-plus, right? Don't we want to preserve that for object-size stuff? So maybe directly pattern match ADDR_EXPR <MEM_REF <SSA_NAME, ..>> only? > + { > + tree new_ptr; > + poly_offset_int off = 0; > + > + /* If the base was a MEM, then add the offset to the other > + offset and adjust the base. */ > + if (TREE_CODE (def_rhs_base) == MEM_REF) > + { > + off += mem_ref_offset (def_rhs_base); > + new_ptr = TREE_OPERAND (def_rhs_base, 0); > + } > + else > + new_ptr = build_fold_addr_expr (def_rhs_base); > + > + /* If we have the new base is not an address express, then use a p+ > expression > + as the new expression instead of &MEM[x, offset]. */ > + if (TREE_CODE (new_ptr) != ADDR_EXPR) > + { > + tree offset = wide_int_to_tree (sizetype, off); > + def_rhs = build2 (POINTER_PLUS_EXPR, TREE_TYPE (def_rhs), new_ptr, > offset); Ick. You should be able to use gimple_assign_set_rhs_with_ops. > + } > + } > + > + /* Replace the rhs with the new expression. */ > + def_rhs = unshare_expr (def_rhs); and definitely no need to unshare anything here? > + gimple_assign_set_rhs_from_tree (use_stmt_gsi, def_rhs); > + gimple *use_stmt = gsi_stmt (*use_stmt_gsi); > + update_stmt (use_stmt); > +} > + > /* We've just substituted an ADDR_EXPR into stmt. Update all the > relevant data structures to match. */ > > @@ -696,8 +737,8 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs, > if (single_use_p > && useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (def_rhs))) > { > - gimple_assign_set_rhs1 (use_stmt, unshare_expr (def_rhs)); > - gimple_assign_set_rhs_code (use_stmt, TREE_CODE (def_rhs)); > + rewrite_assign_addr (use_stmt_gsi, def_rhs); > + gcc_assert (gsi_stmt (*use_stmt_gsi) == use_stmt); > return true; > } > > @@ -741,14 +782,7 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs, > if (forward_propagate_addr_expr (lhs, new_def_rhs, single_use_p)) > return true; > > - if (useless_type_conversion_p (TREE_TYPE (lhs), > - TREE_TYPE (new_def_rhs))) > - gimple_assign_set_rhs_with_ops (use_stmt_gsi, TREE_CODE (new_def_rhs), > - new_def_rhs); > - else if (is_gimple_min_invariant (new_def_rhs)) > - gimple_assign_set_rhs_with_ops (use_stmt_gsi, NOP_EXPR, new_def_rhs); > - else > - return false; > + rewrite_assign_addr (use_stmt_gsi, new_def_rhs); > gcc_assert (gsi_stmt (*use_stmt_gsi) == use_stmt); > update_stmt (use_stmt); > return true; > @@ -951,9 +985,7 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs, > unshare_expr (def_rhs), > fold_convert (ptr_type_node, > rhs2))); > - gimple_assign_set_rhs_from_tree (use_stmt_gsi, new_rhs); > - use_stmt = gsi_stmt (*use_stmt_gsi); > - update_stmt (use_stmt); > + rewrite_assign_addr (use_stmt_gsi, new_rhs); so you only do this after addr_expr forwarding but not on stmts in general? You could do it that way in the 2nd loop over the BB. > tidy_after_forward_propagate_addr (use_stmt); > return true; > } > -- > 2.17.1 >