When Sandra implemented the GOMP_interop call in gimplify.cc for declare_variant's append_args, she run into an ICE because the C++ template substitution for prefer_type did not work.
Her solution was to add a sorry to defer the implementation, which now the attached patch does. Actually, the heavy lifting in pt.cc was already done, but converting the template-replaced expressions into the proper input for gimplification was missing. The same is required for 'omp interop' for the prefer_type modifier to init; hence, we already have a function that does this. Solution: Call that one also for append_args' prefer_type. Unless there are comments, I intent to commit the attached patch later today. Thanks, Tobias
OpenMP: Fix C++ template handling with append_args' prefer_type modifier It is possible but not very sensible to use C++ templates with in the prefer_type modifier to the 'append_args' clause of 'declare variant'. The commit r15-6336-g12dd892b1a3ad7 added substitution support in pt.cc, but missed to update afterward the actual data in decl.cc. As gimplification support was only added in r15-8898-gf016ee89955ab4, this could not be tested back then. The latter commit added a sorry for it gimplify.cc and the existing testcase, which this commit now removes. gcc/cp/ChangeLog: * cp-tree.h (cp_finish_omp_init_prefer_type): Add. * decl.cc (omp_declare_variant_finalize_one): Call it. * pt.cc (tsubst_attribute): Minor rebustification for OpenMP append_args handling. * semantics.cc (cp_omp_init_prefer_type_update): Rename to ... (cp_finish_omp_init_prefer_type): ... this; remove static attribute and return modified tree. Move clause handling to ... (finish_omp_clauses): ... the caller. gcc/ChangeLog: * gimplify.cc (modify_call_for_omp_dispatch): Remove sorry. gcc/testsuite/ChangeLog: * g++.dg/gomp/append-args-1.C: Remove expected dg-sorry. * g++.dg/gomp/append-args-8.C: New test. gcc/cp/cp-tree.h | 1 + gcc/cp/decl.cc | 3 + gcc/cp/pt.cc | 9 ++- gcc/cp/semantics.cc | 21 +++---- gcc/gimplify.cc | 7 --- gcc/testsuite/g++.dg/gomp/append-args-1.C | 4 +- gcc/testsuite/g++.dg/gomp/append-args-8.C | 93 +++++++++++++++++++++++++++++++ 7 files changed, 117 insertions(+), 21 deletions(-) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 07500fa2b21..1e82a7337be 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -8055,6 +8055,7 @@ extern tree omp_reduction_id (enum tree_code, tree, tree); extern tree cp_remove_omp_priv_cleanup_stmt (tree *, int *, void *); extern bool cp_check_omp_declare_reduction (tree); extern void finish_omp_declare_simd_methods (tree); +extern tree cp_finish_omp_init_prefer_type (tree); extern tree finish_omp_clauses (tree, enum c_omp_region_type); extern tree push_omp_privatization_clauses (bool); extern void pop_omp_privatization_clauses (tree); diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index 337ee65752e..a785d5e79cb 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -8652,6 +8652,9 @@ omp_declare_variant_finalize_one (tree decl, tree attr) = build_int_cst (TREE_TYPE (nargs), tree_to_uhwi (TREE_PURPOSE (nargs)) + 1); } + for (tree t = append_args_list; t; t = TREE_CHAIN (t)) + TREE_VALUE (t) + = cp_finish_omp_init_prefer_type (TREE_VALUE (t)); DECL_ATTRIBUTES (variant) = tree_cons ( get_identifier ("omp declare variant variant args"), TREE_VALUE (adjust_args_list), DECL_ATTRIBUTES (variant)); diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 39c0ee610bb..1f5ab4e3f71 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -12134,13 +12134,18 @@ tsubst_attribute (tree t, tree *decl_p, tree args, location_t match_loc = cp_expr_loc_or_input_loc (TREE_PURPOSE (chain)); tree ctx = copy_list (TREE_VALUE (val)); tree append_args_list = TREE_CHAIN (TREE_CHAIN (chain)); - if (append_args_list && TREE_VALUE (append_args_list)) + if (append_args_list + && TREE_VALUE (append_args_list) + && TREE_CHAIN (TREE_VALUE (append_args_list))) { - append_args_list = TREE_VALUE (TREE_VALUE (append_args_list)); + append_args_list = TREE_VALUE (append_args_list); + append_args_list = TREE_VALUE (TREE_CHAIN (append_args_list)); for (; append_args_list; append_args_list = TREE_CHAIN (append_args_list)) { tree pref_list = TREE_VALUE (append_args_list); + if (pref_list == NULL_TREE || TREE_CODE (pref_list) != TREE_LIST) + continue; tree fr_list = TREE_VALUE (pref_list); int len = TREE_VEC_LENGTH (fr_list); for (int i = 0; i < len; i++) diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index b390d663e24..7d8beb8833d 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -7466,17 +7466,17 @@ cp_oacc_check_attachments (tree c) /* Update OMP_CLAUSE_INIT_PREFER_TYPE in case template substitution happened. */ -static void -cp_omp_init_prefer_type_update (tree c) +tree +cp_finish_omp_init_prefer_type (tree pref_type) { if (processing_template_decl - || OMP_CLAUSE_INIT_PREFER_TYPE (c) == NULL_TREE - || TREE_CODE (OMP_CLAUSE_INIT_PREFER_TYPE (c)) != TREE_LIST) - return; + || pref_type == NULL_TREE + || TREE_CODE (pref_type) != TREE_LIST) + return pref_type; - tree t = TREE_PURPOSE (OMP_CLAUSE_INIT_PREFER_TYPE (c)); + tree t = TREE_PURPOSE (pref_type); char *str = const_cast<char *> (TREE_STRING_POINTER (t)); - tree fr_list = TREE_VALUE (OMP_CLAUSE_INIT_PREFER_TYPE (c)); + tree fr_list = TREE_VALUE (pref_type); int len = TREE_VEC_LENGTH (fr_list); int cnt = 0; @@ -7502,7 +7502,7 @@ cp_omp_init_prefer_type_update (tree c) || !tree_fits_shwi_p (value)) error_at (loc, "expected string literal or " - "constant integer expression instead of %qE", value); // FIXME of 'qE' and no 'loc'? + "constant integer expression instead of %qE", value); else { HOST_WIDE_INT n = tree_to_shwi (value); @@ -7531,7 +7531,7 @@ cp_omp_init_prefer_type_update (tree c) if (cnt >= len) break; } - OMP_CLAUSE_INIT_PREFER_TYPE (c) = t; + return t; } /* For all elements of CLAUSES, validate them vs OpenMP constraints. @@ -9690,7 +9690,8 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) break; case OMP_CLAUSE_INIT: init_seen = true; - cp_omp_init_prefer_type_update (c); + OMP_CLAUSE_INIT_PREFER_TYPE (c) + = cp_finish_omp_init_prefer_type (OMP_CLAUSE_INIT_PREFER_TYPE (c)); if (!OMP_CLAUSE_INIT_TARGETSYNC (c)) init_no_targetsync_clause = c; /* FALLTHRU */ diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc index 2364de081ff..422ad1265a6 100644 --- a/gcc/gimplify.cc +++ b/gcc/gimplify.cc @@ -4073,13 +4073,6 @@ modify_call_for_omp_dispatch (tree expr, tree dispatch_clauses, tree pref = TREE_VALUE (a); if (pref == NULL_TREE) pref = null_pointer_node; - else if (TREE_CODE (pref) == TREE_LIST) - { - /* FIXME: this is a bug in the C++ front end. */ - sorry_at (OMP_CLAUSE_LOCATION (dispatch_interop), - "%<prefer_type%> with template function"); - pref = null_pointer_node; - } else pref = build_fold_addr_expr (pref); init = build4 (ARRAY_REF, prefer_type_type, prefer_type, diff --git a/gcc/testsuite/g++.dg/gomp/append-args-1.C b/gcc/testsuite/g++.dg/gomp/append-args-1.C index 25ea4c28e4a..4e1390511b9 100644 --- a/gcc/testsuite/g++.dg/gomp/append-args-1.C +++ b/gcc/testsuite/g++.dg/gomp/append-args-1.C @@ -97,10 +97,10 @@ test (int *a, int *b) #pragma omp dispatch base99 (); - #pragma omp dispatch interop ( obj1 ) // { dg-message "sorry" } + #pragma omp dispatch interop ( obj1 ) base2<int *, omp_interop_t> (b, omp_interop_none); - #pragma omp dispatch interop ( obj1 ) // { dg-message "sorry" } + #pragma omp dispatch interop ( obj1 ) base2<int *, int *> (b, a); #pragma omp dispatch interop ( obj1 ) diff --git a/gcc/testsuite/g++.dg/gomp/append-args-8.C b/gcc/testsuite/g++.dg/gomp/append-args-8.C new file mode 100644 index 00000000000..7fbbfa88b88 --- /dev/null +++ b/gcc/testsuite/g++.dg/gomp/append-args-8.C @@ -0,0 +1,93 @@ +/* { dg-additional-options "-fdump-tree-gimple" } */ + +/* The following definitions are in omp_lib, which cannot be included +gcc/testsuite/g++.dg/gomp/append-args-1.C in gcc/testsuite/ */ + +#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; + + +template<typename T, typename T2, typename T3> +void repl2(T, T2, T3, T3); +#pragma omp declare variant(repl2) match(construct={dispatch}) adjust_args(need_device_ptr : y) \ + append_args(interop(target, targetsync, prefer_type(1)), \ + interop(prefer_type({fr(3), attr("ompx_nop")},{fr(2)},{attr("ompx_all")}))) +template<typename T, typename T2> +void base2(T x, T2 y); + + + +template<typename T, typename T2> +void repl3(T, T2, T2, T2, ...); +#pragma omp declare variant(repl3) match(construct={dispatch}) \ + append_args( interop(target, prefer_type("cuda", "hsa")), \ + interop(targetsync), \ + interop(prefer_type({attr("ompx_nop")})) ) +template<typename T> +void base3(T, ...); + + + + +float +test (int *a, int *b) +{ + omp_interop_t obj1, obj2; + float x, y; + + #pragma omp dispatch interop ( obj1 ) + base2<int *, int *> (b, a); + + #pragma omp dispatch nocontext(1) + base3<int*>(a, 1, 2, "abc"); + + #pragma omp dispatch + base3<int*>(a, 1, 2, "abc"); + + return x; +} + +/* { dg-final { scan-tree-dump-times "base3<int\\*> \\(a, 1, 2, \"abc\"\\);" 1 "gimple" } } */ + +/* { dg-final { scan-tree-dump-times "unsigned.* \\* interopobjs.\[0-9\]+\\\[1\\\];" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "unsigned.* \\* interopobjs.\[0-9\]+\\\[3\\\];" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "int tgt_tgtsync.\[0-9\]+\\\[1\\\];" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "int tgt_tgtsync.\[0-9\]+\\\[3\\\];" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "const char \\* pref_type.\[0-9\]+\\\[1\\\];" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "const char \\* pref_type.\[0-9\]+\\\[3\\\];" 1 "gimple" } } */ + +/* { dg-final { scan-tree-dump-times "interopobjs.\[0-9\]+\\\[0\\\] = &interop\\.\[0-9\]+;" 2 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "interopobjs.\[0-9\]+\\\[1\\\] = &interop\\.\[0-9\]+;" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "interopobjs.\[0-9\]+\\\[2\\\] = &interop\\.\[0-9\]+;" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "tgt_tgtsync.\[0-9\]+\\\[0\\\] = 0;" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "tgt_tgtsync.\[0-9\]+\\\[0\\\] = 1;" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "tgt_tgtsync.\[0-9\]+\\\[1\\\] = 2;" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "tgt_tgtsync.\[0-9\]+\\\[2\\\] = 0;" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "pref_type.\[0-9\]+\\\[0\\\] = \"\\\\x80\\\\x03\\\\x80ompx_nop\\\\x00\\\\x00\\\\x80\\\\x02\\\\x80\\\\x00\\\\x80\\\\x80ompx_all\\\\x00\\\\x00\";" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "pref_type.\[0-9\]+\\\[0\\\] = \"\\\\x80\\\\x01\\\\x80\\\\x00\\\\x80\\\\x07\\\\x80\\\\x00\";" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "pref_type.\[0-9\]+\\\[1\\\] = 0B;" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "pref_type.\[0-9\]+\\\[2\\\] = \"\\\\x80\\\\x80ompx_nop\\\\x00\\\\x00\";" 1 "gimple" } } */ + + +/* { dg-final { scan-tree-dump-times "D\.\[0-9\]+ = __builtin_omp_get_interop_int \\(obj1, -5, 0B\\);" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "D\.\[0-9\]+ = __builtin_omp_get_default_device \\(\\);" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "__builtin_omp_set_default_device \\(D\.\[0-9\]+\\);" 2 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "D\.\[0-9\]+ = __builtin_omp_get_mapped_ptr \\(a, D\.\[0-9\]+\\);" 1 "gimple" } } */ + +/* { dg-final { scan-tree-dump-times "__builtin_GOMP_interop \\(D\.\[0-9\]+, 1, interopobjs\.\[0-9\], tgt_tgtsync\.\[0-9\]+, pref_type.2, 0, 0B, 0, 0B, 0, 0B\\);" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "repl2<int\\*, int\\*, omp_interop_t> \\(b, D\.\[0-9\]+, obj1, interop\.\[0-9\]+\\);" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "__builtin_GOMP_interop \\(D\.\[0-9\]+, 0, 0B, 0B, 0B, 0, 0B, 1, interopobjs\.\[0-9\]+, 0, 0B\\);" 1 "gimple" } } */ + + +/* { dg-final { scan-tree-dump-times "__builtin_GOMP_interop \\(-5, 0, 0B, 0B, 0B, 0, 0B, 3, interopobjs\.\[0-9\]+, 0, 0B\\);" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "repl3<int\\*, omp_interop_t> \\(a, interop\.\[0-9\]+3, interop\.\[0-9\]+2, interop\.\[0-9\]+, 1, 2, \"abc\"\\);" 1 "gimple" } } */ +/* { dg-final { scan-tree-dump-times "__builtin_GOMP_interop \\(-5, 3, interopobjs\.\[0-9\]+, tgt_tgtsync\.\[0-9\]+, pref_type\.\[0-9\]+, 0, 0B, 0, 0B, 0, 0B\\);" 1 "gimple" } } */