OpenMP's adjust_args clause to 'declare variant' can request to convert a pointer to a device pointer in the call ('need_device_ptr').
The arguments are stored by their position in the argument list, but if hidden arguments get added - like C++'s 'this' pointer, the list if off by one. This patch fixes it for the 'this' pointer. Tested on x86_64-gnu-linux. Any comment, suggestion, remark before I push it? Tobias PS: I wonder whether any of the other ways to get hidden arguments (at the front) matter. For C++, I see the VTT parm and for Fortran the ENTRY master argument, but I don't yet understand whether that matters for 'declare variant' or not.
OpenMP/C++: Fix declare_variant's 'adjust_args' if there is a 'this' pointer [PR118321] The adjust_args clause is internally store as the i-th argument to the function, which fails if hidden arguments come before. This commit handles the C++ 'this' pointer by shifting the internal arg index by one. PR fortran/118321 gcc/cp/ChangeLog: * decl.cc (omp_declare_variant_finalize_one): Shift adjust_args index by one for non-static class function's 'this' pointer. gcc/testsuite/ChangeLog: * g++.dg/gomp/adjust-args-4.C: New test. gcc/cp/decl.cc | 19 ++++++++-- gcc/testsuite/g++.dg/gomp/adjust-args-4.C | 60 +++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 3 deletions(-) diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index ef887915ff1..af1b89fb8c9 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -8629,9 +8629,22 @@ omp_declare_variant_finalize_one (tree decl, tree attr) // Prepend adjust_args list to variant attributes tree adjust_args_list = TREE_CHAIN (TREE_CHAIN (chain)); if (adjust_args_list != NULL_TREE) - DECL_ATTRIBUTES (variant) = tree_cons ( - get_identifier ("omp declare variant variant args"), - TREE_VALUE (adjust_args_list), DECL_ATTRIBUTES (variant)); + { + if (DECL_NONSTATIC_MEMBER_P (variant) + && TREE_VALUE (adjust_args_list)) + { + /* Shift arg position for the added 'this' pointer. */ + /* Handle need_device_ptr */ + for (tree t = TREE_PURPOSE (TREE_VALUE (adjust_args_list)); + t; t = TREE_CHAIN (t)) + TREE_VALUE (t) + = build_int_cst (TREE_TYPE (t), + tree_to_uhwi (TREE_VALUE (t)) + 1); + } + DECL_ATTRIBUTES (variant) = tree_cons ( + get_identifier ("omp declare variant variant args"), + TREE_VALUE (adjust_args_list), DECL_ATTRIBUTES (variant)); + } } } else if (!processing_template_decl) diff --git a/gcc/testsuite/g++.dg/gomp/adjust-args-4.C b/gcc/testsuite/g++.dg/gomp/adjust-args-4.C new file mode 100644 index 00000000000..83100457e3e --- /dev/null +++ b/gcc/testsuite/g++.dg/gomp/adjust-args-4.C @@ -0,0 +1,60 @@ +/* { dg-additional-options "-fdump-tree-gimple" } */ + +/* PR fortran/118321. */ + +/* Check that adjust_args applies to the right argument, + if C++ inserts a 'this' pointer. */ + +struct t1 { + void f1(int *x, int *y, int *z); + #pragma omp declare variant(f1) match(construct={dispatch}) \ + adjust_args(need_device_ptr : y) + void g1(int *x, int *y, int *z); +}; + +struct t2 { + void f2(int *x, int *y, int *z); + #pragma omp declare variant(f2) match(construct={dispatch}) \ + adjust_args(need_device_ptr : x, y, z) + void g2(int *x, int *y, int *z); +}; + +struct t3 { + void f3(int *x, int *y, int *z); + #pragma omp declare variant(f3) match(construct={dispatch}) \ + adjust_args(nothing : x, y, z) + void g3(int *x, int *y, int *z); +}; + + +void test(int *a1, int *b1, int *c1, + int *a2, int *b2, int *c2, + int *a3, int *b3, int *c3) +{ + struct t1 s1; + struct t2 s2; + struct t3 s3; + + #pragma omp dispatch + s1.g1 (a1, b1, c1); + #pragma omp dispatch + s2.g2 (a2, b2, c2); + #pragma omp dispatch + s3.g3 (a3, b3, c3); +} + + +/* { dg-final { scan-tree-dump-times "D\.\[0-9\]+ = __builtin_omp_get_default_device \\(\\);" 2 "gimple" } } */ + +/* { dg-final { scan-tree-dump-times "__builtin_omp_get_mapped_ptr" 4 "gimple" } } */ + +/* { dg-final { scan-tree-dump "D\.\[0-9\]+ = __builtin_omp_get_mapped_ptr \\(b1, D\.\[0-9\]+\\);" "gimple" } } */ +/* { dg-final { scan-tree-dump "t1::f1 \\(&s1, a1, D\.\[0-9\]+, c1\\);" "gimple" } } */ + + +/* { dg-final { scan-tree-dump "D\.\[0-9\]+ = __builtin_omp_get_mapped_ptr \\(c2, D\.\[0-9\]+\\);" "gimple" } } */ +/* { dg-final { scan-tree-dump "D\.\[0-9\]+ = __builtin_omp_get_mapped_ptr \\(b2, D\.\[0-9\]+\\);" "gimple" } } */ +/* { dg-final { scan-tree-dump "D\.\[0-9\]+ = __builtin_omp_get_mapped_ptr \\(a2, D\.\[0-9\]+\\);" "gimple" } } */ +/* { dg-final { scan-tree-dump "t2::f2 \\(&s2, D\.\[0-9\]+, D\.\[0-9\]+, D\.\[0-9\]+\\);" "gimple" } } */ + +/* { dg-final { scan-tree-dump "t3::f3 \\(&s3, a3, b3, c3\\);" "gimple" } } */