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]

Re: Patch gcc-4.0 should not apply mathematical associative rules for addition or multiplication



On Oct 6, 2004, at 11:38 AM, Geoff Keating wrote:



On 06/10/2004, at 10:11 AM, Fariborz Jahanian wrote:



On Oct 5, 2004, at 2:46 PM, Geoff Keating wrote:



OK. I am not going to re-design Fariborz's patch for him in an e-mail exchange. It is clear that the explanation of the patch is inadequate to determine whether or not the patch is correct, so the patch is rejected. Fariborz, please re-post the patch with a better explanation, and addressing the other points I mentioned.


I have a new patch description which, I hope, addresses Geoff's questions. Also, I have attached a dejagnu-style
test case.

No, do not "attach" it. Make it *part of the patch*, so that I can see where you are planning to put it in the tree. Also, why is it limited to running on powerpc? Why is it forcing -O1?

Every body attaches a test case to the patch describing the patch. Sorry, I don't understand you here. This test
case goes under gcc.dg directory (if this is the question you are raising). Also, -O1 shows the problem. So,
test case shows the problem with -O1. I will remove powerpc in test case.



- fariborz (fjahanian@apple.com)

Abstract: In the following code the repeated multiplication is folded into a single
operation (multiplication by Infinity), when compiled for apple-ppc-darwin target.
For different values of "x" this leads to undeserved or absent floating point
exceptions, and breaks some of the elementary math functions in Libm. Occurs
at optimization O1 and higher.


/* test */
static const double C = 0x1.0p1023;

double foo(double x)
{
        return ( ( (x * C) * C ) * C );
}

Section 5.1.2.3 Program execution of the Programming languages C standard says:

13 EXAMPLE 5 Rearrangement for floating-point expressions is often restricted because of limitations
in precision as well as range. The implementation cannot generally apply the mathematical associative
rules for addition or multiplication, nor the distributive rule, because of roundoff error, even
in the absence of overflowand underflow. Likewise, implementations cannot generally replace decimal
constants in order to rearrange expressions. In the following fragment, rearrangements suggested by
mathematical rules for real numbers are often not valid (see F.8).
double x, y, z;
/*... */
x=(x*y)*z;
//not equivalent to
x*=y*z;


So, such optimization cannot take place under general optimization flags.
Question remains, under which flag should we place this specific unsafe optiomization?
There has been three suggestions, I will address each, one by one.


1. Do this optimization when flag_trapping_math is 0 (default is 1).
"Zero means that floating-point math operations cannot generate a
(user-visible) trap". This includes overflow, underflow. This certainly
can be the flag to check for. But such an optimization may cause finite
results which could be incorrect without causing a trap, for example,
a roundoff error.


2. Do this optimization when flag_finite_math_only is 1 (default is 0).
"Allow optimizations for floating-point arithmetic that assume that
arguments and results are not NaNs or +-Infs". Again, result of such
an optimization can be finite but wrong.


3. -funsafe-math-optimizations
"Allow optimizations for floating-point arithmetic that (a) assume
that arguments and results are valid and (b) may violate IEEE or
ANSI standards".
Such an optimization is in violation of Section 5.1.2.3 of ANSI standards
as noted in above.


Above flag has been used for the following case, among others:

from negate_expr_p(tree) in fold-const.c

      case PLUS_EXPR:
      if (FLOAT_TYPE_P (type) && !flag_unsafe_math_optimizations)
        return false;
      /* -(A + B) -> (-B) - A.  */
        ...
      /* -(A + B) -> (-A) - B.  */
        ...

So, it seems that flag_unsafe_math_optimizations has been used in
other situations to disallow certain optimizations which are in violation of ANSI
standards. This is the flag that I check for in my patch.

Your explanation is still wrong, but I don't think you understand the situation well enough to come up with a correct explanation, so I'm giving up on that part. I would suggest, though, that in future you ask an expert about standards or floating-point questions.

I tried, I tried. I sent the patch as request for comments and received responses from several people;
including Dale, Gaby, you, and Roger. I am sure you will find an expert among this panel. Please go
back and read the extensive thread of the past two days. BTW, this bug was filed by Steve Peters at
Apple who most of us consider an expert on FP issues.


- fariborz




ChangeLog:


2004-10-05 Fariborz Jahanian <fjahanian@apple.com>

        * tree-ssa-dom.c (associative_fp_binop): New function.
        (simplify_rhs_and_lookup_avail_expr): Disallow associativity
        and constant folding of floating point MULT_EXPR/PLUS_EXPR
        expressions.

<fsf-patch-tree-ssa-dom.txt> <unsafe-fp-assoc.c>



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