[Patch] Testsuite/Fortran: gfortran.dg/pr96711.f90 - fix expected value for PowerPC [PR96983]
Tobias Burnus
tobias@codesourcery.com
Wed May 19 18:35:26 GMT 2021
Hi Segher,
Quick version: Jump to the new patch, which I like much more.
Longer version:
On 19.05.21 17:15, Segher Boessenkool wrote:
>> real(16) :: y ! 128bit REAL
>> integer(16), parameter :: k2 = nint (2 / epsilon (y), kind(k2))
>> integer(16), parameter :: m2 = 10384593717069655257060992658440192_16
>> !2**113
>> if (k2 /= m2) stop 3
>>
>> On x86_64-linux-gnu, k2 == m2 — but on powerpc64le-linux-gnu,
>> k2 == 2**106 instead of 2**113.
>>
>> My solution is to permit also 2**106 besides 2**113.
> I do not understand Fortran well enough, could you explain what the code
> is supposed to do?
First, 2_16 means the integer '2' of the integer kind '16', i.e. int128_t type.
The original bug report (PR96983) was that 'nint'
with the 16byte floating point/quad-precision was giving an ICE
and the complaint was that there was no testcase for the value.
And I think this testcase tries to ensure that the result of 'nint'
both at compile time and at runtime matches what should be the result.
(Quotes from the Fortran standard, augumenty by what the source code does.)
'nint' does "__builtin_round" is available: "The result is the integer
nearest A, or if there are two integers equally near A, the result
is whichever such integer has the greater magnitude" – and in this
testcase, the argument is a quad-precision/16byte/128bit floating-point
number and the result is a 128bit integer.
('a**b' is the Fortran syntax for: 'a' raised to the power of 'b'.)
This testcase does:
nint(2/epsilon(y)). Here, 'epsilon' is the
"Model number that is small compared to 1."
Namely: b**(p-1) = '(radix)**(1-digits)'
alias 'real_format *fmt = REAL_MODE_FORMAT (mode)'
with radix = fmt->b and digits = fmt->p;
[b**(p-1) is from the Fortran standard but 'b' and 'p' also match the
ME/target names, while radix/digits matches the FE names and also the
Fortran intrinsic inquiry function names.]
This is for radix = 2 equivalent to:
2/2**(1-digits) = 2*2**(digits-1) = 2**(digits)
On x86-64, digits == fmt->p == 113.
Our powerpc64le gives digits == 106.
* * *
Having written all this, I wonder why we don't just
rely on the assumption that '2**digit(x)' works – and use this
to generate the valid.
Namely, as the attached updated patch does.
As I like that patch and believe it is obvious, I intent to
commit it as such – unless there are further comments.
It passes on both x86-64-gnu-linux and powerpc64le-none-linux-gnu.
I think the radix == 2 is a good bet, but if we ever run into issues,
it can also be changed to use radix(...) as well ...
Tobias
-----------------
Mentor Graphics (Deutschland) GmbH, Arnulfstrasse 201, 80634 München Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Frank Thürauf
-------------- next part --------------
A non-text attachment was scrubbed...
Name: fix-pr96711-v2.diff
Type: text/x-patch
Size: 1722 bytes
Desc: not available
URL: <https://gcc.gnu.org/pipermail/fortran/attachments/20210519/87e25478/attachment.bin>
More information about the Fortran
mailing list