[clang] [OpenMP][Clang] Handle unsupported inscan modifier for generic types (PR #79431)

via cfe-commits cfe-commits at lists.llvm.org
Thu Jan 25 02:02:08 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Animesh Kumar (animeshk-amd)

<details>
<summary>Changes</summary>

The https://reviews.llvm.org/D79948 patch had implemented the `omp scan` directive. The scan computation happens when the `reduction` clause with the `inscan` modifier is used. The present implementation doesn't support the reduction variable and the input list item to be of generic type. This patch handles this edge case by throwing a diagnostic error message when the `inscan` modifier is used on template type variables.

This fixes #<!-- -->67002:
=> [OpenMP][Clang] Scan Directive not supported for Generic types

---
Full diff: https://github.com/llvm/llvm-project/pull/79431.diff


4 Files Affected:

- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+2) 
- (modified) clang/lib/Sema/SemaOpenMP.cpp (+7) 
- (modified) clang/test/OpenMP/scan_ast_print.cpp (+1-23) 
- (modified) clang/test/OpenMP/scan_messages.cpp (+15-11) 


``````````diff
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index a1c32abb4dcd880..34efa9107a81ab8 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11254,6 +11254,8 @@ def err_omp_reduction_not_inclusive_exclusive : Error<
 def err_omp_wrong_inscan_reduction : Error<
   "'inscan' modifier can be used only in 'omp for', 'omp simd', 'omp for simd',"
   " 'omp parallel for', or 'omp parallel for simd' directive">;
+def err_omp_inscan_reduction_on_template_type: Error <
+  "'inscan' modifier currently does not support generic data types">;
 def err_omp_inscan_reduction_expected : Error<
   "expected 'reduction' clause with the 'inscan' modifier">;
 def note_omp_previous_inscan_reduction : Note<
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 217fcb979deea20..b0353bf9b287789 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -19520,6 +19520,13 @@ static bool actOnOMPReductionKindClause(
   bool FirstIter = true;
   for (Expr *RefExpr : VarList) {
     assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
+    if (ClauseKind == OMPC_reduction &&
+        RD.RedModifier == OMPC_REDUCTION_inscan && RefExpr->isTypeDependent()) {
+      S.Diag(RefExpr->getExprLoc(),
+             diag::err_omp_inscan_reduction_on_template_type);
+      continue;
+    }
+
     // OpenMP [2.1, C/C++]
     //  A list item is a variable or array section, subject to the restrictions
     //  specified in Section 2.4 on page 42 and in each of the sections
diff --git a/clang/test/OpenMP/scan_ast_print.cpp b/clang/test/OpenMP/scan_ast_print.cpp
index 3bbd3b60c3e8c4e..090f7d2cafc34f1 100644
--- a/clang/test/OpenMP/scan_ast_print.cpp
+++ b/clang/test/OpenMP/scan_ast_print.cpp
@@ -12,28 +12,6 @@
 
 void foo() {}
 
-template <class T>
-T tmain(T argc) {
-  static T a;
-#pragma omp for reduction(inscan, +: a)
-  for (int i = 0; i < 10; ++i) {
-#pragma omp scan inclusive(a)
-  }
-  return a + argc;
-}
-// CHECK:      static T a;
-// CHECK-NEXT: #pragma omp for reduction(inscan, +: a)
-// CHECK-NEXT: for (int i = 0; i < 10; ++i) {
-// CHECK-NEXT: #pragma omp scan inclusive(a){{$}}
-// CHECK:      static int a;
-// CHECK-NEXT: #pragma omp for reduction(inscan, +: a)
-// CHECK-NEXT: for (int i = 0; i < 10; ++i) {
-// CHECK-NEXT: #pragma omp scan inclusive(a)
-// CHECK:      static char a;
-// CHECK-NEXT: #pragma omp for reduction(inscan, +: a)
-// CHECK-NEXT: for (int i = 0; i < 10; ++i) {
-// CHECK-NEXT: #pragma omp scan inclusive(a)
-
 int main(int argc, char **argv) {
   static int a;
 // CHECK: static int a;
@@ -46,7 +24,7 @@ int main(int argc, char **argv) {
 // CHECK-NEXT: #pragma omp for simd reduction(inscan, ^: a,argc)
 // CHECK-NEXT: for (int i = 0; i < 10; ++i) {
 // CHECK-NEXT: #pragma omp scan exclusive(a,argc){{$}}
-  return tmain(argc) + tmain(argv[0][0]) + a;
+  return 0;
 }
 
 #endif
diff --git a/clang/test/OpenMP/scan_messages.cpp b/clang/test/OpenMP/scan_messages.cpp
index 0de94898c65712f..3e889072bebf79b 100644
--- a/clang/test/OpenMP/scan_messages.cpp
+++ b/clang/test/OpenMP/scan_messages.cpp
@@ -16,32 +16,32 @@ T tmain() {
 #pragma omp scan untied  // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp scan'}} expected-error {{exactly one of 'inclusive' or 'exclusive' clauses is expected}}
 #pragma omp scan unknown // expected-warning {{extra tokens at the end of '#pragma omp scan' are ignored}} expected-error {{exactly one of 'inclusive' or 'exclusive' clauses is expected}}
   }
-#pragma omp for simd reduction(inscan, +: argc)
+#pragma omp for simd reduction(inscan, +: argc) // expected-error {{'inscan' modifier currently does not support generic data types}}
   for (int i = 0; i < 10; ++i)
     if (argc)
 #pragma omp scan inclusive(argc) // expected-error {{'#pragma omp scan' cannot be an immediate substatement}} expected-error {{orphaned 'omp scan' directives are prohibited; perhaps you forget to enclose the directive into a for, simd, for simd, parallel for, or parallel for simd region?}}
     if (argc) {
 #pragma omp scan inclusive(argc) // expected-error {{orphaned 'omp scan' directives are prohibited; perhaps you forget to enclose the directive into a for, simd, for simd, parallel for, or parallel for simd region?}}
     }
-#pragma omp simd reduction(inscan, +: argc)
+#pragma omp simd reduction(inscan, +: argc) // expected-error {{'inscan' modifier currently does not support generic data types}}
   for (int i = 0; i < 10; ++i)
   while (argc)
 #pragma omp scan inclusive(argc) // expected-error {{'#pragma omp scan' cannot be an immediate substatement}} expected-error {{orphaned 'omp scan' directives are prohibited; perhaps you forget to enclose the directive into a for, simd, for simd, parallel for, or parallel for simd region?}}
     while (argc) {
 #pragma omp scan inclusive(argc) // expected-error {{orphaned 'omp scan' directives are prohibited; perhaps you forget to enclose the directive into a for, simd, for simd, parallel for, or parallel for simd region?}}
     }
-#pragma omp simd reduction(inscan, +: argc)
+#pragma omp simd reduction(inscan, +: argc) // expected-error {{'inscan' modifier currently does not support generic data types}}
   for (int i = 0; i < 10; ++i)
   do
 #pragma omp scan inclusive(argc) // expected-error {{'#pragma omp scan' cannot be an immediate substatement}} expected-error {{orphaned 'omp scan' directives are prohibited; perhaps you forget to enclose the directive into a for, simd, for simd, parallel for, or parallel for simd region?}}
     while (argc)
       ;
-#pragma omp simd reduction(inscan, +: argc) // expected-error {{the inscan reduction list item must appear as a list item in an 'inclusive' or 'exclusive' clause on an inner 'omp scan' directive}}
+#pragma omp simd reduction(inscan, +: argc) // expected-error {{'inscan' modifier currently does not support generic data types}}
   for (int i = 0; i < 10; ++i)
   do {
 #pragma omp scan inclusive(argc) // expected-error {{orphaned 'omp scan' directives are prohibited; perhaps you forget to enclose the directive into a for, simd, for simd, parallel for, or parallel for simd region?}}
   } while (argc);
-#pragma omp simd reduction(inscan, +: argc)
+#pragma omp simd reduction(inscan, +: argc) // expected-error {{'inscan' modifier currently does not support generic data types}}
   for (int i = 0; i < 10; ++i)
   switch (argc)
 #pragma omp scan inclusive(argc) // expected-error {{'#pragma omp scan' cannot be an immediate substatement}} expected-error {{orphaned 'omp scan' directives are prohibited; perhaps you forget to enclose the directive into a for, simd, for simd, parallel for, or parallel for simd region?}}
@@ -52,7 +52,7 @@ T tmain() {
   case 1: {
 #pragma omp scan inclusive(argc) // expected-error {{orphaned 'omp scan' directives are prohibited; perhaps you forget to enclose the directive into a for, simd, for simd, parallel for, or parallel for simd region?}}
   }
-#pragma omp simd reduction(inscan, +: argc) // expected-error {{the inscan reduction list item must appear as a list item in an 'inclusive' or 'exclusive' clause on an inner 'omp scan' directive}}
+#pragma omp simd reduction(inscan, +: argc) // expected-error {{'inscan' modifier currently does not support generic data types}}
   for (int i = 0; i < 10; ++i)
   switch (argc) {
 #pragma omp scan exclusive(argc) // expected-error {{orphaned 'omp scan' directives are prohibited; perhaps you forget to enclose the directive into a for, simd, for simd, parallel for, or parallel for simd region?}}
@@ -64,26 +64,30 @@ T tmain() {
 #pragma omp scan exclusive(argc) // expected-error {{orphaned 'omp scan' directives are prohibited; perhaps you forget to enclose the directive into a for, simd, for simd, parallel for, or parallel for simd region?}}
   } break;
   }
-#pragma omp simd reduction(inscan, +: argc)
+#pragma omp simd reduction(inscan, +: argc) // expected-error {{'inscan' modifier currently does not support generic data types}}
   for (int i = 0; i < 10; ++i)
   for (;;)
 #pragma omp scan exclusive(argc) // expected-error {{'#pragma omp scan' cannot be an immediate substatement}} expected-error {{orphaned 'omp scan' directives are prohibited; perhaps you forget to enclose the directive into a for, simd, for simd, parallel for, or parallel for simd region?}}
     for (;;) {
 #pragma omp scan exclusive(argc) // expected-error {{orphaned 'omp scan' directives are prohibited; perhaps you forget to enclose the directive into a for, simd, for simd, parallel for, or parallel for simd region?}}
     }
-#pragma omp simd reduction(inscan, +: argc)
+#pragma omp simd reduction(inscan, +: argc) // expected-error {{'inscan' modifier currently does not support generic data types}}
   for (int i = 0; i < 10; ++i) {
 label:
-#pragma omp scan exclusive(argc) // expected-error{{'#pragma omp scan' cannot be an immediate substatement}}
+#pragma omp scan exclusive(argc) // expected-error{{'#pragma omp scan' cannot be an immediate substatement}} expected-error {{the list item must appear in 'reduction' clause with the 'inscan' modifier of the parent directive}}
   }
-#pragma omp simd reduction(inscan, +: argc)
+#pragma omp simd reduction(inscan, +: argc) // expected-error {{'inscan' modifier currently does not support generic data types}}
   for (int i = 0; i < 10; ++i) {
-#pragma omp scan inclusive(argc) // expected-note {{previous 'scan' directive used here}}
+#pragma omp scan inclusive(argc) // expected-note {{previous 'scan' directive used here}} expected-error {{the list item must appear in 'reduction' clause with the 'inscan' modifier of the parent directive}}
 #pragma omp scan inclusive(argc) // expected-error {{exactly one 'scan' directive must appear in the loop body of an enclosing directive}}
 label1 : {
 #pragma omp scan inclusive(argc) // expected-error {{orphaned 'omp scan' directives are prohibited; perhaps you forget to enclose the directive into a for, simd, for simd, parallel for, or parallel for simd region?}}
 }}
 
+#pragma omp for reduction(inscan, +: argc) // expected-error {{'inscan' modifier currently does not support generic data types}}
+  for (int i = 0; i < 10; ++i) {
+#pragma omp scan inclusive(argc) // expected-error {{the list item must appear in 'reduction' clause with the 'inscan' modifier of the parent directive}}
+  }
   return T();
 }
 

``````````

</details>


https://github.com/llvm/llvm-project/pull/79431


More information about the cfe-commits mailing list