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" } } */