diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-02-22 14:09:26 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-02-22 14:09:26 +0000 |
commit | bc56c1836bc3de9991bba453bdd65842999bc4d8 (patch) | |
tree | d0392638ecfe63adb514979931814a136068629f /gcc/tree-tailcall.c | |
parent | baa9ba0c60e4d213bff87ba491926fbaeb65a782 (diff) | |
download | gcc-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.c | 47 |
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); } |