This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Fix complex arithmetic and signed zeros

On Thu, May 7, 2009 at 11:27 AM, Joseph S. Myers
<> 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 ?<>
> ? ? ? ?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:


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]