re PR tree-optimization/53168 (ICE in find_or_generate_expression, at tree-ssa-pre.c:3053)

2012-05-04  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/53168
	* tree-ssa-pre.c (phi_translate_1): Only handle type-punned
	memory reads when the result is a constant we can pun.

	* gcc.dg/torture/pr53168.c: New testcase.
	* gcc.dg/tree-ssa/ssa-pre-30.c: Likewise.

From-SVN: r187153
This commit is contained in:
Richard Guenther 2012-05-04 11:30:35 +00:00 committed by Richard Biener
parent 1d67dde883
commit efe7068bc9
5 changed files with 89 additions and 56 deletions

View file

@ -1,3 +1,9 @@
2012-05-04 Richard Guenther <rguenther@suse.de>
PR tree-optimization/53168
* tree-ssa-pre.c (phi_translate_1): Only handle type-punned
memory reads when the result is a constant we can pun.
2012-05-04 Richard Guenther <rguenther@suse.de>
* common.opt (flto-report): Do not mark as Optimization.

View file

@ -1,3 +1,9 @@
2012-05-04 Richard Guenther <rguenther@suse.de>
PR tree-optimization/53168
* gcc.dg/torture/pr53168.c: New testcase.
* gcc.dg/tree-ssa/ssa-pre-30.c: Likewise.
2012-05-04 Richard Guenther <rguenther@suse.de>
* gcc.dg/lto/pr53214_0.c: New testcase.

View file

@ -0,0 +1,28 @@
/* { dg-do compile } */
int a, b, c;
unsigned *d;
int e[1];
void fn1 ();
int fn2 ();
int
fn3 ()
{
int *f = &a;
if (fn2 ())
{
for (; c; c++)
{
e[a] && (b = 0);
fn1 ();
if (e[a])
return 0;
}
for (; c <= 0; c++)
for (;;)
;
}
else
e[0] = 0 != (d = f);
return *d;
}

View file

@ -0,0 +1,27 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-pre-details" } */
int f;
int g;
unsigned int
foo (int b, int x)
{
if (b)
x = *(int *)&f;
g = x;
return *(unsigned int*)&f;
}
float
bar (int b, int x)
{
if (b)
x = *(int *)&f;
g = x;
return *(float *)&f;
}
/* We should see the partial redundant loads of f even though they
are using different types (of the same size). */
/* { dg-final { scan-tree-dump-times "Replaced MEM" 2 "pre" } } */
/* { dg-final { cleanup-tree-dump "pre" } } */

View file

@ -1659,7 +1659,6 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
{
unsigned int new_val_id;
pre_expr constant;
bool converted = false;
tree result = vn_reference_lookup_pieces (newvuse, ref->set,
ref->type,
@ -1668,12 +1667,29 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
if (result)
VEC_free (vn_reference_op_s, heap, newoperands);
/* We can always insert constants, so if we have a partial
redundant constant load of another type try to translate it
to a constant of appropriate type. */
if (result && is_gimple_min_invariant (result))
{
tree tem = result;
if (!useless_type_conversion_p (ref->type, TREE_TYPE (result)))
{
tem = fold_unary (VIEW_CONVERT_EXPR, ref->type, result);
if (tem && !is_gimple_min_invariant (tem))
tem = NULL_TREE;
}
if (tem)
return get_or_alloc_expr_for_constant (tem);
}
/* If we'd have to convert things we would need to validate
if we can insert the translated expression. So fail
here for now - we cannot insert an alias with a different
type in the VN tables either, as that would assert. */
if (result
&& !useless_type_conversion_p (ref->type, TREE_TYPE (result)))
{
result = fold_build1 (VIEW_CONVERT_EXPR, ref->type, result);
converted = true;
}
return NULL;
else if (!result && newref
&& !useless_type_conversion_p (ref->type, newref->type))
{
@ -1681,61 +1697,11 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
return NULL;
}
if (result && is_gimple_min_invariant (result))
{
gcc_assert (!newoperands);
return get_or_alloc_expr_for_constant (result);
}
expr = (pre_expr) pool_alloc (pre_expr_pool);
expr->kind = REFERENCE;
expr->id = 0;
if (converted)
{
vn_nary_op_t nary;
tree nresult;
gcc_assert (CONVERT_EXPR_P (result)
|| TREE_CODE (result) == VIEW_CONVERT_EXPR);
nresult = vn_nary_op_lookup_pieces (1, TREE_CODE (result),
TREE_TYPE (result),
&TREE_OPERAND (result, 0),
&nary);
if (nresult && is_gimple_min_invariant (nresult))
return get_or_alloc_expr_for_constant (nresult);
expr->kind = NARY;
if (nary)
{
PRE_EXPR_NARY (expr) = nary;
constant = fully_constant_expression (expr);
if (constant != expr)
return constant;
new_val_id = nary->value_id;
get_or_alloc_expression_id (expr);
}
else
{
new_val_id = get_next_value_id ();
VEC_safe_grow_cleared (bitmap_set_t, heap,
value_expressions,
get_max_value_id() + 1);
nary = vn_nary_op_insert_pieces (1, TREE_CODE (result),
TREE_TYPE (result),
&TREE_OPERAND (result, 0),
NULL_TREE,
new_val_id);
PRE_EXPR_NARY (expr) = nary;
constant = fully_constant_expression (expr);
if (constant != expr)
return constant;
get_or_alloc_expression_id (expr);
}
}
else if (newref)
if (newref)
{
PRE_EXPR_REFERENCE (expr) = newref;
constant = fully_constant_expression (expr);