[Openmp-commits] [openmp] 3c14034 - [Flang][OpenMP] Validate `omp_initial_device` `omp_invalid_device` as device IDs (#193669)
via Openmp-commits
openmp-commits at lists.llvm.org
Tue Apr 28 09:01:13 PDT 2026
Author: Amit Tiwari
Date: 2026-04-28T21:31:04+05:30
New Revision: 3c14034c55a296306ad0ea4990f0f1b34e9e5d6e
URL: https://github.com/llvm/llvm-project/commit/3c14034c55a296306ad0ea4990f0f1b34e9e5d6e
DIFF: https://github.com/llvm/llvm-project/commit/3c14034c55a296306ad0ea4990f0f1b34e9e5d6e.diff
LOG: [Flang][OpenMP] Validate `omp_initial_device` `omp_invalid_device` as device IDs (#193669)
As per OpenMP 5.2/6.0 the below are valid device values in a `#pragma
omp target` directive:
omp_initial_device (-1) -> refers to the host CPU.
omp_invalid_device (-2) -> an intentionally invalid device, used to
trigger a runtime error.
For the 2 values discussed above flang fails with:
```
error: The device expression of the DEVICE clause must be a positive integer expression
!$OMP TARGET DEVICE(-1)
error: Must have INTEGER type, but is REAL(4)
!$OMP TARGET DEVICE(OMP_INVALID_DEVICE)
```
Issue: https://github.com/llvm/llvm-project/issues/192989
Added:
flang/test/Semantics/OpenMP/device-omp-initial-invalid.f90
flang/test/Semantics/OpenMP/device-pre-52.f90
Modified:
flang/lib/Semantics/check-omp-structure.cpp
flang/test/Semantics/OpenMP/device-constructs.f90
openmp/module/omp_lib.F90.var
openmp/module/omp_lib.h.var
Removed:
################################################################################
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 713e1d02e21c0..114a098da15f6 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -4735,8 +4735,20 @@ 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");
+ // 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};
if (OmpVerifyModifiers(deviceClause, llvm::omp::OMPC_device,
diff --git a/flang/test/Semantics/OpenMP/device-constructs.f90 b/flang/test/Semantics/OpenMP/device-constructs.f90
index a41c461874b90..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
@@ -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
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
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
More information about the Openmp-commits
mailing list