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

Reply via email to