https://gcc.gnu.org/g:b57c24e76e6e752901c964395b8f6803a6d9f1f5

commit b57c24e76e6e752901c964395b8f6803a6d9f1f5
Author: Tobias Burnus <tbur...@baylibre.com>
Date:   Mon Jan 27 12:40:17 2025 +0100

    OpenMP: Enable has_device_addr clause for 'dispatch' in C/C++
    
    The 'has_device_addr' of 'dispatch' has to be seen in conjunction with the
    'need_device_addr' modifier to the 'adjust_args' clause of 'declare 
variant'.
    As the latter has not yet been implemented, 'has_device_addr' has no real
    effect. However, to prepare for 'need_device_addr' and as service to the 
user:
    
    For C, where 'need_device_addr' is not permitted (contrary to C++ and 
Fortran),
    a note is output when then the user tries to use it (alongside the existing
    error that either 'nothing' or 'need_device_ptr' was expected).
    
    And, on the ME side, is is lightly handled by diagnosing when - for the
    same argument - there is a mismatch between the variant's adjust_args
    'need_device_ptr' modifier and dispatch having an 'has_device_addr' clause
    (or likewise for need_device_addr with is_device_ptr) as, according to the
    spec, those are completely separate.
    Thus, 'dispatch' will still do the host to device pointer conversion for
    a 'need_device_ptr' argument, even if it appeared in a 'has_device_addr'
    clause.
    
    gcc/c/ChangeLog:
    
            * c-parser.cc (OMP_DISPATCH_CLAUSE_MASK): Add has_device_addr 
clause.
            (c_finish_omp_declare_variant): Add an 'inform' telling the user 
that
            'need_device_addr' is invalid for C.
    
    gcc/cp/ChangeLog:
    
            * parser.cc (OMP_DISPATCH_CLAUSE_MASK): Add has_device_addr clause.
    
    gcc/ChangeLog:
    
            * gimplify.cc (gimplify_call_expr): When handling OpenMP's dispatch,
            add diagnostic when there is a ptr vs. addr mismatch between
            need_device_{addr,ptr} and {is,has}_device_{ptr,addr}, respectively.
    
    gcc/testsuite/ChangeLog:
    
            * c-c++-common/gomp/adjust-args-3.c: New test.
            * gcc.dg/gomp/adjust-args-2.c: New test.
    
    (cherry picked from commit 2cbb2408a830a63fbd901a4da3bfd341cec4b6ef)

Diff:
---
 gcc/ChangeLog.omp                               |  9 +++
 gcc/c/ChangeLog.omp                             |  9 +++
 gcc/c/c-parser.cc                               |  4 ++
 gcc/cp/ChangeLog.omp                            |  7 ++
 gcc/cp/parser.cc                                |  1 +
 gcc/gimplify.cc                                 | 76 ++++++++++++++++------
 gcc/testsuite/ChangeLog.omp                     |  8 +++
 gcc/testsuite/c-c++-common/gomp/adjust-args-3.c | 85 +++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/gomp/adjust-args-2.c       |  5 ++
 9 files changed, 186 insertions(+), 18 deletions(-)

diff --git a/gcc/ChangeLog.omp b/gcc/ChangeLog.omp
index e83fe6afebb4..36e1767e841e 100644
--- a/gcc/ChangeLog.omp
+++ b/gcc/ChangeLog.omp
@@ -1,3 +1,12 @@
+2025-01-27  Tobias Burnus  <tbur...@baylibre.com>
+
+       Backported from master:
+       2024-12-12  Tobias Burnus  <tbur...@baylibre.com>
+
+       * gimplify.cc (gimplify_call_expr): When handling OpenMP's dispatch,
+       add diagnostic when there is a ptr vs. addr mismatch between
+       need_device_{addr,ptr} and {is,has}_device_{ptr,addr}, respectively.
+
 2025-01-27  Tobias Burnus  <tbur...@baylibre.com>
 
        Backported from master:
diff --git a/gcc/c/ChangeLog.omp b/gcc/c/ChangeLog.omp
index a19c27f82634..cf0e23a0a582 100644
--- a/gcc/c/ChangeLog.omp
+++ b/gcc/c/ChangeLog.omp
@@ -1,3 +1,12 @@
+2025-01-27  Tobias Burnus  <tbur...@baylibre.com>
+
+       Backported from master:
+       2024-12-12  Tobias Burnus  <tbur...@baylibre.com>
+
+       * c-parser.cc (OMP_DISPATCH_CLAUSE_MASK): Add has_device_addr clause.
+       (c_finish_omp_declare_variant): Add an 'inform' telling the user that
+       'need_device_addr' is invalid for C.
+
 2025-01-27  Tobias Burnus  <tbur...@baylibre.com>
 
        Backported from master:
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index 4c1cead30248..acb07c869db1 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -25049,6 +25049,7 @@ c_parser_omp_dispatch_body (c_parser *parser)
    | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)                           
\
    | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOVARIANTS)                       
\
    | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOCONTEXT)                        
\
+   | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR)                  
\
    | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INTEROP)                          
\
    | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR)                    
\
    | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
@@ -26780,6 +26781,9 @@ c_finish_omp_declare_variant (c_parser *parser, tree 
fndecl, tree parms)
                {
                  error_at (c_parser_peek_token (parser)->location,
                            "expected %<nothing%> or %<need_device_ptr%>");
+                 if (strcmp (p, "need_device_addr") == 0)
+                   inform (c_parser_peek_token (parser)->location,
+                           "%<need_device_addr%> is not valid for C");
                  goto fail;
                }
            }
diff --git a/gcc/cp/ChangeLog.omp b/gcc/cp/ChangeLog.omp
index feb5fbb0b09d..0ea0b84c51a6 100644
--- a/gcc/cp/ChangeLog.omp
+++ b/gcc/cp/ChangeLog.omp
@@ -1,3 +1,10 @@
+2025-01-27  Tobias Burnus  <tbur...@baylibre.com>
+
+       Backported from master:
+       2024-12-12  Tobias Burnus  <tbur...@baylibre.com>
+
+       * parser.cc (OMP_DISPATCH_CLAUSE_MASK): Add has_device_addr clause.
+
 2025-01-27  Tobias Burnus  <tbur...@baylibre.com>
 
        Backported from master:
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 7d65fc2fa674..042a5a460e3a 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -50191,6 +50191,7 @@ cp_parser_omp_dispatch_body (cp_parser *parser)
    | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)                           
\
    | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOVARIANTS)                       
\
    | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOCONTEXT)                        
\
+   | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR)                  
\
    | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INTEROP)                          
\
    | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR)                    
\
    | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index cd9bb8d701e1..cfb0114c3414 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -4393,27 +4393,39 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, 
fallback_t fallback)
                        arg_types = TREE_CHAIN (arg_types);
 
                      bool need_device_ptr = false;
-                     for (tree arg
-                          = TREE_PURPOSE (TREE_VALUE (adjust_args_list));
-                          arg != NULL; arg = TREE_CHAIN (arg))
-                       {
-                         if (TREE_VALUE (arg)
-                             && TREE_CODE (TREE_VALUE (arg)) == INTEGER_CST
-                             && wi::eq_p (i, wi::to_wide (TREE_VALUE (arg))))
-                           {
-                             need_device_ptr = true;
-                             break;
-                           }
-                       }
+                     bool need_device_addr = false;
+                     for (int need_addr = 0; need_addr <= 1; need_addr++)
+                       for (tree arg = need_addr
+                                       ? TREE_VALUE (TREE_VALUE (
+                                           adjust_args_list))
+                                       : TREE_PURPOSE (TREE_VALUE (
+                                           adjust_args_list));
+                            arg != NULL; arg = TREE_CHAIN (arg))
+                         {
+                           if (TREE_VALUE (arg)
+                               && TREE_CODE (TREE_VALUE (arg)) == INTEGER_CST
+                               && wi::eq_p (i, wi::to_wide (TREE_VALUE (arg))))
+                             {
+                               if (need_addr)
+                                 need_device_addr = true;
+                               else
+                                 need_device_ptr = true;
+                               break;
+                             }
+                         }
 
-                     if (need_device_ptr)
+                     if (need_device_ptr || need_device_addr)
                        {
                          bool is_device_ptr = false;
+                         bool has_device_addr = false;
+
                          for (tree c = gimplify_omp_ctxp->clauses; c;
                               c = TREE_CHAIN (c))
                            {
-                             if (OMP_CLAUSE_CODE (c)
-                                 == OMP_CLAUSE_IS_DEVICE_PTR)
+                             if ((OMP_CLAUSE_CODE (c)
+                                  == OMP_CLAUSE_IS_DEVICE_PTR)
+                                 || (OMP_CLAUSE_CODE (c)
+                                     == OMP_CLAUSE_HAS_DEVICE_ADDR))
                                {
                                  tree decl1 = DECL_NAME (OMP_CLAUSE_DECL (c));
                                  tree decl2
@@ -4424,15 +4436,43 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, 
fallback_t fallback)
                                      || TREE_CODE (decl2) == PARM_DECL)
                                    {
                                      decl2 = DECL_NAME (decl2);
-                                     if (decl1 == decl2)
-                                       is_device_ptr = true;
+                                     if (decl1 == decl2
+                                         && (OMP_CLAUSE_CODE (c)
+                                             == OMP_CLAUSE_IS_DEVICE_PTR))
+                                       {
+                                         if (need_device_addr)
+                                           warning_at (
+                                             OMP_CLAUSE_LOCATION (c),
+                                             OPT_Wopenmp,
+                                             "%<is_device_ptr%> for %qD does"
+                                             " not imply %<has_device_addr%> "
+                                             "required for "
+                                             "%<need_device_addr%>",
+                                              OMP_CLAUSE_DECL (c));
+                                         is_device_ptr = true;
+                                       }
+                                     else if (decl1 == decl2)
+                                       {
+                                         if (need_device_ptr)
+                                           warning_at (
+                                             OMP_CLAUSE_LOCATION (c),
+                                             OPT_Wopenmp,
+                                             "%<has_device_addr%> for %qD does"
+                                             " not imply %<is_device_ptr%> "
+                                             "required for "
+                                             "%<need_device_ptr%>",
+                                             OMP_CLAUSE_DECL (c));
+                                         has_device_addr = true;
+                                       }
                                    }
                                }
                              else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE)
                                device_num = OMP_CLAUSE_OPERAND (c, 0);
                            }
 
-                         if (variant_substituted_p && !is_device_ptr)
+                         if (variant_substituted_p
+                             && ((need_device_ptr && !is_device_ptr)
+                                 || (need_device_addr && !has_device_addr)))
                            {
                              if (device_num == NULL_TREE)
                                {
diff --git a/gcc/testsuite/ChangeLog.omp b/gcc/testsuite/ChangeLog.omp
index bd3d806ad08a..35da06819a3e 100644
--- a/gcc/testsuite/ChangeLog.omp
+++ b/gcc/testsuite/ChangeLog.omp
@@ -1,3 +1,11 @@
+2025-01-27  Tobias Burnus  <tbur...@baylibre.com>
+
+       Backported from master:
+       2024-12-12  Tobias Burnus  <tbur...@baylibre.com>
+
+       * c-c++-common/gomp/adjust-args-3.c: New test.
+       * gcc.dg/gomp/adjust-args-2.c: New test.
+
 2025-01-27  Tobias Burnus  <tbur...@baylibre.com>
 
        Backported from master:
diff --git a/gcc/testsuite/c-c++-common/gomp/adjust-args-3.c 
b/gcc/testsuite/c-c++-common/gomp/adjust-args-3.c
new file mode 100644
index 000000000000..f62272cfb019
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/adjust-args-3.c
@@ -0,0 +1,85 @@
+/* { dg-additional-options "-fdump-tree-gimple" } */
+
+// Do diagnostic check / dump check only;
+// Note: this test should work as run-test as well.
+
+#if 0
+  #include <omp.h>
+#else
+  #ifdef __cplusplus
+  extern "C" {
+  #endif
+    extern int omp_get_default_device ();
+    extern int omp_get_num_devices ();
+  #ifdef __cplusplus
+  }
+  #endif
+#endif
+
+
+void f(int *x, int *y);
+#pragma omp declare variant(f) adjust_args(need_device_ptr: x, y) 
match(construct={dispatch})
+void g(int *x, int *y);
+
+void
+sub (int *a, int *b)
+{
+  // The has_device_addr is a bit questionable as the caller is not actually
+  // passing a device address - but we cannot pass one because of the
+  // following:
+  //
+  // As for 'b' need_device_ptr has been specified and 'b' is not
+  // in the semantic requirement set 'is_device_ptr' (and only in 
'has_device_addr')
+  // "the argument is converted in the same manner that a use_device_ptr clause
+  //  on a target_data construct converts its pointer"
+  #pragma omp dispatch is_device_ptr(a), has_device_addr(b)  /* { dg-warning 
"'has_device_addr' for 'b' does not imply 'is_device_ptr' required for 
'need_device_ptr' \\\[-Wopenmp\\\]" } */
+    g(a, b);
+}
+
+void
+f(int *from, int *to)
+{
+  static int cnt = 0;
+  cnt++;
+  if (cnt >= 3)
+    {
+      if (omp_get_default_device () != -1
+          && omp_get_default_device () < omp_get_num_devices ())
+        {
+         // On offload device but not mapped
+         if (from != (void *)0L) // Not mapped
+           __builtin_abort ();
+        }
+      else if (from[0] != 5)
+        __builtin_abort ();
+      return;
+    }
+  #pragma omp target is_device_ptr(from, to)
+  {
+    to[0] = from[0] * 10;
+    to[1] = from[1] * 10;
+  }
+}
+
+int
+main ()
+{
+  int A[2], B[2] = {123, 456}, C[1] = {5};
+  int *p = A;
+  #pragma omp target enter data map(A, B)
+
+  /* Note: We don't add  'use_device_addr(B)' here;
+     if we do, it will fail with an illegal memory access (why?).  */
+  #pragma omp target data use_device_ptr(p)
+    {
+      sub(p, B);
+      sub(C, B); /* C is not mapped -> 'from' ptr == NULL  */
+    }
+
+  #pragma omp target exit data map(A, B)
+}
+
+// { dg-final { scan-tree-dump-times "#pragma omp dispatch 
has_device_addr\\(b\\) is_device_ptr\\(a\\)" 1 "gimple" } }
+// { dg-final { scan-tree-dump-times "__builtin_omp_get_mapped_ptr" 1 "gimple" 
} }
+// { dg-final { scan-tree-dump-times "D\\.\[0-9\]+ = 
__builtin_omp_get_mapped_ptr \\(b" 1 "gimple" } }
+// { dg-final { scan-tree-dump-times "f \\(a, D\\.\[0-9\]+\\);" 1 "gimple" } }
diff --git a/gcc/testsuite/gcc.dg/gomp/adjust-args-2.c 
b/gcc/testsuite/gcc.dg/gomp/adjust-args-2.c
new file mode 100644
index 000000000000..ee4feffb2aa3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gomp/adjust-args-2.c
@@ -0,0 +1,5 @@
+void f(int *);
+#pragma omp declare variant(f) adjust_args(need_device_addr: x)
+/* { dg-error "expected 'nothing' or 'need_device_ptr'" "" { target *-*-* } 
.-1 }  */
+/* { dg-note "'need_device_addr' is not valid for C" "" { target *-*-* } .-2 } 
 */
+void g(int *x);

Reply via email to