[flang-commits] [flang] 0f8e792 - [flang] 2.8.1 SIMD structural checks (flang-compiler/f18#554)
via flang-commits
flang-commits at lists.llvm.org
Thu Apr 9 08:15:33 PDT 2020
Author: Jinxin (Brian) Yang
Date: 2019-07-09T14:08:50-07:00
New Revision: 0f8e792455b20421f47bea43888a77dcd8080d4d
URL: https://github.com/llvm/llvm-project/commit/0f8e792455b20421f47bea43888a77dcd8080d4d
DIFF: https://github.com/llvm/llvm-project/commit/0f8e792455b20421f47bea43888a77dcd8080d4d.diff
LOG: [flang] 2.8.1 SIMD structural checks (flang-compiler/f18#554)
Straightforward implementation but not including:
* list-item on aligned clause
* nesting check with the ordered construct (parse tree changes needed!)
* list-item attributes check on aligned clause
Original-commit: flang-compiler/f18 at cf04d8ad26fc392822335a529430afb65421d7b4
Reviewed-on: https://github.com/flang-compiler/f18/pull/554
Added:
Modified:
flang/lib/semantics/check-omp-structure.cc
flang/lib/semantics/check-omp-structure.h
flang/test/semantics/omp-clause-validity01.f90
Removed:
################################################################################
diff --git a/flang/lib/semantics/check-omp-structure.cc b/flang/lib/semantics/check-omp-structure.cc
index 5591c0ec12e0..abf38803eb33 100644
--- a/flang/lib/semantics/check-omp-structure.cc
+++ b/flang/lib/semantics/check-omp-structure.cc
@@ -51,6 +51,10 @@ void OmpStructureChecker::CheckAllowed(const OmpClause &type) {
SetContextClauseInfo(type);
}
+void OmpStructureChecker::Enter(const parser::OpenMPConstruct &x) {
+ // 2.8.1 TODO: Simd Construct with Ordered Construct Nesting check
+}
+
void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
const auto &dir{std::get<parser::OmpLoopDirective>(x.t)};
if (std::holds_alternative<parser::OmpLoopDirective::Do>(dir.u)) {
@@ -124,6 +128,26 @@ void OmpStructureChecker::Enter(const parser::OmpLoopDirective::Do &) {
SetContextAllowedOnce(allowedOnce);
}
+// 2.8.1 simd-clause -> safelen-clause |
+// simdlen-clause |
+// linear-clause |
+// aligned-clause |
+// private-clause |
+// lastprivate-clause |
+// reduction-clause |
+// collapse-clause
+void OmpStructureChecker::Enter(const parser::OmpLoopDirective::Simd &) {
+ SetContextDirectiveEnum(OmpDirective::SIMD);
+
+ OmpClauseSet allowed{OmpClause::LINEAR, OmpClause::ALIGNED,
+ OmpClause::PRIVATE, OmpClause::LASTPRIVATE, OmpClause::REDUCTION};
+ SetContextAllowed(allowed);
+
+ OmpClauseSet allowedOnce{
+ OmpClause::COLLAPSE, OmpClause::SAFELEN, OmpClause::SIMDLEN};
+ SetContextAllowedOnce(allowedOnce);
+}
+
void OmpStructureChecker::Leave(const parser::OmpClauseList &) {
// 2.7 Loop Construct Restriction
if (GetContext().directive == OmpDirective::DO) {
@@ -177,7 +201,31 @@ void OmpStructureChecker::Leave(const parser::OmpClauseList &) {
// TODO: ordered region binding check (requires nesting implementation)
}
- }
+ } // DO
+
+ // 2.8.1 Simd Construct Restriction
+ if (GetContext().directive == OmpDirective::SIMD) {
+ if (auto *clause{FindClause(OmpClause::SIMDLEN)}) {
+ if (auto *clause2{FindClause(OmpClause::SAFELEN)}) {
+ const auto &simdlenClause{
+ std::get<parser::OmpClause::Simdlen>(clause->u)};
+ const auto &safelenClause{
+ std::get<parser::OmpClause::Safelen>(clause2->u)};
+ // simdlen and safelen both have parameters
+ if (const auto simdlenValue{GetIntValue(simdlenClause.v)}) {
+ if (const auto safelenValue{GetIntValue(safelenClause.v)}) {
+ if (*safelenValue > 0 && *simdlenValue > *safelenValue) {
+ context_.Say(clause->source,
+ "The parameter of the SIMDLEN clause must be less than or "
+ "equal to the parameter of the SAFELEN clause"_err_en_US);
+ }
+ }
+ }
+ }
+ }
+
+ // TODO: A list-item cannot appear in more than one aligned clause
+ } // SIMD
}
void OmpStructureChecker::Enter(const parser::OmpClause &x) {
@@ -279,14 +327,30 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Priority &) {
void OmpStructureChecker::Enter(const parser::OmpClause::Private &) {
CheckAllowed(OmpClause::PRIVATE);
}
-void OmpStructureChecker::Enter(const parser::OmpClause::Safelen &) {
+void OmpStructureChecker::Enter(const parser::OmpClause::Safelen &x) {
CheckAllowed(OmpClause::SAFELEN);
+
+ if (const auto v{GetIntValue(x.v)}) {
+ if (*v <= 0) {
+ context_.Say(GetContext().clauseSource,
+ "The parameter of the SAFELEN clause must be "
+ "a constant positive integer expression"_err_en_US);
+ }
+ }
}
void OmpStructureChecker::Enter(const parser::OmpClause::Shared &) {
CheckAllowed(OmpClause::SHARED);
}
-void OmpStructureChecker::Enter(const parser::OmpClause::Simdlen &) {
+void OmpStructureChecker::Enter(const parser::OmpClause::Simdlen &x) {
CheckAllowed(OmpClause::SIMDLEN);
+
+ if (const auto v{GetIntValue(x.v)}) {
+ if (*v <= 0) {
+ context_.Say(GetContext().clauseSource,
+ "The parameter of the SIMDLEN clause must be "
+ "a constant positive integer expression"_err_en_US);
+ }
+ }
}
void OmpStructureChecker::Enter(const parser::OmpClause::ThreadLimit &) {
CheckAllowed(OmpClause::THREAD_LIMIT);
@@ -307,8 +371,20 @@ void OmpStructureChecker::Enter(const parser::OmpClause::IsDevicePtr &) {
CheckAllowed(OmpClause::IS_DEVICE_PTR);
}
-void OmpStructureChecker::Enter(const parser::OmpAlignedClause &) {
+void OmpStructureChecker::Enter(const parser::OmpAlignedClause &x) {
CheckAllowed(OmpClause::ALIGNED);
+
+ if (const auto &expr{
+ std::get<std::optional<parser::ScalarIntConstantExpr>>(x.t)}) {
+ if (const auto v{GetIntValue(*expr)}) {
+ if (*v <= 0) {
+ context_.Say(GetContext().clauseSource,
+ "The ALIGNMENT parameter of the ALIGNED clause must be "
+ "a constant positive integer expression"_err_en_US);
+ }
+ }
+ }
+ // 2.8.1 TODO: list-item attribute check
}
void OmpStructureChecker::Enter(const parser::OmpDefaultClause &) {
CheckAllowed(OmpClause::DEFAULT);
diff --git a/flang/lib/semantics/check-omp-structure.h b/flang/lib/semantics/check-omp-structure.h
index 3d2cc0290f43..e8c6d3bfb9a6 100644
--- a/flang/lib/semantics/check-omp-structure.h
+++ b/flang/lib/semantics/check-omp-structure.h
@@ -43,11 +43,11 @@ ENUM_CLASS(OmpDirective, PARALLEL, DO, SECTIONS, SECTION, SINGLE, WORKSHARE,
using OmpDirectiveSet = common::EnumSet<OmpDirective, OmpDirective_enumSize>;
ENUM_CLASS(OmpClause, DEFAULTMAP, INBRANCH, MERGEABLE, NOGROUP, NOTINBRANCH,
- NOWAIT, UNTIED, COLLAPSE, COPYIN, COPYPRIVATE, DEVICE, DIST_SCHEDULE, FINAL,
- FIRSTPRIVATE, FROM, GRAINSIZE, LASTPRIVATE, NUM_TASKS, NUM_TEAMS,
- NUM_THREADS, ORDERED, PRIORITY, PRIVATE, SAFELEN, SHARED, SIMDLEN,
- THREAD_LIMIT, TO, LINK, UNIFORM, USE_DEVICE_PTR, IS_DEVICE_PTR, ALIGNED,
- DEFAULT, DEPEND, IF, LINEAR, MAP, PROC_BIND, REDUCTION, SCHEDULE)
+ NOWAIT, UNTIED, THREADS, SIMD, COLLAPSE, COPYIN, COPYPRIVATE, DEVICE,
+ DIST_SCHEDULE, FINAL, FIRSTPRIVATE, FROM, GRAINSIZE, LASTPRIVATE, NUM_TASKS,
+ NUM_TEAMS, NUM_THREADS, ORDERED, PRIORITY, PRIVATE, SAFELEN, SHARED,
+ SIMDLEN, THREAD_LIMIT, TO, LINK, UNIFORM, USE_DEVICE_PTR, IS_DEVICE_PTR,
+ ALIGNED, DEFAULT, DEPEND, IF, LINEAR, MAP, PROC_BIND, REDUCTION, SCHEDULE)
using OmpClauseSet = common::EnumSet<OmpClause, OmpClause_enumSize>;
@@ -55,9 +55,11 @@ class OmpStructureChecker : public virtual BaseChecker {
public:
OmpStructureChecker(SemanticsContext &context) : context_{context} {}
+ void Enter(const parser::OpenMPConstruct &);
void Enter(const parser::OpenMPLoopConstruct &);
void Leave(const parser::OpenMPLoopConstruct &);
void Enter(const parser::OmpLoopDirective::Do &);
+ void Enter(const parser::OmpLoopDirective::Simd &);
void Enter(const parser::OpenMPBlockConstruct &);
void Leave(const parser::OpenMPBlockConstruct &);
diff --git a/flang/test/semantics/omp-clause-validity01.f90 b/flang/test/semantics/omp-clause-validity01.f90
index 6313c2be4a4f..ccf3a78ad4d8 100644
--- a/flang/test/semantics/omp-clause-validity01.f90
+++ b/flang/test/semantics/omp-clause-validity01.f90
@@ -20,7 +20,10 @@
! 2.7.1 Loop construct
! ...
+! TODO: all the internal errors
+
integer :: b = 128
+ integer :: c = 32
integer, parameter :: num = 16
N = 1024
@@ -105,8 +108,6 @@
! collapse-clause |
! ordered-clause
-! TODO: all the internal errors
-
!ERROR: When SCHEDULE clause has AUTO specified, it must not have chunk size specified
!ERROR: At most one SCHEDULE clause can appear on the DO directive
!ERROR: When SCHEDULE clause has RUNTIME specified, it must not have chunk size specified
@@ -152,4 +153,44 @@
enddo
enddo
enddo
+
+! 2.8.1 simd-clause -> safelen-clause |
+! simdlen-clause |
+! linear-clause |
+! aligned-clause |
+! private-clause |
+! lastprivate-clause |
+! reduction-clause |
+! collapse-clause
+
+ a = 0.0
+ !$omp simd private(b) reduction(+:a)
+ do i = 1, N
+ a = a + b + 3.14
+ enddo
+
+ !ERROR: At most one SAFELEN clause can appear on the SIMD directive
+ !$omp simd safelen(1) safelen(2)
+ do i = 1, N
+ a = 3.14
+ enddo
+
+ !ERROR: The parameter of the SIMDLEN clause must be a constant positive integer expression
+ !$omp simd simdlen(-1)
+ do i = 1, N
+ a = 3.14
+ enddo
+
+ !ERROR: The ALIGNMENT parameter of the ALIGNED clause must be a constant positive integer expression
+ !ERROR: Internal: no symbol found for 'b'
+ !$omp simd aligned(b:-2)
+ do i = 1, N
+ a = 3.14
+ enddo
+
+ !ERROR: The parameter of the SIMDLEN clause must be less than or equal to the parameter of the SAFELEN clause
+ !$omp simd safelen(1+1) simdlen(1+2)
+ do i = 1, N
+ a = 3.14
+ enddo
end
More information about the flang-commits
mailing list