[PATCH] D64889: [OPENMP] getDSA(): handle loop control variables

Princeton Ferro via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Jul 17 15:20:56 PDT 2019


Prince781 created this revision.
Prince781 added reviewers: ABataev, rsmith.
Prince781 added projects: clang, OpenMP.
Herald added subscribers: cfe-commits, jdoerfert, guansong.

The following example compiles incorrectly since at least clang 8.0.0:

  #include <stdio.h>
  #include <omp.h>
  
  #define N 100
  
  int main(void) {
      int i;
      int arr[N];
  
      #pragma omp parallel // shared(i) shared(arr)
      #pragma omp for // private(i)
      for (i = 0; i < N; i++) {
          #pragma omp task // firstprivate(i) shared(arr)
          {
              printf("[thread %2d] i = %d\n", omp_get_thread_num(), i);
              arr[i] = i;
          }
      }
  
      for (i = 0; i < N; i++) {
          if (arr[i] != i) {
              fprintf(stderr, "FAIL: arr[%d] == %d\n", i, arr[i]);
          }
      }
  }

The iteration variable, `i`, should become `private` at the `omp for` construct and then become implicit `firstprivate` within the task region. What happens instead is that `i` is never privatized within the task construct. As the task construct is parsed, when a reference to `i` is determined, the implicit data-sharing attributes are computed incorrectly.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D64889

Files:
  clang/lib/Sema/SemaOpenMP.cpp


Index: clang/lib/Sema/SemaOpenMP.cpp
===================================================================
--- clang/lib/Sema/SemaOpenMP.cpp
+++ clang/lib/Sema/SemaOpenMP.cpp
@@ -424,6 +424,11 @@
   /// for-loops (from outer to inner).
   const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const;
   /// Check if the specified variable is a loop control variable for
+  /// given region.
+  /// \return The index of the loop control variable in the list of associated
+  /// for-loops (from outer to inner).
+  const LCDeclInfo isLoopControlVariable(const ValueDecl *D, const SharingMapTy &Region) const;
+  /// Check if the specified variable is a loop control variable for
   /// parent region.
   /// \return The index of the loop control variable in the list of associated
   /// for-loops (from outer to inner).
@@ -946,11 +951,24 @@
   case DSA_none:
     return DVar;
   case DSA_unspecified:
+    DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
+    // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
+    // in a Construct, implicitly determined]
+    //  The loop iteration variable(s) in the associated for-loop(s) of a for or
+    //  parallel for construct is (are) private.
+    // OpenMP 5.0 includes taskloop and distribute directives
+    if (!isOpenMPSimdDirective(DVar.DKind) &&
+        isOpenMPLoopDirective(DVar.DKind) &&
+        isLoopControlVariable(D, *Iter).first) {
+      DVar.CKind = OMPC_private;
+      // TODO: OpenMP 5.0: if (Dvar.DKind == OMPD_loop) DVar.CKind = OMPC_lastprivate;
+      return DVar;
+    }
+
     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
     // in a Construct, implicitly determined, p.2]
     //  In a parallel construct, if no default clause is present, these
     //  variables are shared.
-    DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
     if (isOpenMPParallelDirective(DVar.DKind) ||
         isOpenMPTeamsDirective(DVar.DKind)) {
       DVar.CKind = OMPC_shared;
@@ -1018,8 +1036,13 @@
 const DSAStackTy::LCDeclInfo
 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const {
   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
+  return isLoopControlVariable(D, getTopOfStack());
+}
+
+const DSAStackTy::LCDeclInfo
+DSAStackTy::isLoopControlVariable(const ValueDecl *D, const SharingMapTy &Region) const {
   D = getCanonicalDecl(D);
-  const SharingMapTy &StackElem = getTopOfStack();
+  const SharingMapTy &StackElem = Region;
   auto It = StackElem.LCVMap.find(D);
   if (It != StackElem.LCVMap.end())
     return It->second;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D64889.210428.patch
Type: text/x-patch
Size: 2574 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20190717/30682f81/attachment-0001.bin>


More information about the cfe-commits mailing list