Commit 6b00d7dd by Jakub Jelinek Committed by Jakub Jelinek

re PR tree-optimization/58209 (ICE in extract_range_from_binary_expr, at tree-vrp.c:2294)

	PR tree-optimization/58209
	* tree-tailcall.c (process_assignment): Handle POINTER_PLUS_EXPR.
	(find_tail_calls): Give up for pointer result types if m is non-NULL.
	(adjust_return_value_with_ops): For PLUS_EXPR and pointer result type
	emit POINTER_PLUS_EXPR.
	(create_tailcall_accumulator): For pointer result type accumulate in
	sizetype type.

	* gcc.c-torture/execute/pr58209.c: New test.

From-SVN: r201935
parent 6e6bbb60
2013-08-23 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/58209
* tree-tailcall.c (process_assignment): Handle POINTER_PLUS_EXPR.
(find_tail_calls): Give up for pointer result types if m is non-NULL.
(adjust_return_value_with_ops): For PLUS_EXPR and pointer result type
emit POINTER_PLUS_EXPR.
(create_tailcall_accumulator): For pointer result type accumulate in
sizetype type.
2013-08-22 Paolo Carlini <paolo.carlini@oracle.com> 2013-08-22 Paolo Carlini <paolo.carlini@oracle.com>
* configure.ac: Add backslashes missing from the last change. * configure.ac: Add backslashes missing from the last change.
......
2013-08-23 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/58209
* gcc.c-torture/execute/pr58209.c: New test.
2013-08-22 Michael Meissner <meissner@linux.vnet.ibm.com> 2013-08-22 Michael Meissner <meissner@linux.vnet.ibm.com>
* gcc.target/powerpc/pr57744.c: Declare abort. * gcc.target/powerpc/pr57744.c: Declare abort.
......
/* PR tree-optimization/58209 */
extern void abort (void);
typedef __INTPTR_TYPE__ T;
T buf[1024];
T *
foo (T n)
{
if (n == 0)
return (T *) buf;
T s = (T) foo (n - 1);
return (T *) (s + sizeof (T));
}
T *
bar (T n)
{
if (n == 0)
return buf;
return foo (n - 1) + 1;
}
int
main ()
{
int i;
for (i = 0; i < 27; i++)
if (foo (i) != buf + i || bar (i) != buf + i)
abort ();
return 0;
}
...@@ -305,7 +305,7 @@ process_assignment (gimple stmt, gimple_stmt_iterator call, tree *m, ...@@ -305,7 +305,7 @@ process_assignment (gimple stmt, gimple_stmt_iterator call, tree *m,
if (rhs_class == GIMPLE_UNARY_RHS) if (rhs_class == GIMPLE_UNARY_RHS)
; ;
else if (op0 == *ass_var else if (op0 == *ass_var
&& (non_ass_var = independent_of_stmt_p (op1, stmt, call))) && (non_ass_var = independent_of_stmt_p (op1, stmt, call)))
; ;
else if (op1 == *ass_var else if (op1 == *ass_var
&& (non_ass_var = independent_of_stmt_p (op0, stmt, call))) && (non_ass_var = independent_of_stmt_p (op0, stmt, call)))
...@@ -320,6 +320,13 @@ process_assignment (gimple stmt, gimple_stmt_iterator call, tree *m, ...@@ -320,6 +320,13 @@ process_assignment (gimple stmt, gimple_stmt_iterator call, tree *m,
*ass_var = dest; *ass_var = dest;
return true; return true;
case POINTER_PLUS_EXPR:
if (op0 != *ass_var)
return false;
*a = non_ass_var;
*ass_var = dest;
return true;
case MULT_EXPR: case MULT_EXPR:
*m = non_ass_var; *m = non_ass_var;
*ass_var = dest; *ass_var = dest;
...@@ -562,6 +569,10 @@ find_tail_calls (basic_block bb, struct tailcall **ret) ...@@ -562,6 +569,10 @@ find_tail_calls (basic_block bb, struct tailcall **ret)
if (!tail_recursion && (m || a)) if (!tail_recursion && (m || a))
return; return;
/* For pointers only allow additions. */
if (m && POINTER_TYPE_P (TREE_TYPE (DECL_RESULT (current_function_decl))))
return;
nw = XNEW (struct tailcall); nw = XNEW (struct tailcall);
nw->call_gsi = gsi; nw->call_gsi = gsi;
...@@ -604,15 +615,23 @@ adjust_return_value_with_ops (enum tree_code code, const char *label, ...@@ -604,15 +615,23 @@ adjust_return_value_with_ops (enum tree_code code, const char *label,
tree result = make_temp_ssa_name (ret_type, NULL, label); tree result = make_temp_ssa_name (ret_type, NULL, label);
gimple stmt; gimple stmt;
if (types_compatible_p (TREE_TYPE (acc), TREE_TYPE (op1))) if (POINTER_TYPE_P (ret_type))
{
gcc_assert (code == PLUS_EXPR && TREE_TYPE (acc) == sizetype);
code = POINTER_PLUS_EXPR;
}
if (types_compatible_p (TREE_TYPE (acc), TREE_TYPE (op1))
&& code != POINTER_PLUS_EXPR)
stmt = gimple_build_assign_with_ops (code, result, acc, op1); stmt = gimple_build_assign_with_ops (code, result, acc, op1);
else else
{ {
tree rhs = fold_convert (TREE_TYPE (acc), tree tem;
fold_build2 (code, if (code == POINTER_PLUS_EXPR)
TREE_TYPE (op1), tem = fold_build2 (code, TREE_TYPE (op1), op1, acc);
fold_convert (TREE_TYPE (op1), acc), else
op1)); tem = fold_build2 (code, TREE_TYPE (op1),
fold_convert (TREE_TYPE (op1), acc), op1);
tree rhs = fold_convert (ret_type, tem);
rhs = force_gimple_operand_gsi (&gsi, rhs, rhs = force_gimple_operand_gsi (&gsi, rhs,
false, NULL, true, GSI_SAME_STMT); false, NULL, true, GSI_SAME_STMT);
stmt = gimple_build_assign (result, rhs); stmt = gimple_build_assign (result, rhs);
...@@ -892,6 +911,9 @@ static tree ...@@ -892,6 +911,9 @@ static tree
create_tailcall_accumulator (const char *label, basic_block bb, tree init) create_tailcall_accumulator (const char *label, basic_block bb, tree init)
{ {
tree ret_type = TREE_TYPE (DECL_RESULT (current_function_decl)); tree ret_type = TREE_TYPE (DECL_RESULT (current_function_decl));
if (POINTER_TYPE_P (ret_type))
ret_type = sizetype;
tree tmp = make_temp_ssa_name (ret_type, NULL, label); tree tmp = make_temp_ssa_name (ret_type, NULL, label);
gimple phi; gimple phi;
......
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