-
Notifications
You must be signed in to change notification settings - Fork 10.8k
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
Conversation
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
@llvm/pr-subscribers-clang Author: Animesh Kumar (animeshk-amd) ChangesThe https://reviews.llvm.org/D79948 patch had implemented the This fixes #67002: Full diff: https://github.com/llvm/llvm-project/pull/79431.diff 4 Files Affected:
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> |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
if (ClauseKind == OMPC_reduction && | ||
RD.RedModifier == OMPC_REDUCTION_inscan && RefExpr->isTypeDependent()) { | ||
S.Diag(RefExpr->getExprLoc(), | ||
diag::err_omp_inscan_reduction_on_template_type); | ||
continue; | ||
} | ||
|
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
The https://reviews.llvm.org/D79948 patch had implemented the
omp scan
directive. The scan computation happens when thereduction
clause with theinscan
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 theinscan
modifier is used on template type variables.This fixes #67002:
=> [OpenMP][Clang] Scan Directive not supported for Generic types