[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
Wed Feb 19 13:33:00 GMT 2020
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93806
--- Comment #7 from Vincent Lefèvre <vincent-gcc at vinc17 dot net> ---
(In reply to rguenther@suse.de from comment #5)
> From below I implicitely assume you say that "1. + x != 1." -> "x != 0."
> isn't "rearranging at the source level".
No, it depends on how you do that. If in the source you have
int c = 1. + x != 1.;
then you might choose to transform this to
int c = x != 0.;
under -funsafe-math-optimizations (though this transformation is currently not
documented, see below). What the optimizer MUST NOT do is to replace an
occurrence of c in the code by the expression used to compute it, as doing such
a thing is likely to yield major inconsistencies (this might be acceptable if
the value of c is read only once, but IMHO, even this case should not be
optimized as this could be too dangerous).
> Note our documentation
> on -funsafe-math-optimizations is quite vague and I'd argue that
> "rearranging at the source level" is covered by -fassociative-math
> instead.
BTW, strictly speaking, transforming "1. + x != 1." to "x != 0." does not just
use the associativity, but also the "additive property" or "cancellation
property". In math, if "a = b", then "a + x = b + x". However, for an arbitrary
operation, the converse is not necessarily true, even though the operation may
be associative. That is, if "a != b", then "a + x != b + x" is not necessarily
true. Having the cancellation property under -funsafe-math-optimizations might
be OK (here, this is similar to assuming associativity, but possibly stronger,
so that it could be preferable to have a separate option for that).
But I think that this is not directly related to this bug.
The gcc(1) man page says:
-fassociative-math
Allow re-association of operands in series of floating-point
operations. [...]
As I read it, this is possible only inside an expression, otherwise it should
not be worded like that. What the optimizer does here is to apply
re-association of operands beyond expressions, changing the allowed behaviors
to an unexpected one; thus, IMHO, the "as-if rule" is broken by the optimizer
here.
> It's not clear how to classify the above specific transform though.
> There's -ffp-contract which also enables removing of rounding steps.
> So the classification as "unsafe" is probably correct (and vague).
Note that the conditions under FP contraction are rather strict. A consequence
of what -funsafe-math-optimizations can do is to increase the error of the
considered expression, which is not allowed by FP contraction.
More information about the Gcc-bugs
mailing list