On 10/27/21 3:59 AM, apinski--- via Gcc-patches 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.
Since the purpose of this transformation is to avoid a bogus
-Warray-bounds can you please include a test case showing
the difference it makes? (I.e., one that warns without
the patch and doesn't with it. The test in the patch doesn't
trigger a warning for me.)
Thanks
Martin
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)))
+ {
+ 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);
+ }
+ }
+
+ /* Replace the rhs with the new expression. */
+ def_rhs = unshare_expr (def_rhs);
+ 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);
tidy_after_forward_propagate_addr (use_stmt);
return true;
}