Complex arithmetic in Fortran

Toon Moene toon@moene.org
Wed Nov 13 14:55:39 GMT 2024


On 11/13/24 15:40, Richard Biener wrote:
> On Wed, Nov 13, 2024 at 3:21 PM Toon Moene <toon@moene.org> wrote:
>>
>> On 11/13/24 15:12, Richard Biener wrote:
>>
>>> On Wed, Nov 13, 2024 at 3:05 PM Thomas Koenig <tkoenig@netcologne.de> wrote:
>>>>
>>>> Hello world,
>>>>
>>>> J3, the US Fortran standards committee, has passed
>>>> https://j3-fortran.org/doc/year/24/24-179.txt
>>>> which states (with a bit of an overabundance of
>>>> clarity) that, in Fortran, it is possible special-case
>>>> complex multiplication when one of the numbers is known
>>>> to have a zero component, for example when promoting
>>>> a real to complex for complex multiplication.  For
>>>> example, multiplying a complex variable b with a real
>>>> variable a can be done with c%re = b%re * a, c%im = b%im * a,
>>>> without considering NaNs and infinities. Apparently, other
>>>> Fortran compilers do this.
>>>>
>>>> They also stated that ISO/IEC 60559:2020 (aka IEEE 754) does
>>>> not specify complex arithmetic (I wouldn't know, because it is a
>>>> paywalled standard).
>>>>
>>>> How do we want to deal with this? Do we want to implement this
>>>> (it's an obvious speed advantage)?  Should it be the default?
>>>> Do we want to include this in -fcx-fortran-rules?
>>>
>>> The middle-end complex lowering pass does this already, irrespective
>>> of NaNs, same for some degenerate cases with division.
>>
>> Are you sure ?
>>
>> For this code:
>>
>> $ cat complex.f90
>> complex function p(c, r)
>> complex, intent(in) :: c
>> real, intent(in)    :: r
>> p = c * r
>> end
>>
>> I definitely see a difference between
>>
>> $ gfortran -O2 -S complex.f90
>>
>> and
>>
>> $ gfortran -O2 -ffast-math -S complex.f90
> 
> Ah.  This is because of
> 
> static int
> some_nonzerop (tree t)
> {
>    int zerop = false;
> 
>    /* Operations with real or imaginary part of a complex number zero
>       cannot be treated the same as operations with a real or imaginary
>       operand if we care about the signs of zeros in the result.  */
>    if (TREE_CODE (t) == REAL_CST && !flag_signed_zeros)
>      zerop = real_identical (&TREE_REAL_CST (t), &dconst0);
> 
> so the -ffast-math result can be obtained with just -fno-signed-zeros (I assumed
> fortran doesn't have signed zeros?)

Since the Fortran 95 Standard it does (in the current Standard: 7.4.3.2 
Real type):

The real type includes a zero value. Processors that distinguish between 
positive and negative zeros shall treat them as mathematically equivalent
• in all intrinsic relational operations, and
• as actual arguments to intrinsic procedures other than those for which
   it is explicitly specified that negative zero is distinguished.

[Note that "processor" in Fortran standardese means everything 
(combined) from the compiler down to the actual hardware].

So we have to comb through the Standard to see where bullet 2 applies ...

Kind regards,

-- 
Toon Moene - e-mail: toon@moene.org - phone: +31 346 214290
Saturnushof 14, 3738 XG  Maartensdijk, The Netherlands


More information about the Gcc mailing list