[PATCH] fortran, openmp: PR fortran/93660 Fix ICE when coarrays used with 'omp declare simd'
Kwok Cheung Yeung
kcy@codesourcery.com
Thu Sep 10 22:51:51 GMT 2020
Hello
The ICE from the test case in PR93660 is due to the hidden caf_token and
caf_offset parameters generated by the Fortran front end due to the use of coarrays:
<function_decl 0x7ffff74e7400 f
type <function_type 0x7ffff74ed1f8
...
arg-types <tree_list 0x7ffff74e6a28 value <pointer_type 0x7ffff74ed000>
chain <tree_list 0x7ffff731db18 value <void_type 0x7ffff731ef18 void>>>
...
arguments <parm_decl 0x7ffff74d4400 x
type <pointer_type 0x7ffff74ed000 type <integer_type 0x7ffff74e9a80
integer(kind=4)>
...
readonly used unsigned DI passed-by-reference simd_coarray_1.f90:16:0
size <integer_cst 0x7ffff7309bb8 64> unit-size <integer_cst 0x7ffff7309bd0 8>
align:64 warn_if_not_align:0 context <function_decl 0x7ffff74e7400 f>
arg-type <pointer_type 0x7ffff74ed000>
chain <parm_decl 0x7ffff74d4480 caf_token.2 type <pointer_type
0x7ffff732b498>
readonly unsigned DI simd_coarray_1.f90:16:0 size <integer_cst
0x7ffff7309bb8 64> unit-size <integer_cst 0x7ffff7309bd0 8>
align:64 warn_if_not_align:0 context <function_decl 0x7ffff74e7400
f> arg-type <pointer_type 0x7ffff74ed000> chain <parm_decl 0x7ffff74d4500
caf_offset.3>>>
struct-function 0x7ffff74e8210 chain <function_decl 0x7ffff74e7800
_caf_init.15>>
simd_clone_vector_of_formal_parm_types prefers to use the TYPE_ARG_TYPES of a
function decl if available, but they do not contain entries for the hidden caf_*
parameters. Replacements are therefore not generated for them, and the ICE
occurs in ipa_simd_modify_function_body due to an assert firing when a
replacement is not found for these hidden arguments.
This patch fixes this by choosing between TYPE_ARG_TYPES and DECL_ARGUMENT types
depending on which one provides more types, preferring TYPE_ARG_TYPES if equal
to remain closer to the previous behaviour. I tried simply always preferring
DECL_ARGUMENT types, but that causes issues with the tests in g++.dg/gomp/.
Tested with no regressions in the gomp/ tests for gcc, g++ and gfortran, and no
regressions in libgomp with Nvidia offloading.
Okay for trunk?
Thanks
Kwok
-------------- next part --------------
commit e842728189edc14c3f8b7c0a93cb51b007f20220
Author: Kwok Cheung Yeung <kcy@codesourcery.com>
Date: Thu Sep 10 13:59:51 2020 -0700
Fix ICE when coarrays used with the OpenMP 'declare simd' directive
The ICE occurs when Fortran coarrays are used in conjunction with the
'omp declare simd' directive, and the '-fopenmp' and '-fcoarray=lib' flags
are used.
2020-09-10 Kwok Cheung Yeung <kcy@codesourcery.com>
Tobias Burnus <tobias@codesourcery.com>
gcc/
PR fortran/93660
* omp-simd-clone.c (simd_clone_vector_of_formal_parm_types): Choose
method of acquiring types that will result in a larger number of
types.
gcc/testsuite/
PR fortran/93660
* gfortran.dg/gomp/pr93660.f90: New.
libgomp/
PR fortran/93660
* testsuite/libgomp.fortran/coarray-simd.f90: New.
diff --git a/gcc/omp-simd-clone.c b/gcc/omp-simd-clone.c
index 942fb97..e9084c7 100644
--- a/gcc/omp-simd-clone.c
+++ b/gcc/omp-simd-clone.c
@@ -86,23 +86,36 @@ simd_clone_struct_copy (struct cgraph_simd_clone *to,
* sizeof (struct cgraph_simd_clone_arg))));
}
-/* Fill an empty vector ARGS with parameter types of function FNDECL. This
- uses TYPE_ARG_TYPES if available, otherwise falls back to types of
- DECL_ARGUMENTS types. */
+/* Fill an empty vector ARGS with parameter types of function FNDECL.
+ The parameters can be acquired using the TYPE_ARG_TYPES or the
+ DECL_ARGUMENTS types - whichever provides the larger number of types is
+ used. These can differ if one or the other is not available, or if there
+ are hidden parameters (e.g. with Fortran coarrays). In the event of a tie,
+ prefer using the TYPE_ARG_TYPES. */
static void
simd_clone_vector_of_formal_parm_types (vec<tree> *args, tree fndecl)
{
- if (TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
+ int arg_type_count = 0, decl_arg_count = 0;
+ tree t;
+
+ for (t = TYPE_ARG_TYPES (TREE_TYPE (fndecl)); t; t = TREE_CHAIN (t))
+ arg_type_count++;
+ for (t = DECL_ARGUMENTS (fndecl); t; t = DECL_CHAIN (t))
+ decl_arg_count++;
+
+ gcc_assert (arg_type_count || decl_arg_count);
+
+ if (arg_type_count >= decl_arg_count)
+ push_function_arg_types (args, TREE_TYPE (fndecl));
+ else
{
- push_function_arg_types (args, TREE_TYPE (fndecl));
- return;
+ push_function_arg_decls (args, fndecl);
+ unsigned int i;
+ tree arg;
+ FOR_EACH_VEC_ELT (*args, i, arg)
+ (*args)[i] = TREE_TYPE ((*args)[i]);
}
- push_function_arg_decls (args, fndecl);
- unsigned int i;
- tree arg;
- FOR_EACH_VEC_ELT (*args, i, arg)
- (*args)[i] = TREE_TYPE ((*args)[i]);
}
/* Given a simd function in NODE, extract the simd specific
diff --git a/gcc/testsuite/gfortran.dg/gomp/pr93660.f90 b/gcc/testsuite/gfortran.dg/gomp/pr93660.f90
new file mode 100644
index 0000000..999ccb2
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/pr93660.f90
@@ -0,0 +1,8 @@
+! { dg-do compile }
+! { dg-additional-options "-fcoarray=lib -lcaf_single" }
+
+integer function f(x)
+ integer :: x[*]
+ !$omp declare simd
+ f = x[1]
+end
diff --git a/libgomp/testsuite/libgomp.fortran/coarray-simd.f90 b/libgomp/testsuite/libgomp.fortran/coarray-simd.f90
new file mode 100644
index 0000000..debdf5d
--- /dev/null
+++ b/libgomp/testsuite/libgomp.fortran/coarray-simd.f90
@@ -0,0 +1,51 @@
+! { dg-do run }
+! { dg-additional-options "-fcoarray=lib -lcaf_single" }
+
+program coarray_simd
+ implicit none
+ integer :: i, j
+ integer :: A(5)[*]
+ integer, allocatable :: B(:,:)[:,:], C(:,:)
+
+ A = [1,2,3,4,5]
+ if (any(f(A) /= [1,2,3,4,5])) stop 1
+
+ allocate(B(5,5)[1:5,7:*])
+ C = f2(B)
+ do i = 1, 5
+ do j = 1, 5
+ if (5 * B(j,i) /= C(j,i)) stop 2
+ end do
+ end do
+
+ C = f3(B)
+ do i = 1, 5
+ do j = 1, 5
+ if (99 * B(j,i) /= C(j,i)) stop 3
+ end do
+ end do
+contains
+ integer function f(x)
+ integer :: x(5)[*]
+ dimension :: f(5)
+ !$omp declare simd
+ f = x(:)[1]
+ end function
+
+ integer function f2(x)
+ integer, allocatable :: x(:,:)[:,:]
+ allocatable :: f2
+ dimension :: f2(:,:)
+ !$omp declare simd
+ f2 = x(:,:)[1,7] * 5
+ end function
+
+ integer function f3(x)
+ integer :: x(:,:)[1:5,*]
+ allocatable :: f3
+ dimension :: f3(:,:)
+ !$omp declare simd
+ f3 = x(:,:)[1,1] * 99
+ end function
+end
+
More information about the Gcc-patches
mailing list