[Bug middle-end/93806] Wrong optimization: instability of floating-point results with -funsafe-math-optimizations leads to nonsense
vincent-gcc at vinc17 dot net
gcc-bugzilla@gcc.gnu.org
Fri Feb 21 09:36:00 GMT 2020
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 rguenther@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.
More information about the Gcc-bugs
mailing list