https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100991
Bug ID: 100991
Summary: [OpenMP] firstprivate for optional arguments is
mishandled
Product: gcc
Version: 12.0
Status: UNCONFIRMED
Keywords: openmp
Severity: normal
Priority: P3
Component: fortran
Assignee: unassigned at gcc dot gnu.org
Reporter: burnus at gcc dot gnu.org
Target Milestone: ---
Split off from my defaultmap patch.
FAILING is either:
(A) FIRST TEST:
libgomp/testsuite/libgomp.fortran/optional-map.f90
for the implicitly mapped
subroutine sub2(ii, ...
integer, optional :: ii, ...
but that requires the trans-openmp.c patch shown below (otherwise, ii is mapped
fromto)
(B) SECOND TEST
program main
implicit none
integer :: ii
ii = 7
call foo(ii)
call foo()
contains
subroutine foo (ii1)
integer, optional :: ii1
!$omp target firstprivate(ii1)
if (present (ii1)) then
if (ii1 /= 7) stop 1
ii1 = 5
end if
!$omp end target
if (present (ii1)) then
if (ii1 /= 7) stop 1
end if
end
end
Patch mentioned for (A):
gfc_omp_scalar_p (tree decl, bool ptr_alloc_ok)
{
tree type = TREE_TYPE (decl);
+ if (gfc_omp_is_optional_argument (decl))
+ type = TREE_TYPE (type);
if (TREE_CODE (type) == REFERENCE_TYPE)
type = TREE_TYPE (type);
if (TREE_CODE (type) == POINTER_TYPE)
* * * *
The code needed is similar to:
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -12804,7 +12804,8 @@ lower_omp_target (gimple_stmt_iterator *gsi_p,
omp_context *ctx)
if (omp_is_reference (ovar))
type = TREE_TYPE (type);
if ((INTEGRAL_TYPE_P (type)
- && TYPE_PRECISION (type) <= POINTER_SIZE)
+ && TYPE_PRECISION (type) <= POINTER_SIZE
+ && !omp_check_optional_argument (ovar, false))
|| TREE_CODE (type) == POINTER_TYPE)
{
tkind = GOMP_MAP_FIRSTPRIVATE_INT;
@@ -13026,13 +13027,15 @@ lower_omp_target (gimple_stmt_iterator *gsi_p,
omp_context *ctx)
|| is_gimple_reg_type (TREE_TYPE (var)))
{
tree new_var = lookup_decl (var, ctx);
+ bool is_optional = omp_check_optional_argument (var, false);
tree type;
type = TREE_TYPE (var);
if (omp_is_reference (var))
type = TREE_TYPE (type);
if ((INTEGRAL_TYPE_P (type)
&& TYPE_PRECISION (type) <= POINTER_SIZE)
- || TREE_CODE (type) == POINTER_TYPE)
+ || TREE_CODE (type) == POINTER_TYPE
+ || is_optional)
{
x = build_receiver_ref (var, false, ctx);
if (TREE_CODE (type) != POINTER_TYPE)
@@ -13040,11 +13043,14 @@ lower_omp_target (gimple_stmt_iterator *gsi_p,
omp_context *ctx)
x = fold_convert (type, x);
gimplify_expr (&x, &new_body, NULL, is_gimple_val,
fb_rvalue);
- if (omp_is_reference (var))
+ if (omp_is_reference (var) || is_optional)
{
+ tree present = (is_optional
+ ? omp_check_optional_argument (ovar,
true)
+ : NULL_TREE);
...
(Cf. other code in this file.)
Except, of course, that this does not handle all the fun stuff which is not
trivially assignable. (allocatable arrays, polymorphic ...)