&& DECL_P (TREE_OPERAND (CALL_EXPR_FN (*expr_p), 0)))
{
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (*expr_p), 0);
- dispatch_adjust_args_list
- = lookup_attribute ("omp declare variant variant args",
- DECL_ATTRIBUTES (fndecl));
+ if (variant_substituted_p)
+ dispatch_adjust_args_list
+ = lookup_attribute ("omp declare variant variant args",
+ DECL_ATTRIBUTES (fndecl));
if (dispatch_adjust_args_list)
{
dispatch_adjust_args_list = TREE_VALUE (dispatch_adjust_args_list);
int nappend = 0, ninterop = 0;
for (tree t = dispatch_append_args; t; t = TREE_CHAIN (t))
nappend++;
- if (dispatch_interop)
+ if (dispatch_interop && !variant_substituted_p)
+ {
+ error_at (OMP_CLAUSE_LOCATION (dispatch_interop),
+ "unexpected %<interop%> clause as invoked procedure %qD is "
+ "not variant substituted", fndecl);
+ inform (DECL_SOURCE_LOCATION (fndecl),
+ "%qD declared here", fndecl);
+ }
+ else if (dispatch_interop)
{
for (tree t = dispatch_interop; t; t = TREE_CHAIN (t))
if (OMP_CLAUSE_CODE (t) == OMP_CLAUSE_INTEROP)
--- /dev/null
+/* { dg-additional-options "-fdump-tree-gimple" } */
+
+/* Check that append_args is not applied if there the outermost function
+ in '#pragma omp dispatch' is not variant substituted. */
+
+#if __cplusplus >= 201103L
+# define __GOMP_UINTPTR_T_ENUM : __UINTPTR_TYPE__
+#else
+# define __GOMP_UINTPTR_T_ENUM
+#endif
+
+typedef enum omp_interop_t __GOMP_UINTPTR_T_ENUM
+{
+ omp_interop_none = 0,
+ __omp_interop_t_max__ = __UINTPTR_MAX__
+} omp_interop_t;
+
+int v1(int, omp_interop_t);
+#pragma omp declare variant(v1) match(construct={dispatch}) append_args(interop(target))
+int b1(int);
+
+int v2(int);
+int v2a(int);
+#pragma omp declare variant(v2) match(construct={dispatch},user={condition(1)})
+#pragma omp declare variant(v2a) match(user={condition(1)})
+int b2(int);
+
+
+int test (int x1, int x2, int y1, int y2, int z1, int z2, int num1, int num2, int num3)
+{
+
+/* { dg-final { scan-tree-dump-times "D\.\[0-9\]+ = __builtin_omp_get_default_device \\(\\);" 3 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "__builtin_omp_set_default_device \\(D\.\[0-9\]+\\);" 3 "gimple" } } */
+
+ #pragma omp dispatch
+ x1 = v1 (b2 (x1), omp_interop_none);
+/* { dg-final { scan-tree-dump-times "D\.\[0-9\]+ = v2 \\(x1\\);" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "x1 = v1 \\(D\.\[0-9\]+, 0\\);" 1 "gimple" } } */
+
+ #pragma omp dispatch device(num1)
+ x2 = v1 (b2 (x2), omp_interop_none);
+/* { dg-final { scan-tree-dump-times "__builtin_omp_set_default_device \\(num1\\);" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9\]+ = v2 \\(x2\\);" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "x2 = v1 \\(D\.\[0-9\]+, 0\\);" 1 "gimple" } } */
+
+
+ #pragma omp dispatch nocontext(1)
+ y1 = v1 (b2 (y1), omp_interop_none);
+/* { dg-final { scan-tree-dump-times "D\.\[0-9\]+ = v2a \\(y1\\);" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "y1 = v1 \\(D\.\[0-9\]+, 0\\);" 1 "gimple" } } */
+
+ #pragma omp dispatch nocontext(1) device(num2)
+ y2 = v1 (b2 (y2), omp_interop_none);
+/* { dg-final { scan-tree-dump-times "__builtin_omp_set_default_device \\(num2\\);" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9\]+ = v2a \\(y2\\);" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "y2 = v1 \\(D\.\[0-9\]+, 0\\);" 1 "gimple" } } */
+
+
+ #pragma omp dispatch novariants(1)
+ z1 = v1 (b2 (z1), omp_interop_none);
+/* { dg-final { scan-tree-dump-times "D\.\[0-9\]+ = v2 \\(z1\\);" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "z1 = v1 \\(D\.\[0-9\]+, 0\\);" 1 "gimple" } } */
+
+ #pragma omp dispatch novariants(1) device(num3)
+ z2 = v1 (b2 (z2), omp_interop_none);
+/* { dg-final { scan-tree-dump-times "__builtin_omp_set_default_device \\(num3\\);" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "D\.\[0-9\]+ = v2 \\(z2\\);" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "z2 = v1 \\(D\.\[0-9\]+, 0\\);" 1 "gimple" } } */
+
+ return x1 + x2 + y1 + y2 + z1 + z2;
+}
--- /dev/null
+/* { dg-additional-options "-fdump-tree-gimple" } */
+
+/* Check that append_args is not applied when the outermost function
+ in '#pragma omp dispatch' is not variant substituted. */
+
+#if __cplusplus >= 201103L
+# define __GOMP_UINTPTR_T_ENUM : __UINTPTR_TYPE__
+#else
+# define __GOMP_UINTPTR_T_ENUM
+#endif
+
+typedef enum omp_interop_t __GOMP_UINTPTR_T_ENUM
+{
+ omp_interop_none = 0,
+ __omp_interop_t_max__ = __UINTPTR_MAX__
+} omp_interop_t;
+
+int v1(int, omp_interop_t);
+ /* { dg-note "'v1' declared here" "" { target c } .-1 } */
+ /* { dg-note "'int v1\\(int, omp_interop_t\\)' declared here" "" { target c++ } .-2 } */
+int v1a(int);
+ /* { dg-note "'declare variant' candidate 'v1a' declared here" "" { target c } .-1 } */
+ /* { dg-note "'declare variant' candidate 'int v1a\\(int\\)' declared here" "" { target c++ } .-2 } */
+#pragma omp declare variant(v1) match(construct={dispatch},user={condition(1)}) append_args(interop(targetsync))
+#pragma omp declare variant(v1a) match(user={condition(1)})
+int b1(int);
+ /* { dg-note "'b1' declared here" "" { target c } .-1 } */
+ /* { dg-note "'int b1\\(int\\)' declared here" "" { target c++ } .-2 } */
+
+int v2(int);
+int v2a(int);
+#pragma omp declare variant(v2) match(construct={dispatch},user={condition(1)})
+#pragma omp declare variant(v2a) match(user={condition(1)})
+int b2(int);
+
+
+int test (int y1, int y2, int y3, int y4, int num1, int num2, int num3, int num4)
+{
+ int x1, x2, x3, x4;
+ omp_interop_t obj = omp_interop_none;
+
+ #pragma omp dispatch device(num1) interop(obj)
+ x1 = v1 (b2 (y1), omp_interop_none);
+ /* { dg-error "unexpected 'interop' clause as invoked procedure 'v1' is not variant substituted" "" { target c } .-2 } */
+ /* { dg-error "unexpected 'interop' clause as invoked procedure 'int v1\\(int, omp_interop_t\\)' is not variant substituted" "" { target c++ } .-3 } */
+
+
+ #pragma omp dispatch device(num2) nocontext(1) interop(obj)
+ x2 = b1 (b2 (y2));
+ /* { dg-error "number of list items in 'interop' clause \\(1\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'v1a'" "" { target c } .-2 } */
+ /* { dg-error "number of list items in 'interop' clause \\(1\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'int v1a\\(int\\)'" "" { target c++ } .-3 } */
+
+
+ #pragma omp dispatch device(num2) novariants(1) interop(obj)
+ x3 = b1 (b2 (y3));
+ /* { dg-error "unexpected 'interop' clause as invoked procedure 'b1' is not variant substituted" "" { target c } .-2 } */
+ /* { dg-error "unexpected 'interop' clause as invoked procedure 'int b1\\(int\\)' is not variant substituted" "" { target c++ } .-3 } */
+
+
+ /* OK */
+ #pragma omp dispatch device(num4) nocontext(0) interop(obj)
+ x4 = b1 (b2 (y4));
+
+ return x1 + x2 + x3 + x4;
+}