In http://gcc.gnu.org/ml/gcc-patches/2007-05/msg01931.html Andrew Pinski wrote:
> On 5/28/07, Dominique Dhumieres <[EMAIL PROTECTED]> wrote: > > So if I am not mistaken, -ffast-math does not obey the parentheses. > > If you consider this is a bug, I'll fill a bug report. > > -ffast-math enables -funsafe-math-optimizations which tells the > compiler to ignore those rules (and reassiocate all it can). So no > this is not a bug. This is by design. In my opinion, this is a very bad design. Take the following code: real :: f1, f2 print *, f1(1.2), f2(1.2) print *, f1(nearest(1.5,-1.0)), f2(nearest(1.5,-1.0)) print *, f1(1.5), f2(1.5), anint(1.5) print *, f1(nearest(1.5,1.0)), f2(nearest(1.5,1.0)) print *, f1(1.7), f2(1.7) end real function f1(a) real, parameter :: f = 2.0**23 real :: a f1 = (f+a)-f end real function f2(a) real, parameter :: f = 2.0**23 real :: a f2 = (a+f)-f end As you can try, f1(a) and f2(a) return anint(a) in a much faster way (I borrowed the trick from xlf!-). -funsafe-math-optimizations prevents me to use it with other "unsafe-math-optimizations" (see below why this can be bad). For me one of the following actions should be taken (ranked according my preference): (1) This feature should be deleted, though I have no illusion! As a lazy programmer when I put parentheses I have good reasons (see the above code) and want the parentheses obeyed as it is mandatory in Fortran. To bad if it does not give a good timing on some stupid benchmark designed to test this kind of pseudo-optimisation. (2) Remove the feature from -funsafe-math-optimizations and add a new option -fdont-obey-parentheses (anything like that) being not part of -ffast-math. (3) Emit a warning when the parentheses are not obeyed. (4) At least, document (in flashing bold-face red) the (mis)feature: The gcc manual says: > -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. When used at link-time, it may include libraries or > startup files that change the default FPU control word or other > similar optimizations. > > This option is not turned on by any -O option since it can result in > incorrect output for programs which depend on an exact implementation > of IEEE or ISO rules/specifications for math functions. It may, > however, yield faster code for programs that do not require the > guarantees of these specifications. > > The default is -fno-unsafe-math-optimizations. As far as I can read English, I do not see any mention of parentheses removal in this quotation. Note that (2), (3), and (4) are not incompatible, but in any case (4) is mandatory in my opinion if (1) is rejected. Now consider this other code: integer i, n real a, b n = 0 do i = 0, 999 a = 0.001*real(i) b = real(i)/1000.0 if ((a /= b) .and. (n == 0)) print *, a-b, spacing(a) if (a /= b) n = n + 1 end do print *, n end compiled with "-O", it yields: 4.6566129E-10 4.6566129E-10 584 'a' and 'b' are not equal, but differ only by the round-off error. Now compiled with "-O -funsafe-math-optimizations", it yields: 0 Though I did not look at the assembly code, I am pretty sure that the division by 1000.0 has been replaced by a multiplication by 1.0/1000.0 computed only once outside the loop. Since the division is a very costly operation this can give a significant speedup for some codes. In my opinion, this is a very useful optimization (should be included at some level of -O, say -O3) and pretty safe. Indeed one could argue that if I am really interested by this optimization, I can always do it by hand. My answer is that in general I use it in my codes, but sometime the code is easier to understand if the division is left where it belongs in the formulae and I don't see why I'd have to chase divisions when I use the code from a colleague. In addition if the argument is true for division, it is also for writing (a+f)-f if all what you want is a! To summarize I do not see the logic of the design of "-funsafe-math-optimizations": it mixes legitimate (and safe from a numerical point of view) optimization with illegitimate (in the sense that the code is no longer complying to the requirements of the programming language) ones. Final note (to document?): the division is optimized outside the loop with "-funsafe-math-optimizations", while the parentheses are not obeyed starting at "-O1 -funsafe-math-optimizations", but "-O0 -funsafe-math-optimizations" obeys the parentheses. -- Summary: Behavior of -ffast-math Product: gcc Version: 4.3.0 Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: other AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: dominiq at lps dot ens dot fr http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32172