summaryrefslogtreecommitdiff
path: root/gcc/tree-tailcall.c
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2010-02-22 14:09:26 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2010-02-22 14:09:26 +0000
commitbc56c1836bc3de9991bba453bdd65842999bc4d8 (patch)
treed0392638ecfe63adb514979931814a136068629f /gcc/tree-tailcall.c
parentbaa9ba0c60e4d213bff87ba491926fbaeb65a782 (diff)
downloadgcc-bc56c1836bc3de9991bba453bdd65842999bc4d8.tar.gz
2010-02-22 Richard Guenther <rguenther@suse.de>
PR tree-optimization/42749 * tree-tailcall.c (adjust_return_value_with_ops): Drop update parameter. Do arithmetic in the original type. (update_accumulator_with_ops): Likewise. (adjust_accumulator_values): Adjust. * gcc.c-torture/compile/pr42749.c: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@156960 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-tailcall.c')
-rw-r--r--gcc/tree-tailcall.c47
1 files changed, 37 insertions, 10 deletions
diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c
index de2a45e949c..bf8ebb85f71 100644
--- a/gcc/tree-tailcall.c
+++ b/gcc/tree-tailcall.c
@@ -570,23 +570,37 @@ add_successor_phi_arg (edge e, tree var, tree phi_arg)
static tree
adjust_return_value_with_ops (enum tree_code code, const char *label,
- tree op0, tree op1, gimple_stmt_iterator gsi,
- enum gsi_iterator_update update)
+ tree acc, tree op1, gimple_stmt_iterator gsi)
{
tree ret_type = TREE_TYPE (DECL_RESULT (current_function_decl));
tree tmp = create_tmp_var (ret_type, label);
- gimple stmt = gimple_build_assign_with_ops (code, tmp, op0, op1);
+ gimple stmt;
tree result;
if (TREE_CODE (ret_type) == COMPLEX_TYPE
|| TREE_CODE (ret_type) == VECTOR_TYPE)
DECL_GIMPLE_REG_P (tmp) = 1;
add_referenced_var (tmp);
+
+ if (types_compatible_p (TREE_TYPE (acc), TREE_TYPE (op1)))
+ stmt = gimple_build_assign_with_ops (code, tmp, acc, op1);
+ else
+ {
+ tree rhs = fold_convert (TREE_TYPE (acc),
+ fold_build2 (code,
+ TREE_TYPE (op1),
+ fold_convert (TREE_TYPE (op1), acc),
+ op1));
+ rhs = force_gimple_operand_gsi (&gsi, rhs,
+ false, NULL, true, GSI_CONTINUE_LINKING);
+ stmt = gimple_build_assign (NULL_TREE, rhs);
+ }
+
result = make_ssa_name (tmp, stmt);
gimple_assign_set_lhs (stmt, result);
update_stmt (stmt);
- gsi_insert_before (&gsi, stmt, update);
+ gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
return result;
}
@@ -599,9 +613,22 @@ static tree
update_accumulator_with_ops (enum tree_code code, tree acc, tree op1,
gimple_stmt_iterator gsi)
{
- gimple stmt = gimple_build_assign_with_ops (code, SSA_NAME_VAR (acc), acc,
- op1);
- tree var = make_ssa_name (SSA_NAME_VAR (acc), stmt);
+ gimple stmt;
+ tree var;
+ if (types_compatible_p (TREE_TYPE (acc), TREE_TYPE (op1)))
+ stmt = gimple_build_assign_with_ops (code, SSA_NAME_VAR (acc), acc, op1);
+ else
+ {
+ tree rhs = fold_convert (TREE_TYPE (acc),
+ fold_build2 (code,
+ TREE_TYPE (op1),
+ fold_convert (TREE_TYPE (op1), acc),
+ op1));
+ rhs = force_gimple_operand_gsi (&gsi, rhs,
+ false, NULL, false, GSI_CONTINUE_LINKING);
+ stmt = gimple_build_assign (NULL_TREE, rhs);
+ }
+ var = make_ssa_name (SSA_NAME_VAR (acc), stmt);
gimple_assign_set_lhs (stmt, var);
update_stmt (stmt);
gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
@@ -631,7 +658,7 @@ adjust_accumulator_values (gimple_stmt_iterator gsi, tree m, tree a, edge back)
var = m_acc;
else
var = adjust_return_value_with_ops (MULT_EXPR, "acc_tmp", m_acc,
- a, gsi, GSI_NEW_STMT);
+ a, gsi);
}
else
var = a;
@@ -667,10 +694,10 @@ adjust_return_value (basic_block bb, tree m, tree a)
if (m)
retval = adjust_return_value_with_ops (MULT_EXPR, "mul_tmp", m_acc, retval,
- gsi, GSI_SAME_STMT);
+ gsi);
if (a)
retval = adjust_return_value_with_ops (PLUS_EXPR, "acc_tmp", a_acc, retval,
- gsi, GSI_SAME_STMT);
+ gsi);
gimple_return_set_retval (ret_stmt, retval);
update_stmt (ret_stmt);
}