This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix PR42749


This fixes the wrong typed accumulation during tail-recursion elimination.
We need to make sure to reconstruct the original arithmetic types.

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

Richard.

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.

Index: gcc/tree-tailcall.c
===================================================================
*** gcc/tree-tailcall.c	(revision 156949)
--- gcc/tree-tailcall.c	(working copy)
*************** add_successor_phi_arg (edge e, tree var,
*** 570,592 ****
  
  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 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);
    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);
    result = make_ssa_name (tmp, stmt);
    gimple_assign_set_lhs (stmt, result);
    update_stmt (stmt);
!   gsi_insert_before (&gsi, stmt, update);
    return result;
  }
  
--- 570,606 ----
  
  static tree
  adjust_return_value_with_ops (enum tree_code code, const char *label,
! 			      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;
    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, GSI_NEW_STMT);
    return result;
  }
  
*************** static tree
*** 599,607 ****
  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_assign_set_lhs (stmt, var);
    update_stmt (stmt);
    gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
--- 613,634 ----
  update_accumulator_with_ops (enum tree_code code, tree acc, tree op1,
  			     gimple_stmt_iterator gsi)
  {
!   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);
!     }
!   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);
*************** adjust_accumulator_values (gimple_stmt_i
*** 631,637 ****
  	    var = m_acc;
  	  else
  	    var = adjust_return_value_with_ops (MULT_EXPR, "acc_tmp", m_acc,
! 						a, gsi, GSI_NEW_STMT);
  	}
        else
  	var = a;
--- 658,664 ----
  	    var = m_acc;
  	  else
  	    var = adjust_return_value_with_ops (MULT_EXPR, "acc_tmp", m_acc,
! 						a, gsi);
  	}
        else
  	var = a;
*************** adjust_return_value (basic_block bb, tre
*** 667,676 ****
  
    if (m)
      retval = adjust_return_value_with_ops (MULT_EXPR, "mul_tmp", m_acc, retval,
! 					   gsi, GSI_SAME_STMT);
    if (a)
      retval = adjust_return_value_with_ops (PLUS_EXPR, "acc_tmp", a_acc, retval,
! 					   gsi, GSI_SAME_STMT);
    gimple_return_set_retval (ret_stmt, retval);
    update_stmt (ret_stmt);
  }
--- 694,703 ----
  
    if (m)
      retval = adjust_return_value_with_ops (MULT_EXPR, "mul_tmp", m_acc, retval,
! 					   gsi);
    if (a)
      retval = adjust_return_value_with_ops (PLUS_EXPR, "acc_tmp", a_acc, retval,
! 					   gsi);
    gimple_return_set_retval (ret_stmt, retval);
    update_stmt (ret_stmt);
  }
Index: gcc/testsuite/gcc.c-torture/compile/pr42749.c
===================================================================
*** gcc/testsuite/gcc.c-torture/compile/pr42749.c	(revision 0)
--- gcc/testsuite/gcc.c-torture/compile/pr42749.c	(revision 0)
***************
*** 0 ****
--- 1,5 ----
+ struct pdf_object { int val; };
+ int pdf_count_size_object (struct pdf_object * p_obj)
+ {
+     return pdf_count_size_object(p_obj) + 2 * sizeof(struct pdf_object);
+ }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]