diff options
author | Richard Biener <rguenther@suse.de> | 2020-01-21 10:37:18 +0100 |
---|---|---|
committer | Richard Biener <rguenther@suse.de> | 2020-01-21 12:54:08 +0100 |
commit | 01e9f1812c72c940172700971179d7726b7a3050 (patch) | |
tree | df25df2f795f0e78d452406e2a8562bfb3c7e364 /gcc/tree-ssa-sccvn.c | |
parent | 6fc2f9337311c11dabcc464c808cbef205f17a52 (diff) |
tree-optimization/92328 fix value-number with bogus type
We were actually value-numbering two entities with different type
the same rather than just having the same representation in the
hashtable. The following fixes that by wrapping the value in a
to be inserted VIEW_CONVERT_EXPR.
2020-01-21 Richard Biener <rguenther@suse.de>
PR tree-optimization/92328
* tree-ssa-sccvn.c (vn_reference_lookup_3): Preserve
type when value-numbering same-sized store by inserting a
VIEW_CONVERT_EXPR.
(eliminate_dom_walker::eliminate_stmt): When eliminating
a redundant store handle bit-reinterpretation of the same value.
* gcc.dg/torture/pr92328.c: New testcase.
Diffstat (limited to 'gcc/tree-ssa-sccvn.c')
-rw-r--r-- | gcc/tree-ssa-sccvn.c | 43 |
1 files changed, 27 insertions, 16 deletions
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index 4d1301593d7..0b8ee586139 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -2712,26 +2712,30 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_, || known_eq (ref->size, TYPE_PRECISION (vr->type))) && multiple_p (ref->size, BITS_PER_UNIT)) { - if (known_eq (ref->size, size2)) - return vn_reference_lookup_or_insert_for_pieces - (vuse, get_alias_set (lhs), vr->type, vr->operands, - SSA_VAL (def_rhs)); - else if (! INTEGRAL_TYPE_P (TREE_TYPE (def_rhs)) - || type_has_mode_precision_p (TREE_TYPE (def_rhs))) + tree val = NULL_TREE; + if (! INTEGRAL_TYPE_P (TREE_TYPE (def_rhs)) + || type_has_mode_precision_p (TREE_TYPE (def_rhs))) { gimple_match_op op (gimple_match_cond::UNCOND, BIT_FIELD_REF, vr->type, SSA_VAL (def_rhs), bitsize_int (ref->size), bitsize_int (offset - offset2)); - tree val = vn_nary_build_or_lookup (&op); - if (val - && (TREE_CODE (val) != SSA_NAME - || ! SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val))) - return vn_reference_lookup_or_insert_for_pieces - (vuse, get_alias_set (lhs), vr->type, - vr->operands, val); + val = vn_nary_build_or_lookup (&op); } + else if (known_eq (ref->size, size2)) + { + gimple_match_op op (gimple_match_cond::UNCOND, + VIEW_CONVERT_EXPR, vr->type, + SSA_VAL (def_rhs)); + val = vn_nary_build_or_lookup (&op); + } + if (val + && (TREE_CODE (val) != SSA_NAME + || ! SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val))) + return vn_reference_lookup_or_insert_for_pieces + (vuse, get_alias_set (lhs), vr->type, + vr->operands, val); } else if (maxsize.is_constant (&maxsizei) && maxsizei % BITS_PER_UNIT == 0 @@ -5599,7 +5603,6 @@ eliminate_dom_walker::eliminate_stmt (basic_block b, gimple_stmt_iterator *gsi) && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME || is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))) { - tree val; tree rhs = gimple_assign_rhs1 (stmt); vn_reference_t vnresult; /* ??? gcc.dg/torture/pr91445.c shows that we lookup a boolean @@ -5640,14 +5643,22 @@ eliminate_dom_walker::eliminate_stmt (basic_block b, gimple_stmt_iterator *gsi) else lookup_lhs = NULL_TREE; } - val = NULL_TREE; + tree val = NULL_TREE; if (lookup_lhs) val = vn_reference_lookup (lookup_lhs, gimple_vuse (stmt), VN_WALK, &vnresult, false); if (TREE_CODE (rhs) == SSA_NAME) rhs = VN_INFO (rhs)->valnum; if (val - && operand_equal_p (val, rhs, 0)) + && (operand_equal_p (val, rhs, 0) + /* Due to the bitfield lookups above we can get bit + interpretations of the same RHS as values here. Those + are redundant as well. */ + || (TREE_CODE (val) == SSA_NAME + && gimple_assign_single_p (SSA_NAME_DEF_STMT (val)) + && (val = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (val))) + && TREE_CODE (val) == VIEW_CONVERT_EXPR + && TREE_OPERAND (val, 0) == rhs))) { /* We can only remove the later store if the former aliases at least all accesses the later one does or if the store |