When reading the spec, I somehow missed that we can already (spec wise) obtain the OpenMP device number from an interop object; hence, implement this. (For the question what happens if 'interop(omp_interop_none)' was used, I opened an OpenMP spec issue #4459.)
When reading the spec, I realized that this is only supposed to work if only a single interop-object variable has been passed to the interop clause. Hence, there is now a new diagnostic. And, finally, I noticed that restarting the call processing doesn't interact well with 'adjust_args' as the variant substitution is no longer detected. Hence, the code now falls through and there is also a testcase for this. Except for adding some tests for adjust_args and device-number interop-obj extraction, the tests had to be modified for the new diagnostic, either by updating for it or by modifying (e.g. by adding a device clause) in order to test the previous diagnostic/dump. Committed asr15-6721-g1bb367b5cdb9fa. Tobias PS: The arg_types loop was mainly removed because it did not handle calls to variadic functions (causing a segfault); but arg_types is also not actually used after the loop.
commit 1bb367b5cdb9fa77733d87d97483fb57480ef6fe Author: Tobias Burnus <tbur...@baylibre.com> Date: Thu Jan 9 01:36:49 2025 +0100 OpenMP: declare variant's append_args + dispatch interop fixes For 'omp dispatch interop(obj)', call omp_get_interop_int to obtain the device number. Add new error if no device clause is present if multiple interop-clause list items exist. Update some vars and continue after appending interop args instead of restarting to ensure that adjust_args updates are actually performed. gcc/ChangeLog: * builtin-types.def (BT_FN_PTRMODE_PTR_INT_PTR): Add. * gimplify.cc (gimplify_call_expr): Add error for multiple list items to the OpenMP interop clause if no device clause; continue instead of restarting after append_args handling. (gimplify_omp_dispatch): Extract device number from the single interop-clause list item. * omp-builtins.def (BUILT_IN_OMP_GET_INTEROP_INT): Add. gcc/fortran/ChangeLog: * types.def (BT_FN_PTRMODE_PTR_INT_PTR): Add. gcc/testsuite/ChangeLog: * c-c++-common/gomp/append-args-1.c: Update dg-*. * c-c++-common/gomp/append-args-3.c: Extend testcase. * c-c++-common/gomp/dispatch-11.c: Update dg-*. * c-c++-common/gomp/dispatch-12.c: Update dg-*. * g++.dg/gomp/append-args-1.C: Update dg-*. --- gcc/builtin-types.def | 2 + gcc/fortran/types.def | 2 + gcc/gimplify.cc | 67 +++++++++++++++++++------ gcc/omp-builtins.def | 2 + gcc/testsuite/c-c++-common/gomp/append-args-1.c | 3 +- gcc/testsuite/c-c++-common/gomp/append-args-3.c | 49 +++++++++++++++++- gcc/testsuite/c-c++-common/gomp/dispatch-11.c | 57 +++++++++++---------- gcc/testsuite/c-c++-common/gomp/dispatch-12.c | 2 +- gcc/testsuite/g++.dg/gomp/append-args-1.C | 8 +-- 9 files changed, 142 insertions(+), 50 deletions(-) diff --git a/gcc/builtin-types.def b/gcc/builtin-types.def index ede638c66b4..9b7cc9939e4 100644 --- a/gcc/builtin-types.def +++ b/gcc/builtin-types.def @@ -695,6 +695,8 @@ DEF_FUNCTION_TYPE_3 (BT_FN_STRING_STRING_CONST_STRING_SIZE, BT_STRING, BT_STRING, BT_CONST_STRING, BT_SIZE) DEF_FUNCTION_TYPE_3 (BT_FN_INT_CONST_STRING_CONST_STRING_SIZE, BT_INT, BT_CONST_STRING, BT_CONST_STRING, BT_SIZE) +DEF_FUNCTION_TYPE_3 (BT_FN_PTRMODE_PTR_INT_PTR, + BT_PTRMODE, BT_PTR, BT_INT, BT_PTR) DEF_FUNCTION_TYPE_3 (BT_FN_PTR_PTR_CONST_PTR_SIZE, BT_PTR, BT_PTR, BT_CONST_PTR, BT_SIZE) DEF_FUNCTION_TYPE_3 (BT_FN_VOID_PTR_CONST_PTR_SIZE, diff --git a/gcc/fortran/types.def b/gcc/fortran/types.def index 6e27d30e55b..6447cee4ae0 100644 --- a/gcc/fortran/types.def +++ b/gcc/fortran/types.def @@ -133,6 +133,8 @@ DEF_FUNCTION_TYPE_3 (BT_FN_BOOL_VPTR_I8_I8, BT_BOOL, BT_VOLATILE_PTR, BT_I8, BT_I8) DEF_FUNCTION_TYPE_3 (BT_FN_BOOL_VPTR_I16_I16, BT_BOOL, BT_VOLATILE_PTR, BT_I16, BT_I16) +DEF_FUNCTION_TYPE_3 (BT_FN_PTRMODE_PTR_INT_PTR, + BT_PTRMODE, BT_PTR, BT_INT, BT_PTR) DEF_FUNCTION_TYPE_3 (BT_FN_I1_VPTR_I1_I1, BT_I1, BT_VOLATILE_PTR, BT_I1, BT_I1) DEF_FUNCTION_TYPE_3 (BT_FN_I2_VPTR_I2_I2, BT_I2, BT_VOLATILE_PTR, BT_I2, BT_I2) DEF_FUNCTION_TYPE_3 (BT_FN_I4_VPTR_I4_I4, BT_I4, BT_VOLATILE_PTR, BT_I4, BT_I4) diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc index 58a3940514a..58a9d2a748d 100644 --- a/gcc/gimplify.cc +++ b/gcc/gimplify.cc @@ -4121,7 +4121,6 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value) && EXPR_P (CALL_EXPR_FN (*expr_p)) && DECL_P (TREE_OPERAND (CALL_EXPR_FN (*expr_p), 0))) { - tree fndecl = TREE_OPERAND (CALL_EXPR_FN (*expr_p), 0); if (variant_substituted_p) dispatch_adjust_args_list = lookup_attribute ("omp declare variant variant args", @@ -4154,8 +4153,9 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value) 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); + inform (DECL_SOURCE_LOCATION (fndecl), + "%qD declared here", fndecl); + dispatch_interop = NULL_TREE; } else if (dispatch_interop) { @@ -4175,9 +4175,15 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value) "%<declare variant%> candidate %qD declared here", fndecl); } - /* FIXME: obtain the device_number from 1st 'interop' clause item. */ } - if (dispatch_append_args && (nappend != ninterop || !dispatch_device_num)) + if (dispatch_interop && !dispatch_device_num) + { + gcc_checking_assert (ninterop > 1); + error_at (OMP_CLAUSE_LOCATION (dispatch_interop), + "the %<device%> clause must be present if the %<interop%> " + "clause has more than one list item"); + } + if (dispatch_append_args && nappend != ninterop) { sorry_at (OMP_CLAUSE_LOCATION (dispatch_append_args), "%<append_args%> clause not yet supported for %qD", fndecl); @@ -4220,6 +4226,12 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value) CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call); SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (call)); CALL_EXPR_VA_ARG_PACK (*expr_p) = CALL_EXPR_VA_ARG_PACK (call); + ret = gimplify_expr (&CALL_EXPR_FN (*expr_p), pre_p, NULL, + is_gimple_call_addr, fb_rvalue); + if (ret == GS_ERROR) + return GS_ERROR; + nargs = call_expr_nargs (*expr_p); + fndecl = get_callee_fndecl (*expr_p); /* Mark as already processed. */ if (dispatch_interop) @@ -4230,9 +4242,6 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value) TREE_CHAIN (t) = gimplify_omp_ctxp->clauses; gimplify_omp_ctxp->clauses = t; } - - /* Re-run. */ - return GS_OK; } } @@ -4257,9 +4266,6 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value) if (arg_types != NULL_TREE) { - for (int param_idx = 0; param_idx < i; param_idx++) - arg_types = TREE_CHAIN (arg_types); - bool need_device_ptr = false; bool need_device_addr = false; for (int need_addr = 0; need_addr <= 1; need_addr++) @@ -18357,11 +18363,42 @@ gimplify_omp_dispatch (tree *expr_p, gimple_seq *pre_p) // If device clause, adjust ICV tree device = omp_find_clause (OMP_DISPATCH_CLAUSES (expr), OMP_CLAUSE_DEVICE); + // If no device clause exists but an interop clause with a single list + // item, use it to obtain the device number. + if (device) + device = OMP_CLAUSE_DEVICE_ID (device); + else + { + tree first_interop_obj + = omp_find_clause (OMP_DISPATCH_CLAUSES (expr), OMP_CLAUSE_INTEROP); + if (first_interop_obj) + for (tree c = TREE_CHAIN (first_interop_obj); c; c = TREE_CHAIN (c)) + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INTEROP) + { + first_interop_obj = NULL_TREE; + break; + } + if (first_interop_obj) + { + device = create_tmp_var (integer_type_node); + tree c = build_omp_clause (OMP_CLAUSE_LOCATION (first_interop_obj), + OMP_CLAUSE_DEVICE); + OMP_CLAUSE_DEVICE_ID (c) = device; + TREE_CHAIN (c) = TREE_CHAIN (first_interop_obj); + TREE_CHAIN (first_interop_obj) = c; + first_interop_obj = OMP_CLAUSE_DECL (first_interop_obj); + /* device = omp_get_interop_int (obj, omp_ipr_device_num, NULL); */ + tree fn = builtin_decl_explicit (BUILT_IN_OMP_GET_INTEROP_INT); + fn = build_call_expr (fn, 3, first_interop_obj, + build_int_cst (integer_type_node, -5), + null_pointer_node); + gimplify_assign (device, fold_convert (integer_type_node, fn), &body); + } + } tree saved_device_icv = NULL_TREE; if (device - && (TREE_CODE (OMP_CLAUSE_DEVICE_ID (device)) != INTEGER_CST - || !wi::eq_p (wi::to_wide (OMP_CLAUSE_DEVICE_ID (device)), - -1 /* omp_initial_device */))) + && (TREE_CODE (device) != INTEGER_CST + || !wi::eq_p (wi::to_wide (device), -1 /* omp_initial_device */))) { // Save current default-device-var ICV saved_device_icv = create_tmp_var (integer_type_node); @@ -18372,7 +18409,7 @@ gimplify_omp_dispatch (tree *expr_p, gimple_seq *pre_p) // Set default device fn = builtin_decl_explicit (BUILT_IN_OMP_SET_DEFAULT_DEVICE); - call = gimple_build_call (fn, 1, OMP_CLAUSE_DEVICE_ID (device)); + call = gimple_build_call (fn, 1, device); gimplify_seq_add_stmt (&body, call); } diff --git a/gcc/omp-builtins.def b/gcc/omp-builtins.def index 1205c80cfea..b49e1a89bcc 100644 --- a/gcc/omp-builtins.def +++ b/gcc/omp-builtins.def @@ -86,6 +86,8 @@ DEF_GOMP_BUILTIN (BUILT_IN_OMP_GET_DEFAULT_DEVICE, "omp_get_default_device", BT_FN_INT, ATTR_NOTHROW_LEAF_LIST) DEF_GOMP_BUILTIN (BUILT_IN_OMP_SET_DEFAULT_DEVICE, "omp_set_default_device", BT_FN_INT, ATTR_NOTHROW_LEAF_LIST) +DEF_GOMP_BUILTIN (BUILT_IN_OMP_GET_INTEROP_INT, "omp_get_interop_int", + BT_FN_PTRMODE_PTR_INT_PTR, ATTR_NOTHROW_LEAF_LIST) DEF_GOMP_BUILTIN (BUILT_IN_GOMP_ATOMIC_START, "GOMP_atomic_start", BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST) diff --git a/gcc/testsuite/c-c++-common/gomp/append-args-1.c b/gcc/testsuite/c-c++-common/gomp/append-args-1.c index 1325f370fd8..5bfd50d775d 100644 --- a/gcc/testsuite/c-c++-common/gomp/append-args-1.c +++ b/gcc/testsuite/c-c++-common/gomp/append-args-1.c @@ -71,9 +71,8 @@ test (int *a, int *b) #pragma omp dispatch interop (obj2) base3 (5, 1, 2, 3); - /* { dg-note "required by 'dispatch' construct" "" { target *-*-* } .-2 } */ - #pragma omp dispatch interop (obj2, obj1) + #pragma omp dispatch interop (obj2, obj1) /* { dg-error "the 'device' clause must be present if the 'interop' clause has more than one list item" } */ base3 (5, 1, 2, 3); /* { dg-error "number of list items in 'interop' clause \\(2\\) exceeds the number of 'append_args' items \\(1\\) for 'declare variant' candidate 'repl3'" "" { target c } .-2 } */ /* { dg-error "number of list items in 'interop' clause \\(2\\) exceeds the number of 'append_args' items \\(1\\) for 'declare variant' candidate 'void repl3\\(int, omp_interop_t, \\.\\.\\.\\)'" "" { target c++ } .-3 } */ diff --git a/gcc/testsuite/c-c++-common/gomp/append-args-3.c b/gcc/testsuite/c-c++-common/gomp/append-args-3.c index 20fe3c06181..7e08a2df9bb 100644 --- a/gcc/testsuite/c-c++-common/gomp/append-args-3.c +++ b/gcc/testsuite/c-c++-common/gomp/append-args-3.c @@ -17,14 +17,30 @@ void g(int, const char *, omp_interop_t, omp_interop_t); #pragma omp declare variant(g) match(construct={dispatch}) append_args(interop(target),interop(targetsync)) void f(int x, const char *y); +void g1(int, const char *, omp_interop_t); +#pragma omp declare variant(g1) match(construct={dispatch}) append_args(interop(target,targetsync)) +void f1(int x, const char *y); + +void g2(int, const char *, omp_interop_t); +#pragma omp declare variant(g2) match(construct={dispatch}) append_args(interop(target,targetsync)) adjust_args(need_device_ptr: y) +void f2(int x, const char *y); + void foo() { omp_interop_t obj1; /* { dg-note "'obj1' was declared here" } */ omp_interop_t obj2 = omp_interop_none; + omp_interop_t obj5 = omp_interop_none; + omp_interop_t obj6 = omp_interop_none; + const char *cp = 0L; + #pragma omp dispatch device(9) novariants(1) f(2, "abc"); #pragma omp dispatch device(5) interop(obj1,obj2) f(3, "cde"); /* { dg-warning "'obj1' is used uninitialized \\\[-Wuninitialized\\\]" } */ + #pragma omp dispatch interop(obj5) + f1(4, "fgh"); + #pragma omp dispatch interop(obj6) + f2(5, cp); } @@ -32,26 +48,55 @@ void varvar(int, int, omp_interop_t, omp_interop_t, ...); #pragma omp declare variant(varvar) match(construct={dispatch}) append_args(interop(target),interop(targetsync)) void varbase(int x, int y, ...); +void varvar1(int, int, omp_interop_t, ...); +#pragma omp declare variant(varvar1) match(construct={dispatch}) append_args(interop(target,targetsync)) +void varbase1(int x, int y, ...); + +void varvar2(int, int *, omp_interop_t, ...); +#pragma omp declare variant(varvar2) match(construct={dispatch}) append_args(interop(target,targetsync)) adjust_args(need_device_ptr: y) +void varbase2(int x, int *y, ...); + + void bar() { omp_interop_t obj3 = omp_interop_none; omp_interop_t obj4; /* { dg-note "'obj4' was declared here" } */ + omp_interop_t obj7 = omp_interop_none; + omp_interop_t obj8 = omp_interop_none; + int *itr = 0L; + #pragma omp dispatch device(3) nocontext(1) varbase(10, 11, 101, 202, 303); #pragma omp dispatch device(7) interop(obj3,obj4) varbase(20, 21, 111, 222, 333); /* { dg-warning "'obj4' is used uninitialized \\\[-Wuninitialized\\\]" } */ + #pragma omp dispatch interop(obj7) + varbase1(40, 31, 911, 922, 933); + #pragma omp dispatch interop(obj8) + varbase2(49, itr, 919, 929, 939); } -/* { dg-final { scan-tree-dump-times "D\.\[0-9\]+ = __builtin_omp_get_default_device \\(\\);" 4 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "D\.\[0-9\]+ = __builtin_omp_get_default_device \\(\\);" 8 "gimple" } } */ /* { dg-final { scan-tree-dump-times "__builtin_omp_set_default_device \\(9\\);" 1 "gimple" } } */ /* { dg-final { scan-tree-dump-times "__builtin_omp_set_default_device \\(5\\);" 1 "gimple" } } */ /* { dg-final { scan-tree-dump-times "__builtin_omp_set_default_device \\(3\\);" 1 "gimple" } } */ /* { dg-final { scan-tree-dump-times "__builtin_omp_set_default_device \\(7\\);" 1 "gimple" } } */ -/* { dg-final { scan-tree-dump-times "__builtin_omp_set_default_device \\(D\.\[0-9\]+\\);" 4 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "D\.\[0-9\]+ = __builtin_omp_get_interop_int \\(obj5, -5, 0B\\);" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "D\.\[0-9\]+ = __builtin_omp_get_interop_int \\(obj6, -5, 0B\\);" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "D\.\[0-9\]+ = __builtin_omp_get_interop_int \\(obj7, -5, 0B\\);" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "D\.\[0-9\]+ = __builtin_omp_get_interop_int \\(obj8, -5, 0B\\);" 1 "gimple" } } */ + +/* { dg-final { scan-tree-dump-times "__builtin_omp_set_default_device \\(D\.\[0-9\]+\\);" 12 "gimple" } } */ /* { dg-final { scan-tree-dump-times "f \\(2, \"abc\"\\);" 1 "gimple" } } */ /* { dg-final { scan-tree-dump-times "g \\(3, \"cde\", obj1, obj2\\);" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "g1 \\(4, \"fgh\", obj5\\);" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "D\.\[0-9\]+ = __builtin_omp_get_mapped_ptr \\(cp, D\.\[0-9\]+\\);" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "g2 \\(5, D\.\[0-9\]+, obj6\\);" 1 "gimple" } } */ + /* { dg-final { scan-tree-dump-times "varbase \\(10, 11, 101, 202, 303\\);" 1 "gimple" } } */ /* { dg-final { scan-tree-dump-times "varvar \\(20, 21, obj3, obj4, 111, 222, 333\\);" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "varvar1 \\(40, 31, obj7, 911, 922, 933\\);" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "D\.\[0-9\]+ = __builtin_omp_get_mapped_ptr \\(itr, D\.\[0-9\]+\\);" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "varvar2 \\(49, D\.\[0-9\]+, obj8, 919, 929, 939\\);" 1 "gimple" } } */ diff --git a/gcc/testsuite/c-c++-common/gomp/dispatch-11.c b/gcc/testsuite/c-c++-common/gomp/dispatch-11.c index e2372eb3cab..118dbd2663e 100644 --- a/gcc/testsuite/c-c++-common/gomp/dispatch-11.c +++ b/gcc/testsuite/c-c++-common/gomp/dispatch-11.c @@ -19,10 +19,14 @@ typedef enum omp_interop_t __GOMP_UINTPTR_T_ENUM float repl1(); #pragma omp declare variant(repl1) match(construct={dispatch}) float base1(); +/* { dg-note "'base1' declared here" "" { target c } .-1 } */ +/* { dg-note "'float base1\\(\\)' declared here" "" { target c++ } .-2 } */ void repl2(int *, int *); #pragma omp declare variant(repl2) match(construct={dispatch}) adjust_args(need_device_ptr : y) void base2(int *x, int *y); +/* { dg-note "'base2' declared here" "" { target c } .-1 } */ +/* { dg-note "'void base2\\(int\\*, int\\*\\)' declared here" "" { target c++ } .-2 } */ void repl3(int *, int *, omp_interop_t); #pragma omp declare variant(repl3) match(construct={dispatch}) adjust_args(need_device_ptr : y) append_args(interop(target)) @@ -35,28 +39,28 @@ dupl (int *a, int *b) omp_interop_t obj1, obj2; float x; - #pragma omp dispatch interop ( obj1 ) interop(obj2) /* { dg-error "too many 'interop' clauses" } */ + #pragma omp dispatch interop ( obj1 ) interop(obj2) device(2) /* { dg-error "too many 'interop' clauses" } */ x = base1 (); /* { dg-error "number of list items in 'interop' clause \\(2\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'repl1'" "" { target c } .-2 } */ /* { dg-error "number of list items in 'interop' clause \\(2\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'float repl1\\(\\)'" "" { target c++ } .-3 } */ - #pragma omp dispatch interop ( obj1) nocontext(1) interop (obj2 ) /* { dg-error "too many 'interop' clauses" } */ + #pragma omp dispatch interop ( obj1) nocontext(1) interop (obj2 ) device(2)/* { dg-error "too many 'interop' clauses" } */ base2 (a, b); - /* { dg-error "number of list items in 'interop' clause \\(2\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'base2'" "" { target c } .-2 } */ - /* { dg-error "number of list items in 'interop' clause \\(2\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'void base2\\(int\\*, int\\*\\)'" "" { target c++ } .-3 } */ + /* { dg-error "unexpected 'interop' clause as invoked procedure 'base2' is not variant substituted" "" { target c } .-2 } */ + /* { dg-error "unexpected 'interop' clause as invoked procedure 'void base2\\(int\\*, int\\*\\)' is not variant substituted" "" { target c++ } .-3 } */ return x; } /* { dg-note "'declare variant' candidate 'repl1' declared here" "" { target c } 19 } */ /* { dg-note "'declare variant' candidate 'float repl1\\(\\)' declared here" "" { target c++ } 19 } */ -/* { dg-note "'declare variant' candidate 'base1' declared here" "" { target c } 21 } */ -/* { dg-note "'declare variant' candidate 'float base1\\(\\)' declared here" "" { target c++ } 21 } */ -/* { dg-note "'declare variant' candidate 'repl2' declared here" "" { target c } 23 } */ -/* { dg-note "'declare variant' candidate 'void repl2\\(int\\*, int\\*\\)' declared here" "" { target c++ } 23 } */ -/* { dg-note "'declare variant' candidate 'base2' declared here" "" { target c } 25 } */ -/* { dg-note "'declare variant' candidate 'void base2\\(int\\*, int\\*\\)' declared here" "" { target c++ } 25 } */ -/* { dg-note "'declare variant' candidate 'repl3' declared here" "" { target c } 28 } */ -/* { dg-note "'declare variant' candidate 'void repl3\\(int\\*, int\\*, omp_interop_t\\)' declared here" "" { target c++ } 28 } */ + + +/* { dg-note "'declare variant' candidate 'repl2' declared here" "" { target c } 25 } */ +/* { dg-note "'declare variant' candidate 'void repl2\\(int\\*, int\\*\\)' declared here" "" { target c++ } 25 } */ + + +/* { dg-note "'declare variant' candidate 'repl3' declared here" "" { target c } 32 } */ +/* { dg-note "'declare variant' candidate 'void repl3\\(int\\*, int\\*, omp_interop_t\\)' declared here" "" { target c++ } 32 } */ float test (int *a, int *b) @@ -69,27 +73,27 @@ test (int *a, int *b) /* { dg-error "number of list items in 'interop' clause \\(1\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'repl1'" "" { 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 'float repl1\\(\\)'" "" { target c++ } .-3 } */ - #pragma omp dispatch interop ( obj1, obj1 ) /* Twice the same - should be fine. */ + #pragma omp dispatch interop ( obj1, obj1 ) device(42) /* Twice the same - should be fine. */ x = base1 (); /* { dg-error "number of list items in 'interop' clause \\(2\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'repl1'" "" { target c } .-2 } */ /* { dg-error "number of list items in 'interop' clause \\(2\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'float repl1\\(\\)'" "" { target c++ } .-3 } */ - #pragma omp dispatch novariants(1) interop(obj2, obj1) + #pragma omp dispatch novariants(1) interop(obj2, obj1) device(0) y = base1 (); - /* { dg-error "number of list items in 'interop' clause \\(2\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'base1'" "" { target c } .-2 } */ - /* { dg-error "number of list items in 'interop' clause \\(2\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'float base1\\(\\)'" "" { target c++ } .-3 } */ + /* { dg-error "unexpected 'interop' clause as invoked procedure 'base1' is not variant substituted" "" { target c } .-2 } */ + /* { dg-error "unexpected 'interop' clause as invoked procedure 'float base1\\(\\)' is not variant substituted" "" { target c++ } .-3 } */ - #pragma omp dispatch interop(obj2, obj1) + #pragma omp dispatch interop(obj2, obj1) device(3) base2 (a, b); /* { dg-error "number of list items in 'interop' clause \\(2\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'repl2'" "" { target c } .-2 } */ /* { dg-error "number of list items in 'interop' clause \\(2\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'void repl2\\(int\\*, int\\*\\)'" "" { target c++ } .-3 } */ #pragma omp dispatch interop(obj2) nocontext(1) base2 (a, b); - /* { dg-error "number of list items in 'interop' clause \\(1\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'base2'" "" { 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 'void base2\\(int\\*, int\\*\\)'" "" { target c++ } .-3 } */ + /* { dg-error "unexpected 'interop' clause as invoked procedure 'base2' is not variant substituted" "" { target c } .-2 } */ + /* { dg-error "unexpected 'interop' clause as invoked procedure 'void base2\\(int\\*, int\\*\\)' is not variant substituted" "" { target c++ } .-3 } */ - #pragma omp dispatch interop(obj3, obj2) + #pragma omp dispatch interop(obj3, obj2) device(2) base3 (a, b); /* { dg-error "number of list items in 'interop' clause \\(2\\) exceeds the number of 'append_args' items \\(1\\) for 'declare variant' candidate 'repl3'" "" { target c } .-2 } */ /* { dg-error "number of list items in 'interop' clause \\(2\\) exceeds the number of 'append_args' items \\(1\\) for 'declare variant' candidate 'void repl3\\(int\\*, int\\*, omp_interop_t\\)'" "" { target c++ } .-3 } */ @@ -97,16 +101,15 @@ test (int *a, int *b) #pragma omp dispatch interop(obj3) base3 (a, b); - /* { dg-message "sorry, unimplemented: 'append_args' clause not yet supported for 'repl3'" "" { target c } 28 } */ - /* { dg-message "sorry, unimplemented: 'append_args' clause not yet supported for 'void repl3\\(int\\*, int\\*, omp_interop_t\\)'" "" { target c++ } 28 } */ - /* { dg-note "required by 'dispatch' construct" "" { target *-*-* } .-4 } */ + /* { dg-message "sorry, unimplemented: 'append_args' clause not yet supported for 'repl3'" "" { target c } 32 } */ + /* { dg-message "sorry, unimplemented: 'append_args' clause not yet supported for 'void repl3\\(int\\*, int\\*, omp_interop_t\\)'" "" { target c++ } 32 } */ return x + y; } /* { dg-final { scan-tree-dump-times "#pragma omp dispatch interop\\(obj1\\)\[\\n\\r\]" 1 "original" } } */ -/* { dg-final { scan-tree-dump-times "#pragma omp dispatch interop\\(obj1\\) interop\\(obj1\\)\[\\n\\r\]" 1 "original" } } */ -/* { dg-final { scan-tree-dump-times "#pragma omp dispatch interop\\(obj1\\) interop\\(obj2\\) novariants\\(1\\)\[\\n\\r\]" 1 "original" } } */ -/* { dg-final { scan-tree-dump-times "#pragma omp dispatch interop\\(obj1\\) interop\\(obj2\\)\[\\n\\r\]" 1 "original" } } */ +/* { dg-final { scan-tree-dump-times "#pragma omp dispatch device\\(42\\) interop\\(obj1\\) interop\\(obj1\\)\[\\n\\r\]" 1 "original" } } */ +/* { dg-final { scan-tree-dump-times "#pragma omp dispatch device\\(0\\) interop\\(obj1\\) interop\\(obj2\\) novariants\\(1\\)\[\\n\\r\]" 1 "original" } } */ +/* { dg-final { scan-tree-dump-times "#pragma omp dispatch device\\(3\\) interop\\(obj1\\) interop\\(obj2\\)\[\\n\\r\]" 1 "original" } } */ /* { dg-final { scan-tree-dump-times "#pragma omp dispatch nocontext\\(1\\) interop\\(obj2\\)\[\\n\\r\]" 1 "original" } } */ -/* { dg-final { scan-tree-dump-times "#pragma omp dispatch interop\\(obj2\\) interop\\(obj3\\)\[\\n\\r\]" 1 "original" } } */ +/* { dg-final { scan-tree-dump-times "#pragma omp dispatch device\\(2\\) interop\\(obj2\\) interop\\(obj3\\)\[\\n\\r\]" 1 "original" } } */ /* { dg-final { scan-tree-dump-times "#pragma omp dispatch interop\\(obj3\\)\[\\n\\r\]" 1 "original" } } */ diff --git a/gcc/testsuite/c-c++-common/gomp/dispatch-12.c b/gcc/testsuite/c-c++-common/gomp/dispatch-12.c index 0b8fdfab5ca..a34420e3d6f 100644 --- a/gcc/testsuite/c-c++-common/gomp/dispatch-12.c +++ b/gcc/testsuite/c-c++-common/gomp/dispatch-12.c @@ -26,7 +26,7 @@ test () const omp_interop_t *obj3; short x; - #pragma omp dispatch interop ( obj1, obj2, obj1 ) /* { dg-error "'obj2' must be of 'omp_interop_t'" } */ + #pragma omp dispatch interop ( obj1, obj2, obj1 ) device(2) /* { dg-error "'obj2' must be of 'omp_interop_t'" } */ base1 (); /* { dg-error "number of list items in 'interop' clause \\(3\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'repl1'" "" { target c } .-2 } */ /* { dg-error "number of list items in 'interop' clause \\(3\\) exceeds the number of 'append_args' items \\(0\\) for 'declare variant' candidate 'void repl1\\(\\)'" "" { target c++ } .-3 } */ diff --git a/gcc/testsuite/g++.dg/gomp/append-args-1.C b/gcc/testsuite/g++.dg/gomp/append-args-1.C index d4f9a70d19f..2fbb21aeb4d 100644 --- a/gcc/testsuite/g++.dg/gomp/append-args-1.C +++ b/gcc/testsuite/g++.dg/gomp/append-args-1.C @@ -19,7 +19,7 @@ float repl1(T, T2, T2); template<typename T> float base1(T); -/* { dg-message "sorry, unimplemented: 'append_args' clause not yet supported for 'float repl1\\(T, T2, T2\\) \\\[with T = short int; T2 = omp_interop_t\\\]'" "" { target *-*-* } .-4 } */ + /* { dg-message "sorry, unimplemented: 'append_args' clause not yet supported for 'float repl1\\(T, T2, T2\\) \\\[with T = omp_interop_t; T2 = omp_interop_t\\\]'" "" { target *-*-* } .-5 } */ /* { dg-message "sorry, unimplemented: 'append_args' clause not yet supported for 'float repl1\\(T, T2, T2\\) \\\[with T = float; T2 = omp_interop_t\\\]'" "" { target *-*-* } .-6 } */ @@ -93,9 +93,11 @@ test (int *a, int *b) omp_interop_t obj1, obj2; float x, y; - #pragma omp dispatch interop ( obj1, obj2 ) + #pragma omp dispatch interop ( obj1, obj2 ) device(2) // OK + x = base1<short> (5); + + #pragma omp dispatch interop ( obj1, obj2 ) // { dg-error "the 'device' clause must be present if the 'interop' clause has more than one list item" } x = base1<short> (5); - /* { dg-note "required by 'dispatch' construct" "" { target *-*-* } .-2 } */ #pragma omp dispatch base2inval<int *, omp_interop_t> (a, omp_interop_none);