https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93806

--- Comment #35 from Vincent Lefèvre <vincent-gcc at vinc17 dot net> ---
(In reply to Alexander Cherepanov from comment #34)
> (In reply to Vincent Lefèvre from comment #13)
> > In C without Annex F, division by 0 is undefined behavior (really undefined
> > behavior, not an unspecified result, which would be very different).
> > 
> > With the examples using divisions by 0, you need to assume that Annex F
> > applies, but at the same time, with your interpretation, -fno-signed-zeros
> > breaks Annex F in some cases, e.g. if you have floating-point divisions by
> > 0. So I don't follow you...
> 
> You seem to say that either Annex F is fully there or not at all but why?
> -fno-signed-zeros breaks Annex F but only parts of it. Isn't it possible to
> retain the other parts of it? Maybe it's impossible or maybe it's impossible
> to retain division by zero, I don't know. What is your logic here?

This issue is that the nice property x == y implies f(x) == f(y), in
particular, x == y implies 1 / x == 1 / y is no longer valid with signed zeros.
Thus one intent of -fno-signed-zeros could be to enable optimizations based on
this property. But this means that division by zero becomes undefined behavior
(like in C without Annex F). Major parts of Annex F would still remain valid.

> (In reply to Vincent Lefèvre from comment #15)
> > Note that there are very few ways to be able to distinguish the sign of
> > zero. The main one is division by zero. Other ones are:
> > 
> > * Conversion to a character string, e.g. via printf(). But in this case, if
> > -fno-signed-zeros is used, whether "0" or "-0" is output (even in a way that
> > seems to be inconsistent) doesn't matter since the user does not care about
> > the sign of 0, i.e. "0" and "-0" are regarded as equivalent (IIRC, this
> > would be a bit like NaN, which has a sign bit in IEEE 754, but the output
> > does not need to match its sign bit).
> 
> This means that you cannot implement you own printf: if you analyze sign bit
> of your value to decide whether you need to print '-', the sign of zero is
> significant in your code.

If you want to implement a printf that takes care of the sign of 0, you must
not use -fno-signed-zeros.

> IOW why do you think that printf is fine while "1 / x == 1 / 0." is not?

printf is not supposed to trigger undefined behavior. Part of its output is
unspecified, but that's all.

> > * Memory analysis. Again, the sign does not matter, but for instance,
> > reading an object twice as a byte sequence while the object has not been
> > changed by the code must give the same result. I doubt that this is affected
> > by optimization.
> 
> Working with objects on byte level is often optimized too:

Indeed, there could be invalid optimization... But I would have thought that in
such a case, the same kind of issue could also occur without -fno-signed-zeros.
Indeed, if x == y, then this does not mean that x and y have the same memory
representation. Where does -fno-signed-zeros introduce a difference?

Note: There's also the case of IEEE 754 decimal floating-point formats (such as
_Decimal64), for instance, due to the "cohorts", where two identical values can
have different memory representations. Is GCC always correct here?

Reply via email to