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 floating-point reassociation #1


This is a first fix for FP reassocation where we leave + 0.0, * 1.0
in the IL.

Bootstrap and regtest running on x86_64-unknown-linux-gnu, I'll apply
this if it succeeds.

Richard.

2008-02-20  Richard Guenther  <rguenther@suse.de>

	* tree.h (fold_real_zero_addition_p): Declare.
	* fold-const.c (fold_real_zero_addition_p): Export.
	* tree-ssa-reassoc.c (eliminate_using_constants): Also handle
	floating-point operations with zero and one.

	* gcc.dg/tree-ssa/reassoc-13.c: New testcase.

Index: tree-ssa-reassoc.c
===================================================================
*** tree-ssa-reassoc.c	(revision 132472)
--- tree-ssa-reassoc.c	(working copy)
*************** along with GCC; see the file COPYING3.  
*** 39,44 ****
--- 39,45 ----
  #include "langhooks.h"
  #include "pointer-set.h"
  #include "cfgloop.h"
+ #include "flags.h"
  
  /*  This is a simple global reassociation pass.  It is, in part, based
      on the LLVM pass of the same name (They do some things more/less
*************** eliminate_using_constants (enum tree_cod
*** 598,605 ****
  			   VEC(operand_entry_t, heap) **ops)
  {
    operand_entry_t oelast = VEC_last (operand_entry_t, *ops);
  
!   if (oelast->rank == 0 && INTEGRAL_TYPE_P (TREE_TYPE (oelast->op)))
      {
        switch (opcode)
  	{
--- 599,608 ----
  			   VEC(operand_entry_t, heap) **ops)
  {
    operand_entry_t oelast = VEC_last (operand_entry_t, *ops);
+   tree type = TREE_TYPE (oelast->op);
  
!   if (oelast->rank == 0
!       && (INTEGRAL_TYPE_P (type) || FLOAT_TYPE_P (type)))
      {
        switch (opcode)
  	{
*************** eliminate_using_constants (enum tree_cod
*** 660,666 ****
  	    }
  	  break;
  	case MULT_EXPR:
! 	  if (integer_zerop (oelast->op))
  	    {
  	      if (VEC_length (operand_entry_t, *ops) != 1)
  		{
--- 663,673 ----
  	    }
  	  break;
  	case MULT_EXPR:
! 	  if (integer_zerop (oelast->op)
! 	      || (FLOAT_TYPE_P (type)
! 		  && !HONOR_NANS (TYPE_MODE (type))
! 		  && !HONOR_SIGNED_ZEROS (TYPE_MODE (type))
! 		  && real_zerop (oelast->op)))
  	    {
  	      if (VEC_length (operand_entry_t, *ops) != 1)
  		{
*************** eliminate_using_constants (enum tree_cod
*** 675,681 ****
  		  return;
  		}
  	    }
! 	  else if (integer_onep (oelast->op))
  	    {
  	      if (VEC_length (operand_entry_t, *ops) != 1)
  		{
--- 682,691 ----
  		  return;
  		}
  	    }
! 	  else if (integer_onep (oelast->op)
! 		   || (FLOAT_TYPE_P (type)
! 		       && !HONOR_SNANS (TYPE_MODE (type))
! 		       && real_onep (oelast->op)))
  	    {
  	      if (VEC_length (operand_entry_t, *ops) != 1)
  		{
*************** eliminate_using_constants (enum tree_cod
*** 690,696 ****
  	case BIT_XOR_EXPR:
  	case PLUS_EXPR:
  	case MINUS_EXPR:
! 	  if (integer_zerop (oelast->op))
  	    {
  	      if (VEC_length (operand_entry_t, *ops) != 1)
  		{
--- 700,710 ----
  	case BIT_XOR_EXPR:
  	case PLUS_EXPR:
  	case MINUS_EXPR:
! 	  if (integer_zerop (oelast->op)
! 	      || (FLOAT_TYPE_P (type)
! 		  && (opcode == PLUS_EXPR || opcode == MINUS_EXPR)
! 		  && fold_real_zero_addition_p (type, oelast->op,
! 						opcode == MINUS_EXPR)))
  	    {
  	      if (VEC_length (operand_entry_t, *ops) != 1)
  		{
Index: testsuite/gcc.dg/tree-ssa/reassoc-13.c
===================================================================
*** testsuite/gcc.dg/tree-ssa/reassoc-13.c	(revision 0)
--- testsuite/gcc.dg/tree-ssa/reassoc-13.c	(revision 0)
***************
*** 0 ****
--- 1,15 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O -ffast-math -fdump-tree-reassoc1 -fdump-tree-optimized" } */
+ 
+ double foo(double a)
+ {
+   double tmp = 5.0;
+   double tmp2 = a + tmp;
+   tmp2 = tmp2 - a;
+   return a + tmp2 - 5.0;
+ }
+ 
+ /* { dg-final { scan-tree-dump-not "\\\+ 0.0" "reassoc1" } } */
+ /* { dg-final { scan-tree-dump "return a;" "optimized" } } */
+ /* { dg-final { cleanup-tree-dump "reassoc1" } } */
+ /* { dg-final { cleanup-tree-dump "optimized" } } */
Index: tree.h
===================================================================
*** tree.h	(revision 132472)
--- tree.h	(working copy)
*************** extern enum tree_code invert_tree_compar
*** 4851,4856 ****
--- 4851,4858 ----
  extern bool tree_expr_nonzero_p (tree);
  extern bool tree_expr_nonzero_warnv_p (tree, bool *);
  
+ extern bool fold_real_zero_addition_p (const_tree, const_tree, int);
+ 
  /* In builtins.c */
  extern tree fold_call_expr (tree, bool);
  extern tree fold_builtin_fputs (tree, tree, bool, bool, tree);
Index: fold-const.c
===================================================================
*** fold-const.c	(revision 132472)
--- fold-const.c	(working copy)
*************** static tree extract_muldiv_1 (tree, tree
*** 134,140 ****
  static tree fold_binary_op_with_conditional_arg (enum tree_code, tree,
  						 tree, tree,
  						 tree, tree, int);
- static bool fold_real_zero_addition_p (const_tree, const_tree, int);
  static tree fold_mathfn_compare (enum built_in_function, enum tree_code,
  				 tree, tree, tree);
  static tree fold_inf_compare (enum tree_code, tree, tree, tree);
--- 134,139 ----
*************** fold_binary_op_with_conditional_arg (enu
*** 6426,6432 ****
     X - 0 is not the same as X because 0 - 0 is -0.  In other rounding
     modes, X + 0 is not the same as X because -0 + 0 is 0.  */
  
! static bool
  fold_real_zero_addition_p (const_tree type, const_tree addend, int negate)
  {
    if (!real_zerop (addend))
--- 6425,6431 ----
     X - 0 is not the same as X because 0 - 0 is -0.  In other rounding
     modes, X + 0 is not the same as X because -0 + 0 is 0.  */
  
! bool
  fold_real_zero_addition_p (const_tree type, const_tree addend, int negate)
  {
    if (!real_zerop (addend))


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