Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[OpenMP][Clang] Handle unsupported inscan modifier for generic types #79431

Closed
wants to merge 1 commit into from

Conversation

animeshk-amd
Copy link
Contributor

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

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 llvm#67002:
=> [OpenMP][Clang] Scan Directive not supported for Generic types
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:openmp OpenMP related changes to Clang labels Jan 25, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Jan 25, 2024

@llvm/pr-subscribers-clang

Author: Animesh Kumar (animeshk-amd)

Changes

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 --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();
 }
 

@@ -12,28 +12,6 @@

void foo() {}

template <class T>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How was this test case working till now when templates were not supported in scan?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test was passing because the for directive at line:18 is used outside a parallel region, in which case the compiler wasn't crashing. Contrary to what would happen when used within a parallel region.
Since the scan directive currently doesn't support templates, within or without a parallel region, I transferred this test to the scan_messages.cpp line:87 with expected errors.

Comment on lines +19523 to +19529
if (ClauseKind == OMPC_reduction &&
RD.RedModifier == OMPC_REDUCTION_inscan && RefExpr->isTypeDependent()) {
S.Diag(RefExpr->getExprLoc(),
diag::err_omp_inscan_reduction_on_template_type);
continue;
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is definetely wrong, templates should be supported

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should ideally be supported. However, the compiler crashes as per #67002 on the latest builds.
And, can you please elaborate on what you think is wrong with the patch?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is definetely wrong, templates should be supported

Did you mean that templates are currently supported, or did you mean that they should be supported?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are supported, but this check disables this support

@animeshk-amd
Copy link
Contributor Author

Closing this PR because #82220 is fixing the issue #67002

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:openmp OpenMP related changes to Clang clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[OpenMP][Clang] Scan Directive not supported for Generic types
4 participants