r345277 - [OPENMP]Fix PR39422: variables are not firstprivatized in task context.

Alexey Bataev via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 25 08:35:28 PDT 2018


Author: abataev
Date: Thu Oct 25 08:35:27 2018
New Revision: 345277

URL: http://llvm.org/viewvc/llvm-project?rev=345277&view=rev
Log:
[OPENMP]Fix PR39422: variables are not firstprivatized in task context.

According to the OpenMP standard, In a task generating construct, if no
default clause is present, a variable for which the data-sharing
attribute is not determined by the rules above is firstprivatized.
Compiler tries to implement this, but if the variable is not directly
used in the task context, this variable may not be firstprivatized.
Patch fixes this problem.

Modified:
    cfe/trunk/lib/Sema/SemaOpenMP.cpp
    cfe/trunk/test/OpenMP/parallel_sections_default_messages.cpp
    cfe/trunk/test/OpenMP/task_codegen.cpp

Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=345277&r1=345276&r2=345277&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Thu Oct 25 08:35:27 2018
@@ -2251,8 +2251,31 @@ public:
   }
   void VisitStmt(Stmt *S) {
     for (Stmt *C : S->children()) {
-      if (C && !isa<OMPExecutableDirective>(C))
-        Visit(C);
+      if (C) {
+        if (auto *OED = dyn_cast<OMPExecutableDirective>(C)) {
+          // Check implicitly captured vriables in the task-based directives to
+          // check if they must be firstprivatized.
+          if (!OED->hasAssociatedStmt())
+            continue;
+          const Stmt *AS = OED->getAssociatedStmt();
+          if (!AS)
+            continue;
+          for (const CapturedStmt::Capture &Cap :
+               cast<CapturedStmt>(AS)->captures()) {
+            if (Cap.capturesVariable()) {
+              DeclRefExpr *DRE = buildDeclRefExpr(
+                  SemaRef, Cap.getCapturedVar(),
+                  Cap.getCapturedVar()->getType().getNonLValueExprType(
+                      SemaRef.Context),
+                  Cap.getLocation(),
+                  /*RefersToCapture=*/true);
+              Visit(DRE);
+            }
+          }
+        } else {
+          Visit(C);
+        }
+      }
     }
   }
 

Modified: cfe/trunk/test/OpenMP/parallel_sections_default_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_sections_default_messages.cpp?rev=345277&r1=345276&r2=345277&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/parallel_sections_default_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/parallel_sections_default_messages.cpp Thu Oct 25 08:35:27 2018
@@ -34,7 +34,7 @@ int main(int argc, char **argv) {
   {
 #pragma omp parallel sections default(shared)
     {
-      ++argc;
+      ++argc;  // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
     }
   }
   return 0;

Modified: cfe/trunk/test/OpenMP/task_codegen.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/task_codegen.cpp?rev=345277&r1=345276&r2=345277&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/task_codegen.cpp (original)
+++ cfe/trunk/test/OpenMP/task_codegen.cpp Thu Oct 25 08:35:27 2018
@@ -107,6 +107,7 @@ int main() {
 // CHECK: call i32 @__kmpc_omp_task([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i8* [[ORIG_TASK_PTR]])
 #pragma omp task untied
   {
+#pragma omp critical
     a = 1;
   }
 // CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i32 0, i64 40, i64 1,




More information about the cfe-commits mailing list