[Patch] Fortran: Fixes to OpenMP 'interop' directive parsing support

2024-09-12 Thread Tobias Burnus
This patch fixes a couple of issues, like a missing white-space gobbling 
after matching an expression.


It also reorganizes some code to handle 'identifier_"string"' vs. 
'identifier' better as there were some diagnostic issues.


(OpenMP requires for 'fr' that the argument is either an identifier 
(that is a scalar integer parameter) or a string; while for the older 
syntax, it can be any constant integer expression.)


However, the two main changes are:

* 'fr' and 'attr' actually support a list of arguments. While I believe 
'attr("x", "y") and "attr("x"),attr("y")' are semantically identically, 
supporting more than one (or zero) values for 'fr' required a different 
encoding.


* Jakub additionally suggested that for 'fr', which supports constant 
integers and string literals, we could pass on integer values – and do 
some checking.


That's what this patch does: Known string values are converted to their 
associated integer values, others to 0. And if the integer/string value 
is unknown, a warning is printed [-Wopenmp].


Known values are those in the "OpenMP API Additional Definitions" 
document, https://www.openmp.org/specifications/ – with the addition of 
hsa / 7, which has been voted at spec level (no idea about ARB level) 
but not yet published.


Note that that's the warning is based on what is defined there, i.e. 
'level_zero' there is no warning, even though GCC does not support it. 
Obviously, if will add another value next year, GCC 15 will not support 
it and warn, even if the code is perfectly valid. — But I guess we can 
live with a warning in that case.


Comments, remarks, suggestions? — Especially regarding the internal 
representation?


Tobias

PS: Next step will be to get the C/C++ parsing working, which also 
implies encoding this representation into 'tree'. (Then doing the tree 
conversion for Fortran.) Once satisfied with that, the middle end + 
libgomp part that links those bits will come next. And the question 
whether there should be one call per 'interop' directive or might be 
multiple (e.g. one per interop object in 'init'/'use'/'destroy').
Fortran: Fixes to OpenMP 'interop' directive parsing support

Handle lists as argument to 'fr' and 'attr'; fix parsing corner cases.
Additionally, 'fr' values are now internally stored as integer, permitting
the diagnoses (warning) for values not defined in the OpenMP additional
definitions document.

	PR fortran/116661

gcc/fortran/ChangeLog:

	* gfortran.h (gfc_omp_namelist): Rename 'init' members for clarity.
	* match.cc (gfc_free_omp_namelist): Handle renaming.
	* dump-parse-tree.cc (show_omp_namelist): Update for new format
	and features.
	* openmp.cc (gfc_match_omp_prefer_type): Parse list to 'fr' and 'attr';
	store 'fr' values as integer.
	(gfc_match_omp_init): Rename variable names.

gcc/ChangeLog:

	* omp-api.h (omp_get_fr_id_from_name, omp_get_name_from_fr_id): New
	prototypes.
	* omp-general.cc (omp_get_fr_id_from_name, omp_get_name_from_fr_id):
	New.

include/ChangeLog:

	* gomp-constants.h (GOMP_INTEROP_IFR_LAST,
	GOMP_INTEROP_IFR_SEPARATOR, GOMP_INTEROP_IFR_NONE): New.

gcc/testsuite/ChangeLog:

	* gfortran.dg/gomp/interop-1.f90: Extend, update dg-*.
	* gfortran.dg/gomp/interop-2.f90: Update dg-error.
	* gfortran.dg/gomp/interop-3.f90: Add dg-warning.

 gcc/fortran/dump-parse-tree.cc   |  84 +---
 gcc/fortran/gfortran.h   |   4 +-
 gcc/fortran/match.cc |  10 +-
 gcc/fortran/openmp.cc| 305 ---
 gcc/omp-api.h|   3 +
 gcc/omp-general.cc   |  29 +++
 gcc/testsuite/gfortran.dg/gomp/interop-1.f90 |  32 ++-
 gcc/testsuite/gfortran.dg/gomp/interop-2.f90 |   2 +-
 gcc/testsuite/gfortran.dg/gomp/interop-3.f90 |   2 +-
 include/gomp-constants.h |   5 +
 10 files changed, 314 insertions(+), 162 deletions(-)

diff --git a/gcc/fortran/dump-parse-tree.cc b/gcc/fortran/dump-parse-tree.cc
index 8fc6141611c..3547d7f8aca 100644
--- a/gcc/fortran/dump-parse-tree.cc
+++ b/gcc/fortran/dump-parse-tree.cc
@@ -37,6 +37,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "constructor.h"
 #include "version.h"
 #include "parse.h"  /* For gfc_ascii_statement.  */
+#include "omp-api.h"  /* For omp_get_name_from_fr_id.  */
+#include "gomp-constants.h"  /* For GOMP_INTEROP_IFR_SEPARATOR.  */
 
 /* Keep track of indentation for symbol tree dumps.  */
 static int show_level = 0;
@@ -1537,35 +1539,69 @@ show_omp_namelist (int list_type, gfc_omp_namelist *n)
 	}
   else if (list_type == OMP_LIST_INIT)
 	{
-	  int i = 0;
 	  if (n->u.init.target)
 	fputs ("target,", dumpfile);
 	  if (n->u.init.targetsync)
 	fputs ("targetsync,", dumpfile);
-	  char *prefer_type = n->u.init.str;
-	  if (n->u.init.len)
-	fputs ("prefer_type(", dumpfile);
-	  if (n->u.init.len)
-	while (*prefer_type)
-	  {
-		fputc ('{', dumpfile);
-		if (n->u2.interop_int

[patch, fortran, committed] module support for UNSIGNED

2024-09-12 Thread Thomas Koenig

Hello world,

I just pushed Steve's patch for module support to trunk as obvious, as
https://gcc.gnu.org/g:2847a541c1f19b67ae84be8d0f6dc8e1f9371d16 .

Best regards

Thomas

gcc/fortran/ChangeLog:

* module.cc (bt_types): Add BT_UNSIGNED.

gcc/testsuite/ChangeLog:

* gfortran.dg/unsigned_kiss.f90: New test.

diff --git a/gcc/fortran/module.cc b/gcc/fortran/module.cc
index c565b84d61b..8cf58ff5142 100644
--- a/gcc/fortran/module.cc
+++ b/gcc/fortran/module.cc
@@ -2781,6 +2781,7 @@ static const mstring bt_types[] = {
 minit ("UNKNOWN", BT_UNKNOWN),
 minit ("VOID", BT_VOID),
 minit ("ASSUMED", BT_ASSUMED),
+minit ("UNSIGNED", BT_UNSIGNED),
 minit (NULL, -1)
 };

diff --git a/gcc/testsuite/gfortran.dg/unsigned_kiss.f90 
b/gcc/testsuite/gfortran.dg/unsigned_kiss.f90

new file mode 100644
index 000..46ee86ccd26
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/unsigned_kiss.f90
@@ -0,0 +1,100 @@
+!
+! { dg-do run }
+! { dg-options "-funsigned" }
+!
+! Modern Fortran rewrite of Marsaglia's 64-bit KISS PRNG.
+! https://www.thecodingforums.com/threads/64-bit-kiss-rngs.673657/
+!
+module kissm
+
+   implicit none
+   private
+   public uk, kseed, kiss
+
+   integer, parameter :: uk = kind(1u_8)  ! Check kind() works.
+
+   ! Default seeds.  Checks unsigned with parameter attribute.
+   unsigned(uk), parameter :: seed(4) = [ &
+   &  1234567890987654321u_uk, 362436362436362436u_uk, &
+   &  1066149217761810u_uk, 123456123456123456u_uk ]
+
+   ! Seeds used during generation
+   unsigned(uk), save :: sd(4) = seed
+
+   contains
+
+  ! Tests unsigned in an internal function.
+  function s(x)
+ unsigned(uk) s
+ unsigned(uk), intent(in) :: x
+ s = ishft(x, -63)! Tests ishft
+  end function
+
+  ! Poor seeding routine.  Need to check v for entropy!
+  ! Tests intent(in) and optional attributes.
+  ! Tests ishftc() and array constructors.
+  subroutine kseed(v)
+ unsigned(uk), intent(in), optional :: v
+ if (present(v)) then
+sd = seed + [ishftc(v,1), ishftc(v,15), ishftc(v,31), 
ishftc(v,44)]

+ else
+sd = seed
+ end if
+  end subroutine kseed
+
+  function kiss()
+ unsigned(uk) kiss
+ unsigned(uk) m, t
+ integer k
+
+ ! Test unsigned in a statement function
+ m(t, k) = ieor(t, ishft(t, k))
+
+ t = ishft(sd(1), 58) + sd(4)
+ if (s(sd(1)) == s(t)) then
+sd(4) = ishft(sd(1), -6) + s(sd(1))
+ else
+sd(4) = ishft(sd(1), -6) + 1u_uk - s(sd(1) + t)
+ endif
+
+ sd(1) = t + sd(1)
+ sd(2) = m(m(m(sd(2), 13), -17), 43)
+ sd(3) = 6906969069u_uk * sd(3) + 1234567u_uk
+ kiss = sd(1) + sd(2) + sd(3)
+  end function kiss
+
+end module kissm
+
+program testkiss
+   use kissm
+   integer, parameter :: n = 4
+   unsigned(uk) prn(4)
+
+   ! Default sequence
+   unsigned(uk), parameter :: a(4) = [8932985056925012148u_uk, &
+   &  5710300428094272059u_uk, 18342510866933518593u_uk,   &
+   &  14303636270573868250u_uk]
+
+   ! Sequence with the seed 123412341234u_uk
+   unsigned(uk), parameter :: b(4) = [4002508872477953753u_uk, &
+   &  18025327658415290923u_uk,  16058856976144281263u_uk, &
+   &  11842224026193909403u_uk]
+
+   do i = 1, n
+  prn(i) = kiss()
+   end do
+   if (any(prn /= a)) stop 1
+
+   call kseed(123412341234u_uk)
+   do i = 1, n
+  prn(i) = kiss()
+   end do
+   if (any(prn /= b)) stop 2
+
+   call kseed()
+   do i = 1, n
+  prn(i) = kiss()
+   end do
+   if (any(prn /= a)) stop 3
+
+end program testkiss


[patch, teststuite, Fortran, committed] Fix endianness issue on test case

2024-09-12 Thread Thomas Koenig

I just committed the fix for PR 116653 as obvious.

Unfortunately, I left out the description in the ChangeLog, I hope it
is clear enough.

Best regards

Thomas

https://gcc.gnu.org/g:5d9486c29938d79beb798dce1a5509da54fe8c9f

commit r15-3619-g5d9486c29938d79beb798dce1a5509da54fe8c9f
Author: Thomas Koenig 
Date:   Fri Sep 13 07:47:24 2024 +0200

Fix endianness issue on unsigned_21.f90.

gcc/testsuite/ChangeLog:

PR fortran/116653
* gfortran.dg/unsigned_21.f90:
* gfortran.dg/unsigned_21_be.f90: New test.

diff --git a/gcc/testsuite/gfortran.dg/unsigned_21.f90 
b/gcc/testsuite/gfortran.dg/unsigned_21.f90

index 23302c7eabe..c3f65a469dc 100644
--- a/gcc/testsuite/gfortran.dg/unsigned_21.f90
+++ b/gcc/testsuite/gfortran.dg/unsigned_21.f90
@@ -1,5 +1,6 @@
 ! { dg-do run }
 ! { dg-options "-funsigned" }
+! { dg-require-effective-target le }
 program main
   integer :: i
   integer(2) :: j
diff --git a/gcc/testsuite/gfortran.dg/unsigned_21_be.f90 
b/gcc/testsuite/gfortran.dg/unsigned_21_be.f90

new file mode 100644
index 000..64fecd9cd4a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/unsigned_21_be.f90
@@ -0,0 +1,14 @@
+! { dg-do run }
+! { dg-options "-funsigned" }
+! { dg-require-effective-target be }
+program main
+  integer :: i
+  integer(2) :: j
+  unsigned :: u
+  i = -1
+  u = transfer(i,u)
+  if (u /= huge(u)) error stop 1
+  u = 4278058235u
+  j = transfer(u,j)
+  if (j /= -259) error stop 2
+end program main