Fix complex arithmetic and signed zeros
H.J. Lu
hjl.tools@gmail.com
Sat Jan 1 23:01:00 GMT 2011
On Thu, May 7, 2009 at 11:27 AM, Joseph S. Myers
<joseph@codesourcery.com> wrote:
> This patch implements the C99 requirements that arithmetic between one
> real and one complex operand does not convert the real operand to a
> complex type. This avoids excess operations on zero values in such
> cases, which are inefficient and can lead to the wrong sign of zero in
> the result (recall that positive and negative zero add to positive
> zero in all rounding modes except towards negative infinity). There
> appear to be no specific requirements regarding the result of
> real/complex division that make converting both operands to a common
> complex type there wrong, and that case might also need a new libgcc
> function or other special handling to avoid the conversion, so nothing
> is done about that case.
>
> There is some code in tree-complex.c that tries to optimize complex
> arithmetic with one operand real or imaginary, but if there are two
> complex operands then that is different from the case of one real and
> one complex operand because of the handling of signed zeros. Thus
> this must be disabled if flag_signed_zeros to get the correct
> semantics.
>
> Note that the absence of imaginary types means that expressions of the
> form (a + b * I) may still yield unwanted results in some cases
> because of b * I being b * (0.0 + 1.0i). As far as I know this
> (signed zeros in complex numbers) is the only use of imaginary types,
> and they are not a generally implemented feature of C99 (Annex G is an
> informative Annex, not normative; the Power ABI working group did not
> find any sign of compilers for Power Architecture that implemented
> these types). So I do not propose to change anything regarding their
> unimplemented state in GCC.
>
> I believe the only piece needed after this patch to make complex
> numbers support Done in c99status.html is fixing complex arithmetic
> folding (PR 30789), likely using MPC.
>
> Bootstrapped with no regressions on x86_64-unknown-linux-gnu. OK to
> commit (the tree-complex.c part)?
>
> The C front-end code checks flag_signed_zeros because it appears the
> language-independent compiler is better with -fno-signed-zeros at
> optimizing the complex arithmetic than at optimizing the accurately
> represented real/complex arithmetic. Without that check,
> gcc.dg/builtins-20.c, gcc.dg/builtins-54.c and gcc.dg/pr30172-1.c fail
> (the last is checking an early GIMPLE dump before most optimizations,
> but the first two do suggest a real problem). The complicated ENCODE
> code in the testcases is because if you initialize both halves of a
> complex number using __real__ and __imag__ assignments (the simplest
> way of putting known values, including signed zeros, in both halves),
> the compiler hasn't worked out that the complex number has a constant
> value by the time it gets to lowering complex arithmetic, so tests
> using __real__ and __imag__ assignments wouldn't detect the
> problematic transformations for complex numbers with one part zero.
>
> 2009-05-07 Joseph Myers <joseph@codesourcery.com>
>
> PR c/24581
> * c-typeck.c (build_binary_op): Handle arithmetic between one real
> and one complex operand specially.
> * tree-complex.c (some_nonzerop): Do not identify a real value as
> zero if flag_signed_zeros.
>
This caused:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47150
H.J.
More information about the Gcc-patches
mailing list