Re: [PATCH] C, C++, Fortran, OpenMP: Add 'has_device_addr' clause to 'target' construct

2021-11-24 Thread Marcel Vollweiler

Hi Jakub,

this is again a new version of the 'has_device_addr' patch. It includes
further minor changes in the C/C++ part and in addition the Fortran
implementation.

Tested on x86_64-linux with nvptx offloading with no regressions.

Marcel
-
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 
München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas 
Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht 
München, HRB 106955
C, C++, Fortran, OpenMP: Add 'has_device_addr' clause to 'target' construct.

This patch adds the 'has_device_addr' clause to the OpenMP 'target' construct
which was introduced in OpenMP 5.1 (OpenMP API 5.1 specification pp. 197ff):

has_device_addr(list)

"The has_device_addr clause indicates that its list items already have device
addresses and therefore they may be directly accessed from a target device.
If the device address of a list item is not for the device on which the target
region executes, accessing the list item inside the region results in
unspecified behavior. The list items may include array sections." (p. 200)

"A list item may not be specified in both an is_device_ptr clause and a
has_device_addr clause on the directive." (p. 202)

"A list item that appears in an is_device_ptr or a has_device_addr clause must
not be specified in any data-sharing attribute clause on the same target
construct." (p. 203)

gcc/c-family/ChangeLog:

* c-omp.c (c_omp_split_clauses): Add OMP_CLAUSE_HAS_DEVICE_ADDR case.
* c-pragma.h (enum pragma_kind): Add 5.1 in comment.
(enum pragma_omp_clause): Add PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR.

gcc/c/ChangeLog:

* c-parser.c (c_parser_omp_clause_name): Parse 'has_device_addr' clause.
(c_parser_omp_variable_list): Handle array sections.
(c_parser_omp_clause_has_device_addr): Added.
(c_parser_omp_all_clauses): Add PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR case.
(c_parser_omp_target_exit_data): Add HAS_DEVICE_ADDR to OMP_CLAUSE_MASK.
* c-typeck.c (handle_omp_array_sections): Handle clause restrictions.
(c_finish_omp_clauses): Handle array sections.

gcc/cp/ChangeLog:

* parser.c (cp_parser_omp_clause_name): Parse 'has_device_addr' clause.
(cp_parser_omp_var_list_no_open): Handle array sections.
(cp_parser_omp_all_clauses): Add PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR case.
(cp_parser_omp_target_update): Add HAS_DEVICE_ADDR to OMP_CLAUSE_MASK.
* pt.c (tsubst_omp_clauses): Add cases for OMP_CLAUSE_HAS_DEVICE_ADDR.
* semantics.c (handle_omp_array_sections): Handle clause restrictions.
(finish_omp_clauses): Handle array sections.

gcc/fortran/ChangeLog:

* dump-parse-tree.c (show_omp_clauses): Added OMP_LIST_HAS_DEVICE_ADDR
case.
* gfortran.h: Added OMP_LIST_HAS_DEVICE_ADDR.
* openmp.c (enum omp_mask1): Added OMP_CLAUSE_HAS_DEVICE_ADDR.
(gfc_match_omp_clauses): Parse HAS_DEVICE_ADDR clause.
(resolve_omp_clauses): Same.
* trans-openmp.c (gfc_trans_omp_variable_list): Added 
OMP_LIST_HAS_DEVICE_ADDR case.
(gfc_trans_omp_clauses): Firstprivatize of array descriptors.

gcc/ChangeLog:

* gimplify.c (gimplify_scan_omp_clauses): Add OMP_CLAUSE_HAS_DEVICE_ADDR
cases
and handle array sections.
(gimplify_adjust_omp_clauses): Add OMP_CLAUSE_HAS_DEVICE_ADDR case.
* omp-low.c (scan_sharing_clauses): Handle OMP_CLAUSE_HAS_DEVICE_ADDR.
(lower_omp_target): Same.
* tree-core.h (enum omp_clause_code): Same.
* tree-nested.c (convert_nonlocal_omp_clauses): Same.
(convert_local_omp_clauses): Same.
* tree-pretty-print.c (dump_omp_clause): Same.
* tree.c: Same.

libgomp/ChangeLog:

* libgomp.texi: Updated entry for HAS_DEVICE_ADDR.
* target.c (copy_firstprivate_data): Copy only if host address is not
NULL.
* testsuite/libgomp.c++/target-has-device-addr-2.C: New test.
* testsuite/libgomp.c++/target-has-device-addr-4.C: New test.
* testsuite/libgomp.c-c++-common/target-has-device-addr-1.c: New test.
* testsuite/libgomp.c/target-has-device-addr-3.c: New test.
* testsuite/libgomp.fortran/target-has-device-addr-1.f90: New test.
* testsuite/libgomp.fortran/target-has-device-addr-2.f90: New test.
* testsuite/libgomp.fortran/target-has-device-addr-3.f90: New test.
* testsuite/libgomp.fortran/target-has-device-addr-4.f90: New test.

gcc/testsuite/ChangeLog:

* c-c++-common/gomp/clauses-1.c: Added has_device_addr to test cases.
* g++.dg/gomp/attrs-1.C: Added has_device_addr to test cases.
* g++.dg/gomp/attrs-2.C: Added has_device_addr to test cases.
* c-c++-common/gomp/target-has-device-addr-1.c: New test.
* c-c++-common/gomp/target-has-device-addr-2.c: New test.
* c-c++-common/gomp/target-is-devi

[PATCH] PR fortran/103411 - ICE in gfc_conv_array_initializer, at fortran/trans-array.c:6377

2021-11-24 Thread Harald Anlauf via Fortran
Dear all,

when checking the SOURCE and SHAPE arguments to the RESHAPE
intrinsic, for absent PAD argument we failed to handle the case
when SHAPE was a parameter.

Fortunately, the proper check was already there, and the code
just needs some tweaking, as well as one of the testcases.

Regtested on x86_64-pc-linux-gnu.  OK for mainline?

Thanks,
Harald

From d6af2a33bad852bcea39b8c5b2e7c27976bde2a1 Mon Sep 17 00:00:00 2001
From: Harald Anlauf 
Date: Wed, 24 Nov 2021 22:22:24 +0100
Subject: [PATCH] Fortran: improve check of arguments to the RESHAPE intrinsic

gcc/fortran/ChangeLog:

	PR fortran/103411
	* check.c (gfc_check_reshape): Improve check of size of source
	array for the RESHAPE intrinsic against the given shape when pad
	is not given, and shape is a parameter.

gcc/testsuite/ChangeLog:

	PR fortran/103411
	* gfortran.dg/reshape_7.f90: Adjust test to improved check.
	* gfortran.dg/reshape_9.f90: New test.
---
 gcc/fortran/check.c | 17 +
 gcc/testsuite/gfortran.dg/reshape_7.f90 |  2 +-
 gcc/testsuite/gfortran.dg/reshape_9.f90 | 14 ++
 3 files changed, 28 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/reshape_9.f90

diff --git a/gcc/fortran/check.c b/gcc/fortran/check.c
index 5a5aca10ebe..837eb0912c0 100644
--- a/gcc/fortran/check.c
+++ b/gcc/fortran/check.c
@@ -4699,6 +4699,7 @@ gfc_check_reshape (gfc_expr *source, gfc_expr *shape,
   mpz_t size;
   mpz_t nelems;
   int shape_size;
+  bool shape_is_const = false;

   if (!array_check (source, 0))
 return false;
@@ -4736,6 +4737,7 @@ gfc_check_reshape (gfc_expr *source, gfc_expr *shape,
 {
   gfc_expr *e;
   int i, extent;
+  shape_is_const = true;
   for (i = 0; i < shape_size; ++i)
 	{
 	  e = gfc_constructor_lookup_expr (shape->value.constructor, i);
@@ -4748,7 +4750,7 @@ gfc_check_reshape (gfc_expr *source, gfc_expr *shape,
 	  gfc_error ("%qs argument of %qs intrinsic at %L has "
 			 "negative element (%d)",
 			 gfc_current_intrinsic_arg[1]->name,
-			 gfc_current_intrinsic, &e->where, extent);
+			 gfc_current_intrinsic, &shape->where, extent);
 	  return false;
 	}
 	}
@@ -4766,6 +4768,7 @@ gfc_check_reshape (gfc_expr *source, gfc_expr *shape,
   int i, extent;
   gfc_expr *e, *v;

+  shape_is_const = true;
   v = shape->symtree->n.sym->value;

   for (i = 0; i < shape_size; i++)
@@ -4856,8 +4859,7 @@ gfc_check_reshape (gfc_expr *source, gfc_expr *shape,
 	}
 }

-  if (pad == NULL && shape->expr_type == EXPR_ARRAY
-  && gfc_is_constant_expr (shape)
+  if (pad == NULL && shape_is_const
   && !(source->expr_type == EXPR_VARIABLE && source->symtree->n.sym->as
 	   && source->symtree->n.sym->as->type == AS_ASSUMED_SIZE))
 {
@@ -4866,10 +4868,17 @@ gfc_check_reshape (gfc_expr *source, gfc_expr *shape,
 	{
 	  gfc_constructor *c;
 	  bool test;
+	  gfc_constructor_base b;

+	  if (shape->expr_type == EXPR_ARRAY)
+	b = shape->value.constructor;
+	  else if (shape->expr_type == EXPR_VARIABLE)
+	b = shape->symtree->n.sym->value->value.constructor;
+	  else
+	gcc_unreachable ();

 	  mpz_init_set_ui (size, 1);
-	  for (c = gfc_constructor_first (shape->value.constructor);
+	  for (c = gfc_constructor_first (b);
 	   c; c = gfc_constructor_next (c))
 	mpz_mul (size, size, c->expr->value.integer);

diff --git a/gcc/testsuite/gfortran.dg/reshape_7.f90 b/gcc/testsuite/gfortran.dg/reshape_7.f90
index d752650aa4e..4216cb60cbb 100644
--- a/gcc/testsuite/gfortran.dg/reshape_7.f90
+++ b/gcc/testsuite/gfortran.dg/reshape_7.f90
@@ -4,7 +4,7 @@
 subroutine p0
integer, parameter :: sh(2) = [2, 3]
integer, parameter :: &
-   & a(2,2) = reshape([1, 2, 3, 4], sh)   ! { dg-error "Different shape" }
+   & a(2,2) = reshape([1, 2, 3, 4], sh)   ! { dg-error "not enough elements" }
if (a(1,1) /= 0) STOP 1
 end subroutine p0

diff --git a/gcc/testsuite/gfortran.dg/reshape_9.f90 b/gcc/testsuite/gfortran.dg/reshape_9.f90
new file mode 100644
index 000..c46e211b47e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/reshape_9.f90
@@ -0,0 +1,14 @@
+! { dg-do compile }
+! PR fortran/103411 - ICE in gfc_conv_array_initializer
+
+program p
+  integer, parameter :: a(2) = [2,2]
+  integer, parameter :: d(2,2) = reshape([1,2,3,4,5], a)
+  integer, parameter :: c(2,2) = reshape([1,2,3,4], a)
+  integer, parameter :: b(2,2) = &
+   reshape([1,2,3], a) ! { dg-error "not enough elements" }
+  print *, reshape([1,2,3], a) ! { dg-error "not enough elements" }
+  print *, reshape([1,2,3,4], a)
+  print *, reshape([1,2,3,4,5], a)
+  print *, b, c, d
+end
--
2.26.2