public inbox for fortran@gcc.gnu.org
 help / color / mirror / Atom feed
From: Tobias Burnus <tobias@codesourcery.com>
To: Segher Boessenkool <segher@kernel.crashing.org>
Cc: gcc-patches <gcc-patches@gcc.gnu.org>,
	fortran <fortran@gcc.gnu.org>, David Edelsohn <dje.gcc@gmail.com>,
	Harald Anlauf <anlauf@gmx.de>
Subject: Re: [Patch] Testsuite/Fortran: gfortran.dg/pr96711.f90 - fix expected value for PowerPC [PR96983]
Date: Wed, 19 May 2021 20:35:26 +0200	[thread overview]
Message-ID: <e01eea30-7d1e-3c39-73f6-7894cc00a20a@codesourcery.com> (raw)
In-Reply-To: <20210519151558.GK10366@gate.crashing.org>

[-- Attachment #1: Type: text/plain, Size: 2859 bytes --]

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

[-- Attachment #2: fix-pr96711-v2.diff --]
[-- Type: text/x-patch, Size: 1722 bytes --]

Testsuite/Fortran: gfortran.dg/pr96711.f90 - fix expected value for PowerPC [PR96983]

gcc/testsuite/ChangeLog:

	PR fortran/96983
	* gfortran.dg/pr96711.f90: Use 2**digit(x) instead of a hard-coded value;
	add comments regarding what the code does.

diff --git a/gcc/testsuite/gfortran.dg/pr96711.f90 b/gcc/testsuite/gfortran.dg/pr96711.f90
index 3761a8ea416..ab7707d0120 100644
--- a/gcc/testsuite/gfortran.dg/pr96711.f90
+++ b/gcc/testsuite/gfortran.dg/pr96711.f90
@@ -1,28 +1,30 @@
 ! { dg-do run }
 ! { dg-require-effective-target fortran_integer_16 }
 ! { dg-require-effective-target fortran_real_16 }
 ! { dg-additional-options "-fdump-tree-original" }
 ! { dg-final { scan-tree-dump-times "_gfortran_stop_numeric" 2 "original" } }
 !
 ! PR fortran/96711 - ICE on NINT() Function
 
 program p
   implicit none
   real(8)                :: x
   real(16)               :: y
+  ! Assume radix(x) == 2
+  ! 2/epsilon(x) = 2/(radix(x)**(1-digits(x)) = 2**digits(x) with that assumption
   integer(16), parameter :: k1 = nint (2 / epsilon (x), kind(k1))
   integer(16), parameter :: k2 = nint (2 / epsilon (y), kind(k2))
-  integer(16), parameter :: m1 = 9007199254740992_16                    !2**53
-  integer(16), parameter :: m2 = 10384593717069655257060992658440192_16 !2**113
+  integer(16), parameter :: m1 = 2_16**digits(x) ! Usually 2**53
+  integer(16), parameter :: m2 = 2_16**digits(y) ! Might be 2**113 or 2**106 or ... depending on the system
   integer(16), volatile  :: m
   x = 2 / epsilon (x)
   y = 2 / epsilon (y)
   m = nint (x, kind(m))
 ! print *, m
   if (k1 /= m1) stop 1
   if (m  /= m1) stop 2
   m = nint (y, kind(m))
 ! print *, m
   if (k2 /= m2) stop 3
   if (m  /= m2) stop 4
 end program

  reply	other threads:[~2021-05-19 18:35 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-19 12:32 Tobias Burnus
2021-05-19 15:15 ` Segher Boessenkool
2021-05-19 18:35   ` Tobias Burnus [this message]
2021-05-19 20:39     ` Bernhard Reutner-Fischer
2021-05-19 21:30       ` Bernhard Reutner-Fischer
2021-05-19 21:41       ` Tobias Burnus
2021-05-19 23:54     ` Segher Boessenkool
2021-05-20  6:57 ` Aw: " Harald Anlauf

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=e01eea30-7d1e-3c39-73f6-7894cc00a20a@codesourcery.com \
    --to=tobias@codesourcery.com \
    --cc=anlauf@gmx.de \
    --cc=dje.gcc@gmail.com \
    --cc=fortran@gcc.gnu.org \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=segher@kernel.crashing.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).