Commit 01e9f181 by Richard Biener

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.
parent 6fc2f933
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.
2020-01-21 Andrew Pinski <apinski@marvel.com> 2020-01-21 Andrew Pinski <apinski@marvel.com>
PR tree-opt/93321 PR tree-opt/93321
......
2020-01-21 Richard Biener <rguenther@suse.de>
PR tree-optimization/92328
* gcc.dg/torture/pr92328.c: New testcase.
2020-01-21 Jakub Jelinek <jakub@redhat.com> 2020-01-21 Jakub Jelinek <jakub@redhat.com>
PR target/93073 PR target/93073
......
/* { dg-do compile } */
/* { dg-additional-options "-ftree-pre -Wno-div-by-zero" } */
int nt;
void
ja (int os)
{
int *ku = &os, *id = &os;
unsigned int qr = 0;
for (;;)
{
if (os == *ku)
{
*id = 0;
qr += os != *ku;
id = &qr;
}
*id &= qr;
if (os != 0)
{
nt /= 0;
ku = &qr;
}
}
}
...@@ -2712,11 +2712,8 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_, ...@@ -2712,11 +2712,8 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_,
|| known_eq (ref->size, TYPE_PRECISION (vr->type))) || known_eq (ref->size, TYPE_PRECISION (vr->type)))
&& multiple_p (ref->size, BITS_PER_UNIT)) && multiple_p (ref->size, BITS_PER_UNIT))
{ {
if (known_eq (ref->size, size2)) tree val = NULL_TREE;
return vn_reference_lookup_or_insert_for_pieces if (! INTEGRAL_TYPE_P (TREE_TYPE (def_rhs))
(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))) || type_has_mode_precision_p (TREE_TYPE (def_rhs)))
{ {
gimple_match_op op (gimple_match_cond::UNCOND, gimple_match_op op (gimple_match_cond::UNCOND,
...@@ -2724,7 +2721,15 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_, ...@@ -2724,7 +2721,15 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_,
SSA_VAL (def_rhs), SSA_VAL (def_rhs),
bitsize_int (ref->size), bitsize_int (ref->size),
bitsize_int (offset - offset2)); bitsize_int (offset - offset2));
tree val = vn_nary_build_or_lookup (&op); 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 if (val
&& (TREE_CODE (val) != SSA_NAME && (TREE_CODE (val) != SSA_NAME
|| ! SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val))) || ! SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val)))
...@@ -2732,7 +2737,6 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_, ...@@ -2732,7 +2737,6 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_,
(vuse, get_alias_set (lhs), vr->type, (vuse, get_alias_set (lhs), vr->type,
vr->operands, val); vr->operands, val);
} }
}
else if (maxsize.is_constant (&maxsizei) else if (maxsize.is_constant (&maxsizei)
&& maxsizei % BITS_PER_UNIT == 0 && maxsizei % BITS_PER_UNIT == 0
&& offset.is_constant (&offseti) && offset.is_constant (&offseti)
...@@ -5599,7 +5603,6 @@ eliminate_dom_walker::eliminate_stmt (basic_block b, gimple_stmt_iterator *gsi) ...@@ -5599,7 +5603,6 @@ eliminate_dom_walker::eliminate_stmt (basic_block b, gimple_stmt_iterator *gsi)
&& (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
|| is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))) || is_gimple_min_invariant (gimple_assign_rhs1 (stmt))))
{ {
tree val;
tree rhs = gimple_assign_rhs1 (stmt); tree rhs = gimple_assign_rhs1 (stmt);
vn_reference_t vnresult; vn_reference_t vnresult;
/* ??? gcc.dg/torture/pr91445.c shows that we lookup a boolean /* ??? 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) ...@@ -5640,14 +5643,22 @@ eliminate_dom_walker::eliminate_stmt (basic_block b, gimple_stmt_iterator *gsi)
else else
lookup_lhs = NULL_TREE; lookup_lhs = NULL_TREE;
} }
val = NULL_TREE; tree val = NULL_TREE;
if (lookup_lhs) if (lookup_lhs)
val = vn_reference_lookup (lookup_lhs, gimple_vuse (stmt), VN_WALK, val = vn_reference_lookup (lookup_lhs, gimple_vuse (stmt), VN_WALK,
&vnresult, false); &vnresult, false);
if (TREE_CODE (rhs) == SSA_NAME) if (TREE_CODE (rhs) == SSA_NAME)
rhs = VN_INFO (rhs)->valnum; rhs = VN_INFO (rhs)->valnum;
if (val 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 /* We can only remove the later store if the former aliases
at least all accesses the later one does or if the store at least all accesses the later one does or if the store
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment