[Openmp-commits] [flang] [openmp] [Flang][OpenMP] Validate `omp_initial_device` `omp_invalid_device` as device IDs (PR #193669)

Amit Tiwari via Openmp-commits openmp-commits at lists.llvm.org
Fri Apr 24 00:02:51 PDT 2026


https://github.com/amitamd7 updated https://github.com/llvm/llvm-project/pull/193669

>From 9733271879a451b310c4944cdef568c796a73c3e Mon Sep 17 00:00:00 2001
From: amtiwari <amtiwari at amd.com>
Date: Wed, 22 Apr 2026 13:21:17 -0400
Subject: [PATCH 1/3] flang_device_ids_fix

---
 flang/lib/Semantics/check-omp-structure.cpp | 8 ++++++--
 openmp/module/omp_lib.F90.var               | 3 +++
 openmp/module/omp_lib.h.var                 | 5 +++++
 3 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 8b5cd35929689..5bd05555913cf 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -4600,8 +4600,12 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Device &x) {
   const parser::OmpDeviceClause &deviceClause{x.v};
   const auto &device{std::get<parser::ScalarIntExpr>(deviceClause.t)};
   unsigned version{context_.langOptions().OpenMPVersion};
-  RequiresPositiveParameter(
-      llvm::omp::Clause::OMPC_device, device, "device expression");
+  if (const auto v{GetIntValue(device)}) {
+    if (*v < -2) {
+      context_.Say(GetContext().clauseSource,
+          "The device expression of the DEVICE clause must be a non-negative integer expression, 'omp_initial_device' (-1), or 'omp_invalid_device' (-2)"_err_en_US);
+    }
+  }
   llvm::omp::Directive dir{GetContext().directive};
 
   if (OmpVerifyModifiers(deviceClause, llvm::omp::OMPC_device,
diff --git a/openmp/module/omp_lib.F90.var b/openmp/module/omp_lib.F90.var
index 90d7e49ebf549..464056847ab92 100644
--- a/openmp/module/omp_lib.F90.var
+++ b/openmp/module/omp_lib.F90.var
@@ -102,6 +102,9 @@
         integer(kind=omp_sched_kind), parameter, public :: omp_sched_auto    = 4
         integer(kind=omp_sched_kind), parameter, public :: omp_sched_monotonic = int(Z'80000000', kind=omp_sched_kind)
 
+        integer (kind=omp_integer_kind), parameter, public :: omp_initial_device = -1
+        integer (kind=omp_integer_kind), parameter, public :: omp_invalid_device = -2
+
         integer (kind=omp_proc_bind_kind), parameter, public :: omp_proc_bind_false = 0
         integer (kind=omp_proc_bind_kind), parameter, public :: omp_proc_bind_true = 1
         integer (kind=omp_proc_bind_kind), parameter, public :: omp_proc_bind_master = 2
diff --git a/openmp/module/omp_lib.h.var b/openmp/module/omp_lib.h.var
index a50bb018c7cc3..e515c9434f120 100644
--- a/openmp/module/omp_lib.h.var
+++ b/openmp/module/omp_lib.h.var
@@ -79,6 +79,11 @@
       integer(kind=omp_sched_kind)omp_sched_monotonic
       parameter(omp_sched_monotonic=Z'80000000')
 
+      integer(kind=omp_integer_kind)omp_initial_device
+      parameter(omp_initial_device=-1)
+      integer(kind=omp_integer_kind)omp_invalid_device
+      parameter(omp_invalid_device=-2)
+
       integer(kind=omp_proc_bind_kind)omp_proc_bind_false
       parameter(omp_proc_bind_false=0)
       integer(kind=omp_proc_bind_kind)omp_proc_bind_true

>From 640b6d6c6e734b649d4ba6098ea9b0e7785f12a4 Mon Sep 17 00:00:00 2001
From: amtiwari <amtiwari at amd.com>
Date: Wed, 22 Apr 2026 13:26:40 -0400
Subject: [PATCH 2/3] sema-tests

---
 .../Semantics/OpenMP/device-constructs.f90    | 16 +++-
 .../OpenMP/device-omp-initial-invalid.f90     | 82 +++++++++++++++++++
 2 files changed, 96 insertions(+), 2 deletions(-)
 create mode 100644 flang/test/Semantics/OpenMP/device-omp-initial-invalid.f90

diff --git a/flang/test/Semantics/OpenMP/device-constructs.f90 b/flang/test/Semantics/OpenMP/device-constructs.f90
index a41c461874b90..5ab8f0bab1404 100644
--- a/flang/test/Semantics/OpenMP/device-constructs.f90
+++ b/flang/test/Semantics/OpenMP/device-constructs.f90
@@ -151,12 +151,24 @@ program main
   enddo
   !$omp end target data
 
-  !ERROR: The device expression of the DEVICE clause must be a positive integer expression
+  ! -2 is the reserved value omp_invalid_device (OpenMP 5.2+), so it is valid.
   !$omp target enter data map(alloc:A) device(-2)
 
-  !ERROR: The device expression of the DEVICE clause must be a positive integer expression
+  ! -2 is the reserved value omp_invalid_device (OpenMP 5.2+), so it is valid.
   !$omp target exit data map(delete:A) device(-2)
 
+  ! -1 is the reserved value omp_initial_device (OpenMP 5.2+), so it is valid.
+  !$omp target enter data map(alloc:A) device(-1)
+
+  ! -1 is the reserved value omp_initial_device (OpenMP 5.2+), so it is valid.
+  !$omp target exit data map(delete:A) device(-1)
+
+  !ERROR: The device expression of the DEVICE clause must be a non-negative integer expression, 'omp_initial_device' (-1), or 'omp_invalid_device' (-2)
+  !$omp target enter data map(alloc:A) device(-3)
+
+  !ERROR: The device expression of the DEVICE clause must be a non-negative integer expression, 'omp_initial_device' (-1), or 'omp_invalid_device' (-2)
+  !$omp target exit data map(delete:A) device(-3)
+
   !ERROR: At most one IF clause can appear on the TARGET ENTER DATA directive
   !$omp target enter data map(to:a) if(.true.) if(.false.)
 
diff --git a/flang/test/Semantics/OpenMP/device-omp-initial-invalid.f90 b/flang/test/Semantics/OpenMP/device-omp-initial-invalid.f90
new file mode 100644
index 0000000000000..6b76265bd96f9
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/device-omp-initial-invalid.f90
@@ -0,0 +1,82 @@
+! The predefined identifiers omp_initial_device (-1) and omp_invalid_device
+! (-2) from the OpenMP 5.2+ specification must be accepted as valid device
+! numbers in the DEVICE clause of target constructs.
+
+! REQUIRES: openmp_runtime
+
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags -fopenmp-version=52
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags -fopenmp-version=60
+
+program main
+  use omp_lib
+
+  real(8) :: arrayA(256)
+  integer :: N, dev
+  arrayA = 1.414d0
+  N = 256
+
+  ! Literal values allowed by the OpenMP 5.2 / 6.0 specification.
+  !$omp target device(-1)
+  do i = 1, N
+     arrayA(i) = 3.14d0
+  enddo
+  !$omp end target
+
+  !$omp target device(-2)
+  do i = 1, N
+     arrayA(i) = 3.14d0
+  enddo
+  !$omp end target
+
+  !$omp target device(0)
+  do i = 1, N
+     arrayA(i) = 3.14d0
+  enddo
+  !$omp end target
+
+  ! Using the predefined identifiers from the omp_lib module.
+  !$omp target device(omp_initial_device)
+  do i = 1, N
+     arrayA(i) = 3.14d0
+  enddo
+  !$omp end target
+
+  !$omp target device(omp_invalid_device)
+  do i = 1, N
+     arrayA(i) = 3.14d0
+  enddo
+  !$omp end target
+
+  ! Also accepted on target data and its data motion variants.
+  !$omp target data map(to: arrayA) device(omp_initial_device)
+  !$omp end target data
+
+  !$omp target data map(to: arrayA) device(omp_invalid_device)
+  !$omp end target data
+
+  !$omp target enter data map(alloc: arrayA) device(omp_initial_device)
+  !$omp target enter data map(alloc: arrayA) device(omp_invalid_device)
+
+  !$omp target exit data map(delete: arrayA) device(omp_initial_device)
+  !$omp target exit data map(delete: arrayA) device(omp_invalid_device)
+
+  !$omp target update to(arrayA) device(omp_initial_device)
+  !$omp target update to(arrayA) device(omp_invalid_device)
+
+  ! Runtime-determined values pass the semantic check.
+  dev = -1
+  !$omp target device(dev)
+  do i = 1, N
+     arrayA(i) = 3.14d0
+  enddo
+  !$omp end target
+
+  ! Values below -2 are still rejected.
+  !ERROR: The device expression of the DEVICE clause must be a non-negative integer expression, 'omp_initial_device' (-1), or 'omp_invalid_device' (-2)
+  !$omp target device(-3)
+  do i = 1, N
+     arrayA(i) = 3.14d0
+  enddo
+  !$omp end target
+
+end program main

>From 19599cdd84ff4cdb0ce3da92eaf4edb96499d3b6 Mon Sep 17 00:00:00 2001
From: amtiwari <amtiwari at amd.com>
Date: Fri, 24 Apr 2026 03:02:33 -0400
Subject: [PATCH 3/3] revised

---
 flang/lib/Semantics/check-omp-structure.cpp   | 16 ++++++---
 .../Semantics/OpenMP/device-constructs.f90    |  2 +-
 flang/test/Semantics/OpenMP/device-pre-52.f90 | 36 +++++++++++++++++++
 3 files changed, 49 insertions(+), 5 deletions(-)
 create mode 100644 flang/test/Semantics/OpenMP/device-pre-52.f90

diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 5bd05555913cf..375741848b986 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -4600,11 +4600,19 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Device &x) {
   const parser::OmpDeviceClause &deviceClause{x.v};
   const auto &device{std::get<parser::ScalarIntExpr>(deviceClause.t)};
   unsigned version{context_.langOptions().OpenMPVersion};
-  if (const auto v{GetIntValue(device)}) {
-    if (*v < -2) {
-      context_.Say(GetContext().clauseSource,
-          "The device expression of the DEVICE clause must be a non-negative integer expression, 'omp_initial_device' (-1), or 'omp_invalid_device' (-2)"_err_en_US);
+  // The predefined identifiers omp_initial_device (-1) and omp_invalid_device
+  // (-2) were introduced in OpenMP 5.2. Under earlier versions the device
+  // expression must be a non-negative integer.
+  if (version >= 52) {
+    if (const auto v{GetIntValue(device)}) {
+      if (*v < -2) {
+        context_.Say(GetContext().clauseSource,
+            "The device expression of the DEVICE clause must be a non-negative integer expression, 'omp_initial_device' (-1), or 'omp_invalid_device' (-2)"_err_en_US);
+      }
     }
+  } else {
+    RequiresPositiveParameter(
+        llvm::omp::Clause::OMPC_device, device, "device expression");
   }
   llvm::omp::Directive dir{GetContext().directive};
 
diff --git a/flang/test/Semantics/OpenMP/device-constructs.f90 b/flang/test/Semantics/OpenMP/device-constructs.f90
index 5ab8f0bab1404..db04e7db155ad 100644
--- a/flang/test/Semantics/OpenMP/device-constructs.f90
+++ b/flang/test/Semantics/OpenMP/device-constructs.f90
@@ -1,4 +1,4 @@
-! RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=51
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=52
 ! Check OpenMP clause validity for the following directives:
 !     2.10 Device constructs
 program main
diff --git a/flang/test/Semantics/OpenMP/device-pre-52.f90 b/flang/test/Semantics/OpenMP/device-pre-52.f90
new file mode 100644
index 0000000000000..f5356e80a0ba7
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/device-pre-52.f90
@@ -0,0 +1,36 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=50
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=51
+
+program main
+  real(8) :: arrayA(256)
+  integer :: N
+  arrayA = 1.414d0
+  N = 256
+
+  !ERROR: The device expression of the DEVICE clause must be a positive integer expression
+  !$omp target device(-1)
+  do i = 1, N
+     arrayA(i) = 3.14d0
+  enddo
+  !$omp end target
+
+  !ERROR: The device expression of the DEVICE clause must be a positive integer expression
+  !$omp target device(-2)
+  do i = 1, N
+     arrayA(i) = 3.14d0
+  enddo
+  !$omp end target
+
+  !ERROR: The device expression of the DEVICE clause must be a positive integer expression
+  !$omp target device(-3)
+  do i = 1, N
+     arrayA(i) = 3.14d0
+  enddo
+  !$omp end target
+
+  !$omp target device(0)
+  do i = 1, N
+     arrayA(i) = 3.14d0
+  enddo
+  !$omp end target
+end program main



More information about the Openmp-commits mailing list