r359340 - [OPENMP]Added check for non-random access types for the dependent loop

Alexey Bataev via cfe-commits cfe-commits at lists.llvm.org
Fri Apr 26 12:28:38 PDT 2019


Author: abataev
Date: Fri Apr 26 12:28:37 2019
New Revision: 359340

URL: http://llvm.org/viewvc/llvm-project?rev=359340&view=rev
Log:
[OPENMP]Added check for non-random access types for the dependent loop
counters.

According to the OpenMP 5.0, For any associated loop where the b or lb
expression is not loop invariant with respect to the outermost loop, the
var-outer that appears in the expression may not have a random access
iterator type.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaOpenMP.cpp
    cfe/trunk/test/OpenMP/for_loop_messages.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=359340&r1=359339&r2=359340&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Apr 26 12:28:37 2019
@@ -9177,8 +9177,10 @@ def err_omp_expected_private_copy_for_al
   "the referenced item is not found in any private clause on the same directive">;
 def err_omp_stmt_depends_on_loop_counter : Error<
   "the loop %select{initializer|condition}0 expression depends on the current loop control variable">;
-def err_omp_invariant_or_linear_dependancy : Error<
+def err_omp_invariant_or_linear_dependency : Error<
   "expected loop invariant expression or '<invariant1> * %0 + <invariant2>' kind of expression">;
+def err_omp_wrong_dependency_iterator_type : Error<
+  "expected an integer or a pointer type of the outer loop counter '%0' for non-rectangular nests">;
 } // end of OpenMP category
 
 let CategoryName = "Related Result Type Issue" in {

Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=359340&r1=359339&r2=359340&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Fri Apr 26 12:28:37 2019
@@ -4520,8 +4520,16 @@ class OpenMPIterationSpaceChecker {
   bool TestIsStrictOp = false;
   /// This flag is true when step is subtracted on each iteration.
   bool SubtractStep = false;
+  /// The outer loop counter this loop depends on (if any).
+  const ValueDecl *DepDecl = nullptr;
+  /// Contains number of loop (starts from 1) on which loop counter init
+  /// expression of this loop depends on.
+  Optional<unsigned> InitDependOnLC;
+  /// Contains number of loop (starts from 1) on which loop counter condition
+  /// expression of this loop depends on.
+  Optional<unsigned> CondDependOnLC;
   /// Checks if the provide statement depends on the loop counter.
-  bool doesDependOnLoopCounter(const Stmt *S, bool IsInitializer) const;
+  Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer);
 
 public:
   OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack,
@@ -4622,7 +4630,7 @@ bool OpenMPIterationSpaceChecker::setLCD
         NewLB = CE->getArg(0)->IgnoreParenImpCasts();
   LB = NewLB;
   if (EmitDiags)
-    (void)doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
+    InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
   return false;
 }
 
@@ -4641,7 +4649,7 @@ bool OpenMPIterationSpaceChecker::setUB(
   TestIsStrictOp = StrictOp;
   ConditionSrcRange = SR;
   ConditionLoc = SL;
-  (void)doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
+  CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
   return false;
 }
 
@@ -4716,58 +4724,62 @@ class LoopCounterRefChecker final
   DSAStackTy &Stack;
   const ValueDecl *CurLCDecl = nullptr;
   const ValueDecl *DepDecl = nullptr;
+  const ValueDecl *PrevDepDecl = nullptr;
   bool IsInitializer = true;
+  unsigned BaseLoopId = 0;
+  bool checkDecl(const Expr *E, const ValueDecl *VD) {
+    if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
+      SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
+          << (IsInitializer ? 0 : 1);
+      return false;
+    }
+    const auto &&Data = Stack.isLoopControlVariable(VD);
+    // OpenMP, 2.9.1 Canonical Loop Form, Restrictions.
+    // The type of the loop iterator on which we depend may not have a random
+    // access iterator type.
+    if (Data.first && VD->getType()->isRecordType()) {
+      SmallString<128> Name;
+      llvm::raw_svector_ostream OS(Name);
+      VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
+                               /*Qualified=*/true);
+      SemaRef.Diag(E->getExprLoc(),
+                   diag::err_omp_wrong_dependency_iterator_type)
+          << OS.str();
+      SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD;
+      return false;
+    }
+    if (Data.first &&
+        (DepDecl || (PrevDepDecl &&
+                     getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) {
+      if (!DepDecl && PrevDepDecl)
+        DepDecl = PrevDepDecl;
+      SmallString<128> Name;
+      llvm::raw_svector_ostream OS(Name);
+      DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
+                                    /*Qualified=*/true);
+      SemaRef.Diag(E->getExprLoc(),
+                   diag::err_omp_invariant_or_linear_dependency)
+          << OS.str();
+      return false;
+    }
+    if (Data.first) {
+      DepDecl = VD;
+      BaseLoopId = Data.first;
+    }
+    return Data.first;
+  }
 
 public:
   bool VisitDeclRefExpr(const DeclRefExpr *E) {
     const ValueDecl *VD = E->getDecl();
-    if (isa<VarDecl>(VD)) {
-      if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
-        SemaRef.Diag(E->getExprLoc(),
-                     diag::err_omp_stmt_depends_on_loop_counter)
-            << (IsInitializer ? 0 : 1);
-        return false;
-      }
-      const auto &&Data = Stack.isLoopControlVariable(VD);
-      if (DepDecl && Data.first) {
-        SmallString<128> Name;
-        llvm::raw_svector_ostream OS(Name);
-        DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
-                                      /*Qualified=*/true);
-        SemaRef.Diag(E->getExprLoc(),
-                     diag::err_omp_invariant_or_linear_dependancy)
-            << OS.str();
-        return false;
-      }
-      if (Data.first)
-        DepDecl = VD;
-      return Data.first;
-    }
+    if (isa<VarDecl>(VD))
+      return checkDecl(E, VD);
     return false;
   }
   bool VisitMemberExpr(const MemberExpr *E) {
     if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
       const ValueDecl *VD = E->getMemberDecl();
-      if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
-        SemaRef.Diag(E->getExprLoc(),
-                     diag::err_omp_stmt_depends_on_loop_counter)
-            << (IsInitializer ? 0 : 1);
-        return false;
-      }
-      const auto &&Data = Stack.isLoopControlVariable(VD);
-      if (DepDecl && Data.first) {
-        SmallString<128> Name;
-        llvm::raw_svector_ostream OS(Name);
-        DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
-                                      /*Qualified=*/true);
-        SemaRef.Diag(E->getExprLoc(),
-                     diag::err_omp_invariant_or_linear_dependancy)
-            << OS.str();
-        return false;
-      }
-      if (Data.first)
-        DepDecl = VD;
-      return Data.first;
+      return checkDecl(E, VD);
     }
     return false;
   }
@@ -4778,17 +4790,32 @@ public:
     return Res;
   }
   explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
-                                 const ValueDecl *CurLCDecl, bool IsInitializer)
+                                 const ValueDecl *CurLCDecl, bool IsInitializer,
+                                 const ValueDecl *PrevDepDecl = nullptr)
       : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
-        IsInitializer(IsInitializer) {}
+        PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {}
+  unsigned getBaseLoopId() const {
+    assert(CurLCDecl && "Expected loop dependency.");
+    return BaseLoopId;
+  }
+  const ValueDecl *getDepDecl() const {
+    assert(CurLCDecl && "Expected loop dependency.");
+    return DepDecl;
+  }
 };
 } // namespace
 
-bool OpenMPIterationSpaceChecker::doesDependOnLoopCounter(
-    const Stmt *S, bool IsInitializer) const {
+Optional<unsigned>
+OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S,
+                                                     bool IsInitializer) {
   // Check for the non-rectangular loops.
-  LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer);
-  return LoopStmtChecker.Visit(S);
+  LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
+                                        DepDecl);
+  if (LoopStmtChecker.Visit(S)) {
+    DepDecl = LoopStmtChecker.getDepDecl();
+    return LoopStmtChecker.getBaseLoopId();
+  }
+  return llvm::None;
 }
 
 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {

Modified: cfe/trunk/test/OpenMP/for_loop_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/for_loop_messages.cpp?rev=359340&r1=359339&r2=359340&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/for_loop_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/for_loop_messages.cpp Fri Apr 26 12:28:37 2019
@@ -299,6 +299,13 @@ int test_iteration_spaces() {
       for (kk = ii * 10 + 25; kk < ii / ii - 23; kk += 1)
         ;
 
+// expected-error at +4 {{expected loop invariant expression or '<invariant1> * ii + <invariant2>' kind of expression}}
+#pragma omp for collapse(3)
+    for (ii = 10 + 25; ii < 1000; ii += 1)
+      for (jj = 10 + 25; jj < 1000; jj += 1)
+        for (kk = ii * 10 + 25; kk < jj - 23; kk += 1)
+          ;
+
 #pragma omp parallel
 // expected-note at +2  {{defined as firstprivate}}
 // expected-error at +2 {{loop iteration variable in the associated loop of 'omp for' directive may not be firstprivate, predetermined as private}}
@@ -601,6 +608,14 @@ int test_with_random_access_iterator() {
   for (Iter1 I; I < end1; ++I) {
   }
   GoodIter1 I1, E1;
+// expected-error at +4 {{expected an integer or a pointer type of the outer loop counter 'I' for non-rectangular nests}}
+// expected-error at +4 {{expected an integer or a pointer type of the outer loop counter 'I' for non-rectangular nests}}
+#pragma omp for collapse(3)
+  for (GoodIter1 I = I1; I < E1; I++) // expected-note 2 {{'I' declared here}}
+    for (int i = (I - I1) * 10 + 25; i < 23; i += 1)
+      for (int j = 10 + 25; j < 23 + (I - E1); j += 1)
+        ;
+
 #pragma omp for
   for (GoodIter1 I = I1; I < E1; I++)
     ;
@@ -609,7 +624,7 @@ int test_with_random_access_iterator() {
 
 template <typename IT, int ST>
 class TC {
-  int ii, iii;
+  int ii, iii, kk;
 public:
   int dotest_lt(IT begin, IT end) {
 #pragma omp parallel
@@ -628,6 +643,17 @@ public:
         ;
 
 #pragma omp parallel
+// expected-error at +6 2 {{expected loop invariant expression or '<invariant1> * ii + <invariant2>' kind of expression}}
+// expected-error at +5 {{expected loop invariant expression or '<invariant1> * TC::ii + <invariant2>' kind of expression}}
+// expected-error at +5 2 {{expected loop invariant expression or '<invariant1> * ii + <invariant2>' kind of expression}}
+// expected-error at +4 {{expected loop invariant expression or '<invariant1> * TC::ii + <invariant2>' kind of expression}}
+#pragma omp for collapse(3)
+    for (ii = 10 + 25; ii < 1000; ii += 1)
+      for (iii = ii * 10 + 25; iii < ii / ii - 23; iii += 1)
+        for (kk = ii * 10 + 25; kk < iii - 23; kk += 1)
+          ;
+
+#pragma omp parallel
 // expected-note at +3 {{loop step is expected to be positive due to this condition}}
 // expected-error at +2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}}
 #pragma omp for




More information about the cfe-commits mailing list