https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93806
--- Comment #21 from rguenther at suse dot de <rguenther at suse dot de> --- On Fri, 21 Feb 2020, vincent-gcc at vinc17 dot net wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93806 > > --- Comment #20 from Vincent Lefèvre <vincent-gcc at vinc17 dot net> --- > (In reply to rguent...@suse.de from comment #18) > > GCC indeed happily evaluates a floating-point expression multiple times, > > for example for > > > > void foo(float a, float b, float *x, float *y) > > { > > float tem = a + b; > > *x = tem - a; > > *y = tem - b; > > } > > > > I would expect GCC to turn this into > > > > *x = (a + b) - a; > > *y = (a + b) - b; > > > > and then simplify further to b and a. Does this violate the "as-if rule"? > > I think that if optimization goes beyond expressions, this is unexpected, thus > violate the "as-if rule". Assignments should be regarded as barriers. Perhaps > casts too. > > Now, if you disregard Annex F entirely and assume that the operations may be > inaccurate (e.g. due to the optimizer), then in foo(), *x can be any value and > *y can be any value, so that the simplification of *x to b and *y to a would > be > valid (as long as GCC assumes that their values are stable, i.e. that it will > not "recompute" a same unmodified variable multiple times). But IMHO, this > kind > of aggressive optimization is not helpful to the user. > > BTW, I fear that due to FP contraction, GCC might be broken even without > "unsafe" optimizations. For instance, consider: > > double a, b, c, r, s, t; > /* ... */ > r = a * b + c; > s = a * b; > t = s + c; > > possibly slightly modified, without changing the semantics and still allowing > FP contraction for r (I mean that things like "opaque" and volatile could be > introduced in the code to change how optimization is done). > > Here, if FP contraction is allowed, the compiler may replace a * b + c by > fma(a,b,c), i.e. compute r with a single rounding instead of two, so that r > and > t may have different values. My question is the following: Due to the fact > that > r and t are computed with the same Level-1 expression a * b + c (i.e. at the > level of real numbers, without rounding), is it possible that GCC's optimizer > regard r and t as equal, even though they may actually be different? If this > is > possible, this would be a bug. Yes, GCCs value-numbering would compute them equal but then it would also replace one with the other. So one would need a quite more contrived example where the value-numbering results in a second order observable difference (hah, compiler side-channel attack!). Note that FP contraction happens quite late after value-numbering has the chance to declare both of the above equal. value-numbering does not, however, consider fma (a, b, c) and a * b + c as equal. The issue here is I think requiring "consistent optimization" for correctness so that in some cases a missed-optimization becomes wrong-code :/ Note that GCC does FP contraction across stmt boundaries so even s = a * b; t = s + c; is contracted. If that is already a bug in your eyes then of couse value-numbering replacing t by r is already a bug.