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
` (6 more replies)
0 siblings, 7 replies; 8+ 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] 8+ 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
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ 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] 8+ 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
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ 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] 8+ 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
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ 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] 8+ 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
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ 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] 8+ 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
2024-06-17 10:03 ` mjr19 at cam dot ac.uk
2024-06-17 14:38 ` kargls at comcast dot net
6 siblings, 0 replies; 8+ 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] 8+ 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
` (4 preceding siblings ...)
2022-10-17 16:14 ` bartoldeman at users dot sourceforge.net
@ 2024-06-17 10:03 ` mjr19 at cam dot ac.uk
2024-06-17 14:38 ` kargls at comcast dot net
6 siblings, 0 replies; 8+ messages in thread
From: mjr19 at cam dot ac.uk @ 2024-06-17 10:03 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107294
mjr19 at cam dot ac.uk changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |mjr19 at cam dot ac.uk
--- Comment #5 from mjr19 at cam dot ac.uk ---
But 10.1.5.2.4 says "once the interpretation of a numeric intrinsic operation
is established, the processor may evaluate any mathematically equivalent
expression, provided that the integrity of parentheses is not violated."
As cmplx(r)*z and cmplx(r*real(z),r*aimag(z)) are mathematically equivalent, is
a Fortran compiler not permitted to make this optimisation (unless conforming
to F90 or F95, for 10.1.5.2.4 was first introduced in F2003)?
Furthermore, Fortran does not define how complex multiplication is to be
performed, so relying on the precise details result when multiplying signed
zeros or NaNs may be unwise.
^ permalink raw reply [flat|nested] 8+ 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
` (5 preceding siblings ...)
2024-06-17 10:03 ` mjr19 at cam dot ac.uk
@ 2024-06-17 14:38 ` kargls at comcast dot net
6 siblings, 0 replies; 8+ messages in thread
From: kargls at comcast dot net @ 2024-06-17 14:38 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107294
--- Comment #6 from kargls at comcast dot net ---
(In reply to mjr19 from comment #5)
> But 10.1.5.2.4 says "once the interpretation of a numeric intrinsic
> operation is established, the processor may evaluate any mathematically
> equivalent expression, provided that the integrity of parentheses is not
> violated."
>
> As cmplx(r)*z and cmplx(r*real(z),r*aimag(z)) are mathematically equivalent,
> is a Fortran compiler not permitted to make this optimisation (unless
> conforming to F90 or F95, for 10.1.5.2.4 was first introduced in F2003)?
>
> Furthermore, Fortran does not define how complex multiplication is to be
> performed, so relying on the precise details result when multiplying signed
> zeros or NaNs may be unwise.
See comment #3. Type conversion occurs.
If you want to get a possibly wrong answer fast, use either -Ofast or
-ffast-math.
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2024-06-17 14:38 UTC | newest]
Thread overview: 8+ 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
2024-06-17 10:03 ` mjr19 at cam dot ac.uk
2024-06-17 14:38 ` kargls at comcast dot 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).