[Bug tree-optimization/63185] Improve DSE with branches
rguenth at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Thu May 17 08:39:00 GMT 2018
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63185
--- Comment #9 from Richard Biener <rguenth at gcc dot gnu.org> ---
So the following incomplete patch solves the value-numbering issue in FRE2.
diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c
index a121b880bb0..745d60cbda5 100644
--- a/gcc/tree-dfa.c
+++ b/gcc/tree-dfa.c
@@ -529,6 +529,31 @@ get_ref_base_and_extent (tree exp, poly_int64_pod
*poffset,
/* Remember that we have seen an array ref with a variable
index. */
seen_variable_array_ref = true;
+
+ wide_int min, max;
+ if (TREE_CODE (index) == SSA_NAME
+ && integer_zerop (array_ref_low_bound (exp))
+ && (unit_size = array_ref_element_size (exp),
+ TREE_CODE (unit_size) == INTEGER_CST)
+ && get_range_info (index, &min, &max) == VR_RANGE
+ && wi::gts_p (max, 0))
+ {
+ poly_offset_int rmaxsize;
+ rmaxsize = offset_int::from (max, UNSIGNED) * wi::to_offset
(unit_size);
+ if (known_size_p (maxsize))
+ {
+ if (known_lt (rmaxsize, maxsize))
+ {
+ maxsize = rmaxsize;
+ seen_variable_array_ref = false;
+ }
+ }
+ else
+ {
+ maxsize = rmaxsize;
+ seen_variable_array_ref = false;
+ }
+ }
}
}
break;
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 1463c1d4116..dad4e4fecdf 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -1960,19 +1960,46 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void
*vr_,
&& gimple_call_builtin_p (def_stmt, BUILT_IN_MEMSET)
&& integer_zerop (gimple_call_arg (def_stmt, 1))
&& 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, 0))
+ return (void *)-1;
+ }
+ else
+ {
+ if (TREE_CODE (base) != MEM_REF
+ || TREE_OPERAND (base, 0) != ref2
+ || !integer_zerop (TREE_OPERAND (base, 1)))
+ return (void *)-1;
+ offset2 = 0;
+ }
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);
return vn_reference_lookup_or_insert_for_pieces
More information about the Gcc-bugs
mailing list