[tree-complex.c] PR tree-optimization/70291: Inline floating-point complex multiplica...
commit5977f2ba1943ed19ec746fa64fb3a9bb07a04abc
authorktkachov <ktkachov@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 3 May 2018 12:59:43 +0000 (3 12:59 +0000)
committerktkachov <ktkachov@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 3 May 2018 12:59:43 +0000 (3 12:59 +0000)
tree73a4a069ba83bba17e9149be02963239df4d3d2e
parente6303a09117cdea076261eb394ca7e35fd6526d7
[tree-complex.c] PR tree-optimization/70291: Inline floating-point complex multiplication more aggressively

We can improve the performance of complex floating-point multiplications by inlining the expansion a bit more aggressively.
We can inline complex x = a * b as:
x = (ar*br - ai*bi) + i(ar*bi + br*ai);
if (isunordered (__real__ x, __imag__ x))
  x = __muldc3 (a, b); //Or __mulsc3 for single-precision

That way the common case where no NaNs are produced we can avoid the libgcc call and fall back to the
NaN handling stuff in libgcc if either components of the expansion are NaN.

The implementation is done in expand_complex_multiplication in tree-complex.c and the above expansion
will be done when optimising for -O1 and greater and when not optimising for size.
At -O0 and -Os the single call to libgcc will be emitted.

For the code:
__complex double
foo (__complex double a, __complex double b)
{
  return a * b;
}

We will now emit at -O2 for aarch64:
foo:
        fmul    d16, d1, d3
        fmul    d6, d1, d2
        fnmsub  d5, d0, d2, d16
        fmadd   d4, d0, d3, d6
        fcmp    d5, d4
        bvs     .L8
        fmov    d1, d4
        fmov    d0, d5
        ret
.L8:
        stp     x29, x30, [sp, -16]!
        mov     x29, sp
        bl      __muldc3
        ldp     x29, x30, [sp], 16
        ret

Instead of just a branch to __muldc3.

PR tree-optimization/70291
* tree-complex.c (expand_complex_libcall): Add type, inplace_p
arguments.  Change return type to tree.  Emit libcall as a new
statement rather than replacing existing one when inplace_p is true.
(expand_complex_multiplication_components): New function.
(expand_complex_multiplication): Expand floating-point complex
multiplication using the above.
(expand_complex_division): Rename inner_type parameter to type.
Update expand_complex_libcall call-site.
(expand_complex_operations_1): Update expand_complex_multiplication
and expand_complex_division call-sites.

* gcc.dg/complex-6.c: New test.
* gcc.dg/complex-7.c: Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@259889 138bc75d-0d04-0410-961f-82ee72b054a4
gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/complex-6.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/complex-7.c [new file with mode: 0644]
gcc/tree-complex.c