[gcc r17-2401] OpenMP: Handle 'device_type(nohost)' on 'target'

Tobias Burnus via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:97a43fc4dbc5cfb1174a13313dda7637c838d110

commit r17-2401-g97a43fc4dbc5cfb1174a13313dda7637c838d110
Author: Tobias Burnus <[email protected]>
Date:   Tue Jul 14 21:44:48 2026 +0200

    OpenMP: Handle 'device_type(nohost)' on 'target'
    
    The parsing support was already there, this just adds code to handle
    'nohost' in the middle end.
    
    That's handled by adding if-else code to the target's structure block
    using the omp_is_initial_device builtin in the condition that is
    replaced by a constant (late) during compilation. Thus, with optimization
    turned on, only the error message or the target body remains for the host
    and the nonhost region, respectively.
    
    Note that 'device_type(host)' is not yet implemented.
    
    Note also there is no change to implicit handling, i.e. functions called
    in the region will implicitly 'declare target' with 'device_type(any)',
    i.e. there is no attempt made to add those with 'nohost', which is also
    the most sensible.
    
    gcc/ChangeLog:
    
            * gimplify.cc (gimplify_omp_workshare): Handle 'device_type(nohost)'
            on 'target'.
            * omp-low.cc (lower_omp_target): Remove sorry for this case.
    
    libgomp/ChangeLog:
    
            * error.c (GOMP_error): When passing msglen == (size_t) -2,
            do not show 'error directive encountered:' in the message.
            * libgomp.texi (Implementation Status): Mark target + device_type
            as partially implemented.
            * testsuite/libgomp.c/target-device-type-1.c: New test.
            * testsuite/libgomp.c/target-device-type-2.c: New test.
    
    gcc/testsuite/ChangeLog:
    
            * c-c++-common/gomp/target-device-type-1.c: Update dg-sorry
            as now only device_type(host) remains unimplemented.
            * gfortran.dg/gomp/target-device-type-1.f90: Likewise.

Diff:
---
 gcc/gimplify.cc                                    | 40 ++++++++++++++++++++++
 gcc/omp-low.cc                                     |  4 +--
 .../c-c++-common/gomp/target-device-type-1.c       |  4 +--
 .../gfortran.dg/gomp/target-device-type-1.f90      |  4 +--
 libgomp/error.c                                    |  6 ++++
 libgomp/libgomp.texi                               |  2 +-
 libgomp/testsuite/libgomp.c/target-device-type-1.c | 21 ++++++++++++
 libgomp/testsuite/libgomp.c/target-device-type-2.c | 27 +++++++++++++++
 8 files changed, 101 insertions(+), 7 deletions(-)

diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index 6c5d182ffab2..223b55b7e93e 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -18990,6 +18990,46 @@ gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
       stmt = gimple_build_omp_scope (body, OMP_CLAUSES (expr));
       break;
     case OMP_TARGET:
+      /* Handle 'device_type(nohost)'.  */
+      if (tree c = omp_find_clause (OMP_CLAUSES (expr), OMP_CLAUSE_DEVICE_TYPE))
+	if (OMP_CLAUSE_DEVICE_TYPE_KIND (c) == OMP_CLAUSE_DEVICE_TYPE_NOHOST)
+	  {
+	    location_t loc = gimple_location (body);
+	    tree fn = builtin_decl_explicit (BUILT_IN_OMP_IS_INITIAL_DEVICE);
+	    fn = build_call_expr_loc (loc, fn, 0);
+	    tree err = builtin_decl_explicit (BUILT_IN_GOMP_ERROR);
+	    const char *str = "Executing device-type 'nohost' target region "
+			      "on the host";
+	    const int len = strlen (str) + 1;
+	    tree msg = build_string (len, str);
+	    TREE_TYPE (msg) = build_array_type_nelts (char_type_node, len);
+	    TREE_READONLY (msg) = 1;
+	    TREE_STATIC (msg) = 1;
+	    msg = build_fold_addr_expr (msg);
+	    tree msglen = fold_build2 (MINUS_EXPR, size_type_node,
+				       build_all_ones_cst (size_type_node),
+				       size_one_node);
+	    err = build_call_expr_loc (loc, err, 2, msg, msglen);
+	    tree l1 = create_artificial_label (UNKNOWN_LOCATION);
+	    tree l2 = create_artificial_label (UNKNOWN_LOCATION);
+	    tree l3 = create_artificial_label (UNKNOWN_LOCATION);
+
+	    gimple_seq new_body = NULL;
+
+	    gimplify_expr (&fn, &new_body, NULL, is_gimple_val, fb_rvalue);
+	    gcond *cond = gimple_build_cond (NE_EXPR, fn,
+					     build_int_cst (TREE_TYPE (fn), 0),
+					     l1, l2);
+	    gimplify_seq_add_stmt (&new_body, cond);
+	    gimplify_seq_add_stmt (&new_body, gimple_build_label (l1));
+	    gimplify_and_add (err, &new_body);
+	    gimplify_seq_add_stmt (&new_body, gimple_build_goto (l3));
+	    gimplify_seq_add_stmt (&new_body, gimple_build_label (l2));
+	    gimple_seq_add_seq (&new_body, body);
+	    gimplify_seq_add_stmt (&new_body, gimple_build_label (l3));
+	    body = gimple_build_bind (NULL_TREE, new_body, make_node (BLOCK));
+	    gimple_set_location (body, loc);
+	  }
       stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_REGION,
 				      OMP_CLAUSES (expr), iterator_loops_seq);
       break;
diff --git a/gcc/omp-low.cc b/gcc/omp-low.cc
index c578e8ece49a..99f73e501c02 100644
--- a/gcc/omp-low.cc
+++ b/gcc/omp-low.cc
@@ -13287,9 +13287,9 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
 	case OMP_CLAUSE_DEVICE_TYPE:
 	  /* FIXME: Ensure that 'nohost' also has not implied before that
 	     'g->have_offload = true' or an implicit declare target.  */
-	  if (OMP_CLAUSE_DEVICE_TYPE_KIND (c) != OMP_CLAUSE_DEVICE_TYPE_ANY)
+	  if (OMP_CLAUSE_DEVICE_TYPE_KIND (c) == OMP_CLAUSE_DEVICE_TYPE_HOST)
 	    sorry_at (OMP_CLAUSE_LOCATION (c),
-		      "only the %<device_type(any)%> is supported");
+		      "the %<device_type(host)%> is not supported");
 	  break;
       case OMP_CLAUSE_USES_ALLOCATORS:
 	allocator = OMP_CLAUSE_USES_ALLOCATORS_ALLOCATOR (c);
diff --git a/gcc/testsuite/c-c++-common/gomp/target-device-type-1.c b/gcc/testsuite/c-c++-common/gomp/target-device-type-1.c
index e64349baae3e..758330436cd1 100644
--- a/gcc/testsuite/c-c++-common/gomp/target-device-type-1.c
+++ b/gcc/testsuite/c-c++-common/gomp/target-device-type-1.c
@@ -10,10 +10,10 @@ void f ()
 #pragma omp target device_type ( any )
   ;
 
-#pragma omp target device_type ( nohost )  // { dg-message "sorry, unimplemented: only the 'device_type\\(any\\)' is supported" }
+#pragma omp target device_type ( nohost )
   ;
 
-#pragma omp target device_type ( host )
+#pragma omp target device_type ( host )  // { dg-message "sorry, unimplemented: the 'device_type\\(host\\)' is not supported" }
   ;
 
 }
diff --git a/gcc/testsuite/gfortran.dg/gomp/target-device-type-1.f90 b/gcc/testsuite/gfortran.dg/gomp/target-device-type-1.f90
index be33bb6a19d7..164fc4f1fd60 100644
--- a/gcc/testsuite/gfortran.dg/gomp/target-device-type-1.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/target-device-type-1.f90
@@ -7,10 +7,10 @@
 !$omp target device_type ( any )
 !$omp end target
 
-!$omp target device_type ( nohost )  ! { dg-message "sorry, unimplemented: only the 'device_type\\(any\\)' is supported" }
+!$omp target device_type ( nohost )
 !$omp end target
 
-!$omp target device_type ( host )
+!$omp target device_type ( host )  ! { dg-message "sorry, unimplemented: the 'device_type\\(host\\)' is not supported" }
 !$omp end target
 
 end
diff --git a/libgomp/error.c b/libgomp/error.c
index cd7c98cf25ec..0fa311faeca1 100644
--- a/libgomp/error.c
+++ b/libgomp/error.c
@@ -105,11 +105,17 @@ GOMP_warning (const char *msg, size_t msglen)
     gomp_error ("error directive encountered");
 }
 
+/* Handle 'omp error' directive; for msglen == -2, it is used internally
+   by the compiler-generated code such that 'error directive encountered'
+   is not printed.  */
+
 void
 GOMP_error (const char *msg, size_t msglen)
 {
   if (msg && msglen == (size_t) -1)
     gomp_fatal ("fatal error: error directive encountered: %s", msg);
+  else if (msg && msglen == (size_t) -2)
+    gomp_fatal ("fatal error: %s", msg);
   else if (msg)
     {
       fputs ("\nlibgomp: fatal error: error directive encountered: ", stderr);
diff --git a/libgomp/libgomp.texi b/libgomp/libgomp.texi
index 5bbc856544ec..63c5cf475b7b 100644
--- a/libgomp/libgomp.texi
+++ b/libgomp/libgomp.texi
@@ -580,7 +580,7 @@ to address of matching mapped list item per 5.1, Sect. 2.21.7.2 @tab N @tab
       @code{target_data}, @code{target_exit_data} and @code{target_update}
       @tab N @tab
 @item New @code{device_type} clause to the @code{target} directive
-      @tab N @tab
+      @tab P @tab @code{device_type(host)} unsupported
 @item @code{target_data} as composite construct @tab N @tab
 @item @code{nowait} clause with reverse-offload @code{target} directives
       @tab N @tab
diff --git a/libgomp/testsuite/libgomp.c/target-device-type-1.c b/libgomp/testsuite/libgomp.c/target-device-type-1.c
new file mode 100644
index 000000000000..a1e1af6979ad
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/target-device-type-1.c
@@ -0,0 +1,21 @@
+/* { dg-do run { target offload_device } } */
+/* { dg-additional-options "-fdump-tree-gimple" } */
+
+int
+f (int *x)
+{
+  #pragma omp target device_type(nohost)
+    (*x)++;
+  return *x;
+}
+
+int
+main ()
+{
+  int i = 3;
+  if (f(&i) != 4)
+    __builtin_abort ();
+}
+
+/* { dg-final { scan-tree-dump "= __builtin_omp_is_initial_device \\(\\);" "gimple" } } */
+/* { dg-final { scan-tree-dump "__builtin_GOMP_error \\(\"Executing device-type ..nohost.. target region on the host\"," "gimple" } } */
diff --git a/libgomp/testsuite/libgomp.c/target-device-type-2.c b/libgomp/testsuite/libgomp.c/target-device-type-2.c
new file mode 100644
index 000000000000..37fa62216c93
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/target-device-type-2.c
@@ -0,0 +1,27 @@
+/* { dg-do run } */
+/* { dg-additional-options "-fdump-tree-gimple" } */
+
+#include <omp.h>
+
+int
+f (int *x)
+{
+  #pragma omp target device_type(nohost)
+    (*x)++;
+  return *x;
+}
+
+int
+main ()
+{
+  omp_set_default_device (omp_initial_device);
+  int i = 3;
+  if (f(&i) != 4)
+    __builtin_abort ();
+}
+
+/* { dg-final { scan-tree-dump "= __builtin_omp_is_initial_device \\(\\);" "gimple" } } */
+/* { dg-final { scan-tree-dump "__builtin_GOMP_error \\(\"Executing device-type ..nohost.. target region on the host\"," "gimple" } } */
+
+/* { dg-output "libgomp: fatal error: Executing device-type 'nohost' target region on the host" } */
+/* { dg-shouldfail "'nohost' target region on the host" } */
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.