See the following code:

#include <complex>
using std::complex;

template<typename _Tp, typename _Up>
complex<_Tp>&
mult_assign (complex<_Tp>& __y, const complex<_Up>& __z)
{
  _Up& _M_real = __y.real();
  _Up& _M_imag = __y.imag();
  const _Tp __r = _M_real * __z.real() - _M_imag * __z.imag();
  _M_imag = _M_real * __z.imag() + _M_imag * __z.real();
  _M_real = __r;
  return __y;
}

void foo (complex<float>& c1, complex<float>& c2)
{ c1 *= c2; }

void bar (complex<float>& c1, complex<float>& c2)
{ mult_assign(c1, c2); }


The function mult_assign is written almost by copying the
implementation of operator *= from <complex>. They have exactly the
same behavior from the view of the source code. However, the compiled
results of foo() and bar() are different: foo() is using builtin
function for multiplication but bar() is not. Just because of a name
change the final behavior is changed? This should not be how a
compiler is working.


thanks,
Cong


On Thu, Nov 14, 2013 at 10:17 AM, Andrew Pinski <pins...@gmail.com> wrote:
> On Thu, Nov 14, 2013 at 8:25 AM, Xinliang David Li <davi...@google.com> wrote:
>> Can we revisit the decision for this? Here are the reasons:
>>
>> 1) It seems that the motivation to make C++ consistent with c99 is to
>> avoid confusing users who build the C source with both C and C++
>> compilers. Why should C++'s default behavior be tuned for this niche
>> case?
>
> It is not a niche case.  It is confusing for people who write C++ code
> to rewrite their code to C99 and find that C is much slower because of
> correctness?  I think they have this backwards here.  C++ should be
> consistent with C here.
>
>> 2) It is very confusing for users who see huge performance difference
>> between compiler generated code for Complex multiplication vs manually
>> expanded code
>
> I don't see why this is an issue if they understand how complex
> multiplication works for correctness.  I am sorry but correctness over
> speed is a good argument of why this should stay this way.
>
>> 3) The default setting can also block potential vectorization
>> opportunities for complex operations
>
> Yes so again this is about a correctness issue over a speed issue.
>
>> 4) GCC is about the only compiler which has this default -- very few
>> user knows about GCC's strict default, and will think GCC performs
>> poorly.
>
>
> Correctness over speed is better.  I am sorry GCC is the only one
> which gets it correct here.  If people don't like there is a flag to
> disable it.
>
> Thanks,
> Andrew Pinski
>
>>
>> thanks,
>>
>> David
>>
>>
>> On Wed, Nov 13, 2013 at 9:07 PM, Andrew Pinski <pins...@gmail.com> wrote:
>>> On Wed, Nov 13, 2013 at 5:26 PM, Cong Hou <co...@google.com> wrote:
>>>> This patch is for PR58963.
>>>>
>>>> In the patch http://gcc.gnu.org/ml/gcc-patches/2005-02/msg00560.html,
>>>> the builtin function is used to perform complex multiplication and
>>>> division. This is to comply with C99 standard, but I am wondering if
>>>> C++ also needs this.
>>>>
>>>> There is no complex keyword in C++, and no content in C++ standard
>>>> about the behavior of operations on complex types. The <complex>
>>>> header file is all written in source code, including complex
>>>> multiplication and division. GCC should not do too much for them by
>>>> using builtin calls by default (although we can set -fcx-limited-range
>>>> to prevent GCC doing this), which has a big impact on performance
>>>> (there may exist vectorization opportunities).
>>>>
>>>> In this patch flag_complex_method will not be set to 2 for C++.
>>>> Bootstraped and tested on an x86-64 machine.
>>>
>>> I think you need to look into this issue deeper as the original patch
>>> only enabled it for C99:
>>> http://gcc.gnu.org/ml/gcc-patches/2005-02/msg01483.html .
>>>
>>> Just a little deeper will find
>>> http://gcc.gnu.org/ml/gcc/2007-07/msg00124.html which says yes C++
>>> needs this.
>>>
>>> Thanks,
>>> Andrew Pinski
>>>
>>>>
>>>>
>>>> thanks,
>>>> Cong
>>>>
>>>>
>>>> Index: gcc/c-family/c-opts.c
>>>> ===================================================================
>>>> --- gcc/c-family/c-opts.c (revision 204712)
>>>> +++ gcc/c-family/c-opts.c (working copy)
>>>> @@ -198,8 +198,10 @@ c_common_init_options_struct (struct gcc
>>>>    opts->x_warn_write_strings = c_dialect_cxx ();
>>>>    opts->x_flag_warn_unused_result = true;
>>>>
>>>> -  /* By default, C99-like requirements for complex multiply and divide.  
>>>> */
>>>> -  opts->x_flag_complex_method = 2;
>>>> +  /* By default, C99-like requirements for complex multiply and divide.
>>>> +     But for C++ this should not be required.  */
>>>> +  if (c_language != clk_cxx && c_language != clk_objcxx)
>>>> +    opts->x_flag_complex_method = 2;
>>>>  }
>>>>
>>>>  /* Common initialization before calling option handlers.  */
>>>> Index: gcc/c-family/ChangeLog
>>>> ===================================================================
>>>> --- gcc/c-family/ChangeLog (revision 204712)
>>>> +++ gcc/c-family/ChangeLog (working copy)
>>>> @@ -1,3 +1,8 @@
>>>> +2013-11-13  Cong Hou  <co...@google.com>
>>>> +
>>>> + * c-opts.c (c_common_init_options_struct): Don't let C++ comply with
>>>> + C99-like requirements for complex multiply and divide.
>>>> +
>>>>  2013-11-12  Joseph Myers  <jos...@codesourcery.com>
>>>>
>>>>   * c-common.c (c_common_reswords): Add _Thread_local.

Reply via email to