aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2018-05-17 12:06:44 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2018-05-17 12:06:44 +0000
commit3f90a68f0fda2f571ba2a3463096b82dbea51217 (patch)
tree8a4f99dc14271f8125acec10e5b00b17aafa6262
parentbb4e47476537f6431fbbf29cc804252b1504bbc2 (diff)
downloadgcc-3f90a68f0fda2f571ba2a3463096b82dbea51217.zip
gcc-3f90a68f0fda2f571ba2a3463096b82dbea51217.tar.gz
gcc-3f90a68f0fda2f571ba2a3463096b82dbea51217.tar.bz2
tree-ssa-sccvn.c (vn_reference_lookup_3): Improve memset handling.
2018-05-17 Richard Biener <rguenther@suse.de> * tree-ssa-sccvn.c (vn_reference_lookup_3): Improve memset handling. * gcc.dg/tree-ssa/ssa-fre-63.c: New testcase. From-SVN: r260318
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-63.c11
-rw-r--r--gcc/tree-ssa-sccvn.c72
4 files changed, 81 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b80d6be..8a800a7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,7 @@
+2018-05-17 Richard Biener <rguenther@suse.de>
+
+ * tree-ssa-sccvn.c (vn_reference_lookup_3): Improve memset handling.
+
2018-05-17 Bin Cheng <bin.cheng@arm.com>
Richard Biener <rguenther@suse.de>
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 69a8998..2139976 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2018-05-17 Richard Biener <rguenther@suse.de>
+
+ * gcc.dg/tree-ssa/ssa-fre-63.c: New testcase.
+
2018-05-17 Bin Cheng <bin.cheng@arm.com>
PR tree-optimization/85793
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-63.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-63.c
new file mode 100644
index 0000000..39e8c08
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-63.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-fre1-stats" } */
+
+int foo(char *x)
+{
+ __builtin_memset (&x[1], 'c', 42);
+ return x[0] + x[1] + x[42] + x[43];
+}
+
+/* We should eliminate x[1] and x[42] and their conversions to int. */
+/* { dg-final { scan-tree-dump "Eliminated: 4" "fre1" } } */
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 1463c1d..39de866 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -1958,23 +1958,75 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_,
1) Memset. */
if (is_gimple_reg_type (vr->type)
&& gimple_call_builtin_p (def_stmt, BUILT_IN_MEMSET)
- && integer_zerop (gimple_call_arg (def_stmt, 1))
+ && (integer_zerop (gimple_call_arg (def_stmt, 1))
+ || (INTEGRAL_TYPE_P (vr->type) && known_eq (ref->size, 8)))
&& poly_int_tree_p (gimple_call_arg (def_stmt, 2))
- && TREE_CODE (gimple_call_arg (def_stmt, 0)) == ADDR_EXPR)
+ && (TREE_CODE (gimple_call_arg (def_stmt, 0)) == ADDR_EXPR
+ || TREE_CODE (gimple_call_arg (def_stmt, 0)) == SSA_NAME))
{
- tree ref2 = TREE_OPERAND (gimple_call_arg (def_stmt, 0), 0);
tree base2;
poly_int64 offset2, size2, maxsize2;
bool reverse;
- base2 = get_ref_base_and_extent (ref2, &offset2, &size2, &maxsize2,
- &reverse);
+ tree ref2 = gimple_call_arg (def_stmt, 0);
+ if (TREE_CODE (ref2) == SSA_NAME)
+ {
+ ref2 = SSA_VAL (ref2);
+ if (TREE_CODE (ref2) == SSA_NAME
+ && (TREE_CODE (base) != MEM_REF
+ || TREE_OPERAND (base, 0) != ref2))
+ {
+ gimple *def_stmt = SSA_NAME_DEF_STMT (ref2);
+ if (gimple_assign_single_p (def_stmt)
+ && gimple_assign_rhs_code (def_stmt) == ADDR_EXPR)
+ ref2 = gimple_assign_rhs1 (def_stmt);
+ }
+ }
+ if (TREE_CODE (ref2) == ADDR_EXPR)
+ {
+ ref2 = TREE_OPERAND (ref2, 0);
+ base2 = get_ref_base_and_extent (ref2, &offset2, &size2, &maxsize2,
+ &reverse);
+ if (!known_size_p (maxsize2)
+ || !operand_equal_p (base, base2, OEP_ADDRESS_OF))
+ return (void *)-1;
+ }
+ else if (TREE_CODE (ref2) == SSA_NAME)
+ {
+ poly_int64 soff;
+ if (TREE_CODE (base) != MEM_REF
+ || !(mem_ref_offset (base) << LOG2_BITS_PER_UNIT).to_shwi (&soff))
+ return (void *)-1;
+ offset += soff;
+ offset2 = 0;
+ if (TREE_OPERAND (base, 0) != ref2)
+ {
+ gimple *def = SSA_NAME_DEF_STMT (ref2);
+ if (is_gimple_assign (def)
+ && gimple_assign_rhs_code (def) == POINTER_PLUS_EXPR
+ && gimple_assign_rhs1 (def) == TREE_OPERAND (base, 0)
+ && poly_int_tree_p (gimple_assign_rhs2 (def))
+ && (wi::to_poly_offset (gimple_assign_rhs2 (def))
+ << LOG2_BITS_PER_UNIT).to_shwi (&offset2))
+ {
+ ref2 = gimple_assign_rhs1 (def);
+ if (TREE_CODE (ref2) == SSA_NAME)
+ ref2 = SSA_VAL (ref2);
+ }
+ else
+ return (void *)-1;
+ }
+ }
+ else
+ return (void *)-1;
tree len = gimple_call_arg (def_stmt, 2);
- if (known_size_p (maxsize2)
- && operand_equal_p (base, base2, 0)
- && known_subrange_p (offset, maxsize, offset2,
- wi::to_poly_offset (len) << LOG2_BITS_PER_UNIT))
+ if (known_subrange_p (offset, maxsize, offset2,
+ wi::to_poly_offset (len) << LOG2_BITS_PER_UNIT))
{
- tree val = build_zero_cst (vr->type);
+ tree val;
+ if (integer_zerop (gimple_call_arg (def_stmt, 1)))
+ val = build_zero_cst (vr->type);
+ else
+ val = fold_convert (vr->type, gimple_call_arg (def_stmt, 1));
return vn_reference_lookup_or_insert_for_pieces
(vuse, vr->set, vr->type, vr->operands, val);
}