]> granicus.if.org Git - clang/commitdiff
[OPENMP] Improved check for the linear dependency in the non-rectangular
authorAlexey Bataev <a.bataev@hotmail.com>
Thu, 25 Apr 2019 16:21:13 +0000 (16:21 +0000)
committerAlexey Bataev <a.bataev@hotmail.com>
Thu, 25 Apr 2019 16:21:13 +0000 (16:21 +0000)
loop nests.

Added a checks that the initializer/condition expressions depend only
only of the single previous loop iteration variable.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@359200 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaOpenMP.cpp
test/OpenMP/for_loop_messages.cpp

index 52374563612edfc97e1f67b98c0923bbd1666078..238c9eec70c8e717b99c046d4d2c5dcc46c1e5df 100644 (file)
@@ -9172,6 +9172,8 @@ def err_omp_expected_private_copy_for_allocate : Error<
   "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<
+  "expected loop invariant expression or '<invariant1> * %0 + <invariant2>' kind of expression">;
 } // end of OpenMP category
 
 let CategoryName = "Related Result Type Issue" in {
index a5afce42cb3d902bf33b23d39735c20b2532c27e..8aaa1848a6012a43c09020bd03c18e79cece9cae 100644 (file)
@@ -4715,6 +4715,7 @@ class LoopCounterRefChecker final
   Sema &SemaRef;
   DSAStackTy &Stack;
   const ValueDecl *CurLCDecl = nullptr;
+  const ValueDecl *DepDecl = nullptr;
   bool IsInitializer = true;
 
 public:
@@ -4728,6 +4729,18 @@ public:
         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 false;
@@ -4742,16 +4755,27 @@ public:
         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 false;
   }
   bool VisitStmt(const Stmt *S) {
-    for (const Stmt *Child : S->children()) {
-      if (Child && Visit(Child))
-        return true;
-    }
-    return false;
+    bool Res = true;
+    for (const Stmt *Child : S->children())
+      Res = Child && Visit(Child) && Res;
+    return Res;
   }
   explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
                                  const ValueDecl *CurLCDecl, bool IsInitializer)
index 01c96add280183b007c576d8d4b385e75e74a2ea..f3fba6781b2af87f8a9eb431c694822d7db211ec 100644 (file)
@@ -293,6 +293,12 @@ int test_iteration_spaces() {
   for (ii = ii * 10 + 25; ii < ii / ii - 23; ii += 1)
     c[ii] = a[ii];
 
+// expected-error@+3 {{expected loop invariant expression or '<invariant1> * ii + <invariant2>' kind of expression}}
+#pragma omp for collapse(2)
+    for (ii = 10 + 25; ii < 1000; ii += 1)
+      for (kk = ii * 10 + 25; kk < ii / ii - 23; kk += 1)
+        ;
+
 #pragma omp parallel
 // expected-note@+2  {{defined as firstprivate}}
 // expected-error@+2 {{loop iteration variable in the associated loop of 'omp for' directive may not be firstprivate, predetermined as private}}
@@ -603,7 +609,7 @@ int test_with_random_access_iterator() {
 
 template <typename IT, int ST>
 class TC {
-  int ii;
+  int ii, iii;
 public:
   int dotest_lt(IT begin, IT end) {
 #pragma omp parallel
@@ -613,6 +619,14 @@ public:
   for (ii = ii * 10 + 25; ii < ii / ii - 23; ii += 1)
     ;
 
+#pragma omp parallel
+// expected-error@+4 2 {{expected loop invariant expression or '<invariant1> * ii + <invariant2>' kind of expression}}
+// expected-error@+3 {{expected loop invariant expression or '<invariant1> * TC::ii + <invariant2>' kind of expression}}
+#pragma omp for collapse(2)
+    for (ii = 10 + 25; ii < 1000; ii += 1)
+      for (iii = ii * 10 + 25; iii < ii / ii - 23; iii += 1)
+        ;
+
 #pragma omp parallel
 // expected-note@+3 {{loop step is expected to be positive due to this condition}}
 // expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}}