[clang] 81cdf94 - [clang][OpenMP] Fix region nesting check for `scan` directive (#98386)

via cfe-commits cfe-commits at lists.llvm.org
Thu Jul 11 06:08:02 PDT 2024


Author: Krzysztof Parzyszek
Date: 2024-07-11T08:07:58-05:00
New Revision: 81cdf9472c347adeee91f39f661e06da77902c93

URL: https://github.com/llvm/llvm-project/commit/81cdf9472c347adeee91f39f661e06da77902c93
DIFF: https://github.com/llvm/llvm-project/commit/81cdf9472c347adeee91f39f661e06da77902c93.diff

LOG: [clang][OpenMP] Fix region nesting check for `scan` directive (#98386)

The previous check was inconsistent. For example, it would allow
```
#pragma omp target
#pragma omp parallel for
  for (...) {
#pragma omp scan
  }
```
but not
```
#pragma omp target parallel for
  for (...) {
#pragma omp scan
  }
```

Make the check conform to the wording on the specification.

Added: 
    

Modified: 
    clang/lib/Sema/SemaOpenMP.cpp
    clang/test/OpenMP/Inputs/nesting_of_regions.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index bc5c172f1390e..ef09e53077f47 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -4989,14 +4989,19 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
     OrphanSeen = ParentRegion == OMPD_unknown;
     Recommend = ShouldBeInTargetRegion;
   } else if (CurrentRegion == OMPD_scan) {
-    // OpenMP [2.16, Nesting of Regions]
-    // If specified, a teams construct must be contained within a target
-    // construct.
-    NestingProhibited =
-        SemaRef.LangOpts.OpenMP < 50 ||
-        (ParentRegion != OMPD_simd && ParentRegion != OMPD_for &&
-         ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for &&
-         ParentRegion != OMPD_parallel_for_simd);
+    if (SemaRef.LangOpts.OpenMP >= 50) {
+      SmallVector<OpenMPDirectiveKind, 4> LeafOrComposite;
+      std::ignore = getLeafOrCompositeConstructs(ParentRegion, LeafOrComposite);
+      // OpenMP spec 5.0 and 5.1 require scan to be directly enclosed by for,
+      // simd, or for simd. This has to take into account combined directives.
+      // In 5.2 this seems to be implied by the fact that the specified
+      // separated constructs are do, for, and simd.
+      OpenMPDirectiveKind Enclosing = LeafOrComposite.back();
+      NestingProhibited = Enclosing != OMPD_for && Enclosing != OMPD_simd &&
+                          Enclosing != OMPD_for_simd;
+    } else {
+      NestingProhibited = true;
+    }
     OrphanSeen = ParentRegion == OMPD_unknown;
     Recommend = ShouldBeInLoopSimdRegion;
   }

diff  --git a/clang/test/OpenMP/Inputs/nesting_of_regions.cpp b/clang/test/OpenMP/Inputs/nesting_of_regions.cpp
index 969ddfcce4cb0..985cdc0e19adc 100644
--- a/clang/test/OpenMP/Inputs/nesting_of_regions.cpp
+++ b/clang/test/OpenMP/Inputs/nesting_of_regions.cpp
@@ -5346,11 +5346,6 @@ void foo() {
   }
 #pragma omp target parallel for
   for (int i = 0; i < 10; ++i) {
-#pragma omp scan // expected-error {{region cannot be closely nested inside 'target parallel for' region}}
-    bar();
-  }
-#pragma omp target parallel for
-  for (int i = 0; i < 10; ++i) {
 #pragma omp taskwait
     bar();
   }
@@ -7146,7 +7141,7 @@ void foo() {
   }
 #pragma omp target simd
   for (int i = 0; i < 10; ++i) {
-#pragma omp scan // omp45-error {{OpenMP constructs may not be nested inside a simd region}} omp50-error {{region cannot be closely nested inside 'target simd' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, for simd, parallel for, or parallel for simd region?}} omp51-error {{region cannot be closely nested inside 'target simd' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, for simd, parallel for, or parallel for simd region?}}
+#pragma omp scan // omp45-error {{OpenMP constructs may not be nested inside a simd region}} omp50-error {{exactly one of 'inclusive' or 'exclusive' clauses is expected}} omp51-error {{exactly one of 'inclusive' or 'exclusive' clauses is expected}}
     bar();
   }
 #pragma omp target simd
@@ -14583,11 +14578,6 @@ void foo() {
   }
 #pragma omp target parallel for
   for (int i = 0; i < 10; ++i) {
-#pragma omp scan // expected-error {{region cannot be closely nested inside 'target parallel for' region}}
-    bar();
-  }
-#pragma omp target parallel for
-  for (int i = 0; i < 10; ++i) {
 #pragma omp taskwait
     bar();
   }
@@ -16685,7 +16675,7 @@ void foo() {
   }
 #pragma omp target simd
   for (int i = 0; i < 10; ++i) {
-#pragma omp scan // omp45-error {{OpenMP constructs may not be nested inside a simd region}} omp50-error {{region cannot be closely nested inside 'target simd' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, for simd, parallel for, or parallel for simd region?}} omp51-error {{region cannot be closely nested inside 'target simd' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, for simd, parallel for, or parallel for simd region?}}
+#pragma omp scan // omp45-error {{OpenMP constructs may not be nested inside a simd region}} omp50-error {{exactly one of 'inclusive' or 'exclusive' clauses is expected}} omp51-error {{exactly one of 'inclusive' or 'exclusive' clauses is expected}}
     bar();
   }
 #pragma omp target simd


        


More information about the cfe-commits mailing list