Skip to content

Commit 2f9ef33

Browse files
committed
[OPENMP] Improved check for the linear dependency in the non-rectangular
loop nests. Added a checks that the initializer/condition expressions depend only only of the single previous loop iteration variable. llvm-svn: 359200
1 parent 3fad6a2 commit 2f9ef33

File tree

3 files changed

+46
-6
lines changed

3 files changed

+46
-6
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9172,6 +9172,8 @@ def err_omp_expected_private_copy_for_allocate : Error<
91729172
"the referenced item is not found in any private clause on the same directive">;
91739173
def err_omp_stmt_depends_on_loop_counter : Error<
91749174
"the loop %select{initializer|condition}0 expression depends on the current loop control variable">;
9175+
def err_omp_invariant_or_linear_dependancy : Error<
9176+
"expected loop invariant expression or '<invariant1> * %0 + <invariant2>' kind of expression">;
91759177
} // end of OpenMP category
91769178

91779179
let CategoryName = "Related Result Type Issue" in {

clang/lib/Sema/SemaOpenMP.cpp

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4715,6 +4715,7 @@ class LoopCounterRefChecker final
47154715
Sema &SemaRef;
47164716
DSAStackTy &Stack;
47174717
const ValueDecl *CurLCDecl = nullptr;
4718+
const ValueDecl *DepDecl = nullptr;
47184719
bool IsInitializer = true;
47194720

47204721
public:
@@ -4728,6 +4729,18 @@ class LoopCounterRefChecker final
47284729
return false;
47294730
}
47304731
const auto &&Data = Stack.isLoopControlVariable(VD);
4732+
if (DepDecl && Data.first) {
4733+
SmallString<128> Name;
4734+
llvm::raw_svector_ostream OS(Name);
4735+
DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
4736+
/*Qualified=*/true);
4737+
SemaRef.Diag(E->getExprLoc(),
4738+
diag::err_omp_invariant_or_linear_dependancy)
4739+
<< OS.str();
4740+
return false;
4741+
}
4742+
if (Data.first)
4743+
DepDecl = VD;
47314744
return Data.first;
47324745
}
47334746
return false;
@@ -4742,16 +4755,27 @@ class LoopCounterRefChecker final
47424755
return false;
47434756
}
47444757
const auto &&Data = Stack.isLoopControlVariable(VD);
4758+
if (DepDecl && Data.first) {
4759+
SmallString<128> Name;
4760+
llvm::raw_svector_ostream OS(Name);
4761+
DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
4762+
/*Qualified=*/true);
4763+
SemaRef.Diag(E->getExprLoc(),
4764+
diag::err_omp_invariant_or_linear_dependancy)
4765+
<< OS.str();
4766+
return false;
4767+
}
4768+
if (Data.first)
4769+
DepDecl = VD;
47454770
return Data.first;
47464771
}
47474772
return false;
47484773
}
47494774
bool VisitStmt(const Stmt *S) {
4750-
for (const Stmt *Child : S->children()) {
4751-
if (Child && Visit(Child))
4752-
return true;
4753-
}
4754-
return false;
4775+
bool Res = true;
4776+
for (const Stmt *Child : S->children())
4777+
Res = Child && Visit(Child) && Res;
4778+
return Res;
47554779
}
47564780
explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
47574781
const ValueDecl *CurLCDecl, bool IsInitializer)

clang/test/OpenMP/for_loop_messages.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,12 @@ int test_iteration_spaces() {
293293
for (ii = ii * 10 + 25; ii < ii / ii - 23; ii += 1)
294294
c[ii] = a[ii];
295295

296+
// expected-error@+3 {{expected loop invariant expression or '<invariant1> * ii + <invariant2>' kind of expression}}
297+
#pragma omp for collapse(2)
298+
for (ii = 10 + 25; ii < 1000; ii += 1)
299+
for (kk = ii * 10 + 25; kk < ii / ii - 23; kk += 1)
300+
;
301+
296302
#pragma omp parallel
297303
// expected-note@+2 {{defined as firstprivate}}
298304
// 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() {
603609

604610
template <typename IT, int ST>
605611
class TC {
606-
int ii;
612+
int ii, iii;
607613
public:
608614
int dotest_lt(IT begin, IT end) {
609615
#pragma omp parallel
@@ -613,6 +619,14 @@ class TC {
613619
for (ii = ii * 10 + 25; ii < ii / ii - 23; ii += 1)
614620
;
615621

622+
#pragma omp parallel
623+
// expected-error@+4 2 {{expected loop invariant expression or '<invariant1> * ii + <invariant2>' kind of expression}}
624+
// expected-error@+3 {{expected loop invariant expression or '<invariant1> * TC::ii + <invariant2>' kind of expression}}
625+
#pragma omp for collapse(2)
626+
for (ii = 10 + 25; ii < 1000; ii += 1)
627+
for (iii = ii * 10 + 25; iii < ii / ii - 23; iii += 1)
628+
;
629+
616630
#pragma omp parallel
617631
// expected-note@+3 {{loop step is expected to be positive due to this condition}}
618632
// expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}}

0 commit comments

Comments
 (0)