https://gcc.gnu.org/g:22635416838bb27cbf8cc02487be4cf47d52ddf8

commit 22635416838bb27cbf8cc02487be4cf47d52ddf8
Author: Tobias Burnus <tbur...@baylibre.com>
Date:   Tue Jan 28 13:03:07 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-*.
    
    (cherry picked from commit 1bb367b5cdb9fa77733d87d97483fb57480ef6fe)

Diff:
---
 gcc/ChangeLog.omp                               | 13 +++++
 gcc/builtin-types.def                           |  2 +
 gcc/fortran/ChangeLog.omp                       |  7 +++
 gcc/fortran/types.def                           |  2 +
 gcc/gimplify.cc                                 | 67 +++++++++++++++++++------
 gcc/omp-builtins.def                            |  2 +
 gcc/testsuite/ChangeLog.omp                     | 11 ++++
 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 +--
 12 files changed, 173 insertions(+), 50 deletions(-)

diff --git a/gcc/ChangeLog.omp b/gcc/ChangeLog.omp
index 5b0c134daea1..e9cd023b7b4c 100644
--- a/gcc/ChangeLog.omp
+++ b/gcc/ChangeLog.omp
@@ -1,3 +1,16 @@
+2025-01-28  Tobias Burnus  <tbur...@baylibre.com>
+
+       Backported from master:
+       2025-01-09  Tobias Burnus  <tbur...@baylibre.com>
+
+       * 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.
+
 2025-01-28  Tobias Burnus  <tbur...@baylibre.com>
 
        Backported from master:
diff --git a/gcc/builtin-types.def b/gcc/builtin-types.def
index d31b15f0aa9d..9ddc0ed33820 100644
--- a/gcc/builtin-types.def
+++ b/gcc/builtin-types.def
@@ -686,6 +686,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/ChangeLog.omp b/gcc/fortran/ChangeLog.omp
index 352d37efdcb9..ff5104d97a27 100644
--- a/gcc/fortran/ChangeLog.omp
+++ b/gcc/fortran/ChangeLog.omp
@@ -1,3 +1,10 @@
+2025-01-28  Tobias Burnus  <tbur...@baylibre.com>
+
+       Backported from master:
+       2025-01-09  Tobias Burnus  <tbur...@baylibre.com>
+
+       * types.def (BT_FN_PTRMODE_PTR_INT_PTR): Add.
+
 2025-01-28  Tobias Burnus  <tbur...@baylibre.com>
 
        Backported from master:
diff --git a/gcc/fortran/types.def b/gcc/fortran/types.def
index ff6b98b6b00f..d1b11c4bfbeb 100644
--- a/gcc/fortran/types.def
+++ b/gcc/fortran/types.def
@@ -135,6 +135,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 f555b548d1e8..58952f143455 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -4353,7 +4353,6 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, 
fallback_t fallback)
       && 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",
@@ -4386,8 +4385,9 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, 
fallback_t fallback)
          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)
        {
@@ -4407,9 +4407,15 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, 
fallback_t fallback)
                      "%<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);
@@ -4452,6 +4458,12 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, 
fallback_t fallback)
          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)
@@ -4462,9 +4474,6 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, 
fallback_t fallback)
              TREE_CHAIN (t) = gimplify_omp_ctxp->clauses;
              gimplify_omp_ctxp->clauses = t;
            }
-
-         /* Re-run.  */
-         return GS_OK;
        }
     }
 
@@ -4489,9 +4498,6 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, 
fallback_t fallback)
 
                  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++)
@@ -19583,11 +19589,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);
@@ -19598,7 +19635,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 5e52180bef21..6e3f0a65c79b 100644
--- a/gcc/omp-builtins.def
+++ b/gcc/omp-builtins.def
@@ -88,6 +88,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/ChangeLog.omp b/gcc/testsuite/ChangeLog.omp
index 45b16708e424..55877e07a456 100644
--- a/gcc/testsuite/ChangeLog.omp
+++ b/gcc/testsuite/ChangeLog.omp
@@ -1,3 +1,14 @@
+2025-01-28  Tobias Burnus  <tbur...@baylibre.com>
+
+       Backported from master:
+       2025-01-09  Tobias Burnus  <tbur...@baylibre.com>
+
+       * 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-*.
+
 2025-01-28  Tobias Burnus  <tbur...@baylibre.com>
 
        Backported from master:
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 278ffe1c837a..e58796e505eb 100644
--- a/gcc/testsuite/c-c++-common/gomp/append-args-1.c
+++ b/gcc/testsuite/c-c++-common/gomp/append-args-1.c
@@ -72,9 +72,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 20fe3c06181c..7e08a2df9bb2 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 e2372eb3cab2..118dbd2663e6 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 0b8fdfab5ca8..a34420e3d6fb 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 f3fabf22415f..427c64077964 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);

Reply via email to