public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug fortran/107294] New: Missed optimization: multiplying real with complex number in Fortran (only)
@ 2022-10-17 12:39 bartoldeman at users dot sourceforge.net
  2022-10-17 12:58 ` [Bug fortran/107294] " rguenth at gcc dot gnu.org
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: bartoldeman at users dot sourceforge.net @ 2022-10-17 12:39 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 107294
           Summary: Missed optimization: multiplying real with complex
                    number in Fortran (only)
           Product: gcc
           Version: 11.3.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: fortran
          Assignee: unassigned at gcc dot gnu.org
          Reporter: bartoldeman at users dot sourceforge.net
  Target Milestone: ---

This code:

complex function csmul(a, b)
  real, value :: a
  complex, value :: b
  csmul = a * b
end function csmul

produces this assembly on x86-64 (11.3, -O2)
   0:   66 0f d6 4c 24 f8       movq   %xmm1,-0x8(%rsp)
   6:   f3 0f 10 64 24 fc       movss  -0x4(%rsp),%xmm4
   c:   f3 0f 10 4c 24 f8       movss  -0x8(%rsp),%xmm1
  12:   0f 28 d0                movaps %xmm0,%xmm2
  15:   66 0f ef db             pxor   %xmm3,%xmm3 # xmm3 = 0
  19:   f3 0f 59 d1             mulss  %xmm1,%xmm2
  1d:   0f 28 ec                movaps %xmm4,%xmm5
  20:   f3 0f 59 eb             mulss  %xmm3,%xmm5 # xmm5 = 0
  24:   f3 0f 59 c4             mulss  %xmm4,%xmm0
  28:   f3 0f 59 cb             mulss  %xmm3,%xmm1 # xmm1 = 0
  2c:   f3 0f 5c d5             subss  %xmm5,%xmm2 # xmm2 unchanged
  30:   f3 0f 58 c1             addss  %xmm1,%xmm0 # xmm0 unchanged
  34:   f3 0f 11 54 24 f0       movss  %xmm2,-0x10(%rsp)
  3a:   f3 0f 11 44 24 f4       movss  %xmm0,-0xc(%rsp)
  40:   f3 0f 7e 44 24 f0       movq   -0x10(%rsp),%xmm0
  46:   c3                      retq    

here xmm3 (imaginary part of a, promoted to complex) is set to 0 but this is
not exploited in the remainder.

On the other hand the assembly for the corresponding C code looks good, with
two mul instructions, as expected:

float _Complex csmul(float a, float _Complex b)
{
  return a * b;
}

0000000000000000 <csmul>:
   0:   66 0f d6 4c 24 f8       movq   %xmm1,-0x8(%rsp)
   6:   f3 0f 10 4c 24 f8       movss  -0x8(%rsp),%xmm1
   c:   f3 0f 59 c8             mulss  %xmm0,%xmm1
  10:   f3 0f 59 44 24 fc       mulss  -0x4(%rsp),%xmm0
  16:   f3 0f 11 4c 24 f0       movss  %xmm1,-0x10(%rsp)
  1c:   f3 0f 11 44 24 f4       movss  %xmm0,-0xc(%rsp)
  22:   f3 0f 7e 44 24 f0       movq   -0x10(%rsp),%xmm0
  28:   c3                      retq   

The same issue is still present in trunk, according to godbolt.org.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug fortran/107294] Missed optimization: multiplying real with complex number in Fortran (only)
  2022-10-17 12:39 [Bug fortran/107294] New: Missed optimization: multiplying real with complex number in Fortran (only) bartoldeman at users dot sourceforge.net
@ 2022-10-17 12:58 ` rguenth at gcc dot gnu.org
  2022-10-17 13:02 ` rguenth at gcc dot gnu.org
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: rguenth at gcc dot gnu.org @ 2022-10-17 12:58 UTC (permalink / raw)
  To: gcc-bugs

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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
     Ever confirmed|0                           |1
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2022-10-17

--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> ---
The issue is that the fortran frontend produces

  complex(kind=4) __result_csmul;

  __result_csmul = COMPLEX_EXPR <a, 0.0> * b;
  return __result_csmul;

while the C frontend does

  return COMPLEX_EXPR <SAVE_EXPR <a> * REALPART_EXPR <SAVE_EXPR <b>>, SAVE_EXPR
<a> * IMAGPART_EXPR <SAVE_EXPR <b>>>;

the fortran IL then gets optimized to

  <bb 2> [local count: 1073741824]:
  b$real_6 = REALPART_EXPR <b_4(D)>;
  b$imag_7 = IMAGPART_EXPR <b_4(D)>;
  _8 = a_3(D) * b$real_6;
  _9 = b$imag_7 * 0.0;
  _10 = a_3(D) * b$imag_7;
  _11 = b$real_6 * 0.0;
  _12 = _8 - _9;
  _13 = _10 + _11;
  _2 = COMPLEX_EXPR <_12, _13>;
  return _2;

and here we have to stop because with singed zeros the multiply by zero
is ambiguous and the resulting sign important(?).  With -fno-signed-zeros
the optimization result is the same but really the C frontend
interprets scalar * complex multiplication differently here.

Not sure who is correct, or if both are and we can optimize the multiply
by zero here (maybe in the context of a - b * 0.0 and a + b * 0.0).

It looks like the C17 standard in the G.5.1 annex gives us leeway to
implement multiplication in the pre-simplified form we do.  Somebody
would have to check the Fortran standard how to treat this case.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug fortran/107294] Missed optimization: multiplying real with complex number in Fortran (only)
  2022-10-17 12:39 [Bug fortran/107294] New: Missed optimization: multiplying real with complex number in Fortran (only) bartoldeman at users dot sourceforge.net
  2022-10-17 12:58 ` [Bug fortran/107294] " rguenth at gcc dot gnu.org
@ 2022-10-17 13:02 ` rguenth at gcc dot gnu.org
  2022-10-17 15:14 ` kargl at gcc dot gnu.org
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: rguenth at gcc dot gnu.org @ 2022-10-17 13:02 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---
Oh, and of course 0 * NaN also isn't 0.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug fortran/107294] Missed optimization: multiplying real with complex number in Fortran (only)
  2022-10-17 12:39 [Bug fortran/107294] New: Missed optimization: multiplying real with complex number in Fortran (only) bartoldeman at users dot sourceforge.net
  2022-10-17 12:58 ` [Bug fortran/107294] " rguenth at gcc dot gnu.org
  2022-10-17 13:02 ` rguenth at gcc dot gnu.org
@ 2022-10-17 15:14 ` kargl at gcc dot gnu.org
  2022-10-17 16:13 ` bartoldeman at users dot sourceforge.net
  2022-10-17 16:14 ` bartoldeman at users dot sourceforge.net
  4 siblings, 0 replies; 6+ messages in thread
From: kargl at gcc dot gnu.org @ 2022-10-17 15:14 UTC (permalink / raw)
  To: gcc-bugs

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

kargl at gcc dot gnu.org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |kargl at gcc dot gnu.org

--- Comment #3 from kargl at gcc dot gnu.org ---
(In reply to Richard Biener from comment #1)

> Not sure who is correct, or if both are and we can optimize the multiply
> by zero here (maybe in the context of a - b * 0.0 and a + b * 0.0).

The Fortran behavior is specified in Fortran 2023 (22-007r1.pdf) in


  10.1.5.2.1 Interpretation of numeric intrinsic operations
  ...
  Except for a value of type real or complex raised to an integer power,
  if the operands have different types or kind type parameters, the
  effect is as if each operand that differs in type or kind type
  parameter from those of the result is converted to the type and kind
  type parameter of the result before the operation is performed.  When
  a value of type real or complex is raised to an integer power, the
  integer operand need not be converted.

So, 
  __result_csmul = COMPLEX_EXPR <a, 0.0> * b;

is correct.  There is a caveat.  The Fortran standard does not mandate
the sign of zero.  If one wants to ignore exceptional values (i.e.,
0 * NaN, 0 * +-inf ), then one could annotate 0.0 to be +0.  But, that
will lead to so seriously flawed computations.

This should probably be closed with WONTFIX.

PS: -ffast-math might produce the optimized assembly.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug fortran/107294] Missed optimization: multiplying real with complex number in Fortran (only)
  2022-10-17 12:39 [Bug fortran/107294] New: Missed optimization: multiplying real with complex number in Fortran (only) bartoldeman at users dot sourceforge.net
                   ` (2 preceding siblings ...)
  2022-10-17 15:14 ` kargl at gcc dot gnu.org
@ 2022-10-17 16:13 ` bartoldeman at users dot sourceforge.net
  2022-10-17 16:14 ` bartoldeman at users dot sourceforge.net
  4 siblings, 0 replies; 6+ messages in thread
From: bartoldeman at users dot sourceforge.net @ 2022-10-17 16:13 UTC (permalink / raw)
  To: gcc-bugs

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

bartoldeman at users dot sourceforge.net changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|---                         |FIXED

--- Comment #4 from bartoldeman at users dot sourceforge.net ---
Thanks for the explanation, finding an example with NaNs you get
0.0 * (NaN + 0.0i) = NaN + 0.0i
for C with annex G.5.1
but
NaN + NaN i
for Fortran, unless you specify -fno-signed-zeros.

program main
  use, intrinsic :: ieee_arithmetic, only: IEEE_Value, IEEE_QUIET_NAN
  use, intrinsic :: iso_fortran_env, only: real32

  real(real32) :: a, nan
  complex(real32) :: cnan

  nan = IEEE_VALUE(nan, IEEE_QUIET_NAN)
  cnan = cmplx(nan, 0.0)
  zero = 0.0
  print *, zero, cnan, zero * cnan
end

illustrates this
   0.00000000     (             NaN,  0.00000000    ) (             NaN,       
     NaN)
vs
   0.00000000     (             NaN,  0.00000000    ) (             NaN, 
0.00000000    )

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug fortran/107294] Missed optimization: multiplying real with complex number in Fortran (only)
  2022-10-17 12:39 [Bug fortran/107294] New: Missed optimization: multiplying real with complex number in Fortran (only) bartoldeman at users dot sourceforge.net
                   ` (3 preceding siblings ...)
  2022-10-17 16:13 ` bartoldeman at users dot sourceforge.net
@ 2022-10-17 16:14 ` bartoldeman at users dot sourceforge.net
  4 siblings, 0 replies; 6+ messages in thread
From: bartoldeman at users dot sourceforge.net @ 2022-10-17 16:14 UTC (permalink / raw)
  To: gcc-bugs

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

bartoldeman at users dot sourceforge.net changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|FIXED                       |WONTFIX

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-10-17 16:14 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-17 12:39 [Bug fortran/107294] New: Missed optimization: multiplying real with complex number in Fortran (only) bartoldeman at users dot sourceforge.net
2022-10-17 12:58 ` [Bug fortran/107294] " rguenth at gcc dot gnu.org
2022-10-17 13:02 ` rguenth at gcc dot gnu.org
2022-10-17 15:14 ` kargl at gcc dot gnu.org
2022-10-17 16:13 ` bartoldeman at users dot sourceforge.net
2022-10-17 16:14 ` bartoldeman at users dot sourceforge.net

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).