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] FP divide trapping math


	When flag_trapping_math support was added to GCC, may_trap_p() and
tree_could_trap_p() were modified in a way that is overly conservative and
presumably not what was intended.  The current tests for divide in
tree_could_trap_p() are:

      if (honor_snans || honor_trapv)
        return true;
      if (fp_operation && flag_trapping_math)
        return true;
      t = TREE_OPERAND (expr, 1);
      if (!TREE_CONSTANT (t) || integer_zerop (t))
        return true;
      return false;

As currently written, if flag_trapping_math is false, the code drops
through to the !TREE_CONSTANT || integer_zerop test, which is intended for
integer values.  Any division with a non-constant divisor is considered
trapping, even if trapping-math transformations are allowed.

	may_trap_p() has a similar algorithmic problem.

	As suggested by Daniel Jacobowitz on IRC, the following patch
changes both functions to directly return flag_trapping_math for FP
operations in the divide case instead of testing and falling through for
the false case.

Okay for mainline?

Thanks, David


2005-04-02  David Edelsohn  <edelsohn@gnu.org>
	    Daniel Jacobowitz  <dan@codesourcery.com>

	* tree-eh.c (tree_could_trap_p): Allow non-constant floating point
	trapping divide.
	* rtlanal.c (may_trap_p): Same.

Index: tree-eh.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-eh.c,v
retrieving revision 2.28
diff -c -p -r2.28 tree-eh.c
*** tree-eh.c	1 Apr 2005 03:42:44 -0000	2.28
--- tree-eh.c	2 Apr 2005 19:31:00 -0000
*************** tree_could_trap_p (tree expr)
*** 1787,1794 ****
      case RDIV_EXPR:
        if (honor_snans || honor_trapv)
  	return true;
!       if (fp_operation && flag_trapping_math)
! 	return true;
        t = TREE_OPERAND (expr, 1);
        if (!TREE_CONSTANT (t) || integer_zerop (t))
          return true;
--- 1787,1794 ----
      case RDIV_EXPR:
        if (honor_snans || honor_trapv)
  	return true;
!       if (fp_operation)
! 	return flag_trapping_math;
        t = TREE_OPERAND (expr, 1);
        if (!TREE_CONSTANT (t) || integer_zerop (t))
          return true;
Index: rtlanal.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtlanal.c,v
retrieving revision 1.213
diff -c -p -r1.213 rtlanal.c
*** rtlanal.c	16 Mar 2005 20:42:37 -0000	1.213
--- rtlanal.c	2 Apr 2005 19:31:00 -0000
*************** may_trap_p (rtx x)
*** 2105,2115 ****
      case UMOD:
        if (HONOR_SNANS (GET_MODE (x)))
  	return 1;
!       if (! CONSTANT_P (XEXP (x, 1))
! 	  || (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT
! 	      && flag_trapping_math))
! 	return 1;
!       if (XEXP (x, 1) == const0_rtx)
  	return 1;
        break;
  
--- 2105,2113 ----
      case UMOD:
        if (HONOR_SNANS (GET_MODE (x)))
  	return 1;
!       if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
! 	return flag_trapping_math;
!       if (!CONSTANT_P (XEXP (x, 1)) || (XEXP (x, 1) == const0_rtx))
  	return 1;
        break;
  


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