This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] FP divide trapping math
- From: David Edelsohn <dje at watson dot ibm dot com>
- To: Richard Henderson <rth at redhat dot com>, Roger Sayle <roger at eyesopen dot com>, Geoff Keating <geoffk at geoffk dot org>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Sat, 02 Apr 2005 15:30:04 -0500
- Subject: [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;