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