@@ -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
new file mode 100644
@@ -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
new file mode 100644
@@ -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
+