re PR tree-optimization/39999 (gcc 4.4.0 compiles in infinite loop)

2009-05-18  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/39999
	* gimple.h (gimple_expr_type): Use the expression type looking
	through useless conversions.
	* tree-ssa-sccvn.c (vn_nary_op_lookup_stmt): Use gimple_expr_type.
	(vn_nary_op_insert_stmt): Likewise.
	(simplify_binary_expression): Likewise.

	* gcc.c-torture/compile/pr39999.c: New testcase.

From-SVN: r147657
This commit is contained in:
Richard Guenther 2009-05-18 10:13:43 +00:00 committed by Richard Biener
parent a335923eb2
commit b7943d39f0
5 changed files with 84 additions and 32 deletions

View File

@ -1,3 +1,12 @@
2009-05-18 Richard Guenther <rguenther@suse.de>
PR tree-optimization/39999
* gimple.h (gimple_expr_type): Use the expression type looking
through useless conversions.
* tree-ssa-sccvn.c (vn_nary_op_lookup_stmt): Use gimple_expr_type.
(vn_nary_op_insert_stmt): Likewise.
(simplify_binary_expression): Likewise.
2009-05-16 Richard Earnshaw <rearnsha@arm.com>
PR target/40153

View File

@ -1394,35 +1394,6 @@ gimple_modified_p (const_gimple g)
return (gimple_has_ops (g)) ? (bool) g->gsbase.modified : false;
}
/* Return the type of the main expression computed by STMT. Return
void_type_node if the statement computes nothing. */
static inline tree
gimple_expr_type (const_gimple stmt)
{
enum gimple_code code = gimple_code (stmt);
if (code == GIMPLE_ASSIGN || code == GIMPLE_CALL)
{
tree type = TREE_TYPE (gimple_get_lhs (stmt));
/* Integral sub-types are never the type of the expression,
but they still can be the type of the result as the base
type (in which expressions are computed) is trivially
convertible to one of its sub-types. So always return
the base type here. */
if (INTEGRAL_TYPE_P (type)
&& TREE_TYPE (type)
/* But only if they are trivially convertible. */
&& useless_type_conversion_p (type, TREE_TYPE (type)))
type = TREE_TYPE (type);
return type;
}
else if (code == GIMPLE_COND)
return boolean_type_node;
else
return void_type_node;
}
/* Return the tree code for the expression computed by STMT. This is
only valid for GIMPLE_COND, GIMPLE_CALL and GIMPLE_ASSIGN. For
@ -4285,6 +4256,55 @@ gimple_predict_set_outcome (gimple gs, enum prediction outcome)
}
/* Return the type of the main expression computed by STMT. Return
void_type_node if the statement computes nothing. */
static inline tree
gimple_expr_type (const_gimple stmt)
{
enum gimple_code code = gimple_code (stmt);
if (code == GIMPLE_ASSIGN || code == GIMPLE_CALL)
{
tree type;
/* In general we want to pass out a type that can be substituted
for both the RHS and the LHS types if there is a possibly
useless conversion involved. That means returning the
original RHS type as far as we can reconstruct it. */
if (code == GIMPLE_CALL)
type = gimple_call_return_type (stmt);
else
switch (gimple_assign_rhs_code (stmt))
{
case POINTER_PLUS_EXPR:
type = TREE_TYPE (gimple_assign_rhs1 (stmt));
break;
default:
/* As fallback use the type of the LHS. */
type = TREE_TYPE (gimple_get_lhs (stmt));
break;
}
/* Integral sub-types are never the type of the expression,
but they still can be the type of the result as the base
type (in which expressions are computed) is trivially
convertible to one of its sub-types. So always return
the base type here. */
if (INTEGRAL_TYPE_P (type)
&& TREE_TYPE (type)
/* But only if they are trivially convertible. */
&& useless_type_conversion_p (type, TREE_TYPE (type)))
type = TREE_TYPE (type);
return type;
}
else if (code == GIMPLE_COND)
return boolean_type_node;
else
return void_type_node;
}
/* Return a new iterator pointing to GIMPLE_SEQ's first statement. */
static inline gimple_stmt_iterator

View File

@ -1,3 +1,8 @@
2009-05-18 Richard Guenther <rguenther@suse.de>
PR tree-optimization/39999
* gcc.c-torture/compile/pr39999.c: New testcase.
2009-05-17 Jason Merrill <jason@redhat.com>
PR c++/40139

View File

@ -0,0 +1,18 @@
void foo(void *);
void
MMAPGCD (int *A1, int *A2)
{
int *t;
do
{
t = A1;
A1 = A2;
A2 = t;
}
while (A2[-1]);
foo (A1-1);
foo (A2-1);
}

View File

@ -1293,7 +1293,7 @@ vn_nary_op_lookup_stmt (gimple stmt, vn_nary_op_t *vnresult)
*vnresult = NULL;
vno1.opcode = gimple_assign_rhs_code (stmt);
vno1.length = gimple_num_ops (stmt) - 1;
vno1.type = TREE_TYPE (gimple_assign_lhs (stmt));
vno1.type = gimple_expr_type (stmt);
for (i = 0; i < vno1.length; ++i)
vno1.op[i] = gimple_op (stmt, i + 1);
if (vno1.opcode == REALPART_EXPR
@ -1401,7 +1401,7 @@ vn_nary_op_insert_stmt (gimple stmt, tree result)
vno1->value_id = VN_INFO (result)->value_id;
vno1->opcode = gimple_assign_rhs_code (stmt);
vno1->length = length;
vno1->type = TREE_TYPE (gimple_assign_lhs (stmt));
vno1->type = gimple_expr_type (stmt);
for (i = 0; i < vno1->length; ++i)
vno1->op[i] = gimple_op (stmt, i + 1);
if (vno1->opcode == REALPART_EXPR
@ -2142,7 +2142,7 @@ simplify_binary_expression (gimple stmt)
fold_defer_overflow_warnings ();
result = fold_binary (gimple_assign_rhs_code (stmt),
TREE_TYPE (gimple_get_lhs (stmt)), op0, op1);
gimple_expr_type (stmt), op0, op1);
if (result)
STRIP_USELESS_TYPE_CONVERSION (result);