[flang-commits] [flang] [Flang][OpenMP] Add some semantic checks for Linear clause (PR #111354)
Thirumalai Shaktivel via flang-commits
flang-commits at lists.llvm.org
Tue Oct 8 05:00:48 PDT 2024
https://github.com/Thirumalai-Shaktivel updated https://github.com/llvm/llvm-project/pull/111354
>From cabbaa271b144d72e0ec4c23cc5e6160f0fac2b0 Mon Sep 17 00:00:00 2001
From: Thirumalai-Shaktivel <thirumalaishaktivel at gmail.com>
Date: Mon, 7 Oct 2024 10:15:21 +0000
Subject: [PATCH 1/3] [LLVM-Flang][OpenMP] Add some semantic checks for Linear
clause based on the OpenMP 5.2 restrictions
---
flang/lib/Semantics/check-omp-structure.cpp | 109 +++++++++++++++++++-
1 file changed, 105 insertions(+), 4 deletions(-)
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 5ef504aa72326e..171a74210db798 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -303,6 +303,30 @@ void OmpStructureChecker::CheckMultListItems() {
CheckMultipleOccurrence(
listVars, nontempNameList, itr->second->source, "NONTEMPORAL");
}
+
+ // Linear clause
+ auto linearClauses{FindClauses(llvm::omp::Clause::OMPC_linear)};
+ for (auto itr{linearClauses.first}; itr != linearClauses.second; ++itr) {
+ const auto &linearClause{
+ std::get<parser::OmpClause::Linear>(itr->second->u)};
+ std::list<parser::Name> nameList;
+ common::visit(
+ common::visitors{
+ [&](const parser::OmpLinearClause::WithoutModifier
+ &withoutModifier) {
+ for (const auto &name : withoutModifier.names) {
+ nameList.push_back(name);
+ }
+ },
+ [&](const parser::OmpLinearClause::WithModifier &withModifier) {
+ for (const auto &name : withModifier.names) {
+ nameList.push_back(name);
+ }
+ },
+ },
+ linearClause.v.u);
+ CheckMultipleOccurrence(listVars, nameList, itr->second->source, "LINEAR");
+ }
}
bool OmpStructureChecker::HasInvalidWorksharingNesting(
@@ -2256,11 +2280,12 @@ void OmpStructureChecker::Leave(const parser::OmpClauseList &) {
}
}
}
- // Sema checks related to presence of multiple list items within the same
- // clause
- CheckMultListItems();
} // SIMD
+ // Semantics checks related to presence of multiple list items within the same
+ // clause
+ CheckMultListItems();
+
// 2.7.3 Single Construct Restriction
if (GetContext().directive == llvm::omp::Directive::OMPD_end_single) {
CheckNotAllowedIfClause(
@@ -2975,16 +3000,92 @@ void OmpStructureChecker::Enter(const parser::OmpClause::If &x) {
void OmpStructureChecker::Enter(const parser::OmpClause::Linear &x) {
CheckAllowedClause(llvm::omp::Clause::OMPC_linear);
+ parser::CharBlock source{GetContext().clauseSource};
// 2.7 Loop Construct Restriction
if ((llvm::omp::allDoSet | llvm::omp::allSimdSet)
.test(GetContext().directive)) {
if (std::holds_alternative<parser::OmpLinearClause::WithModifier>(x.v.u)) {
- context_.Say(GetContext().clauseSource,
+ context_.Say(source,
"A modifier may not be specified in a LINEAR clause "
"on the %s directive"_err_en_US,
ContextDirectiveAsFortran());
+ return;
}
}
+
+ auto checkForValidLinearClause = [&](const parser::Name &name, bool is_ref) {
+ parser::CharBlock source{GetContext().clauseSource};
+ std::string listItemName{name.ToString()};
+ if (!is_ref && !name.symbol->GetType()->IsNumeric(TypeCategory::Integer)) {
+ context_.Say(source,
+ "The list item `%s` specified with other than linear-modifier `REF`"
+ " must be of type INTEGER"_err_en_US,
+ listItemName);
+ }
+ if (GetContext().directive == llvm::omp::Directive::OMPD_declare_simd &&
+ !IsDummy(*name.symbol)) {
+ context_.Say(source,
+ "The list item `%s` must be a dummy argument"_err_en_US,
+ listItemName);
+ }
+ if (IsPointer(*name.symbol) ||
+ name.symbol->test(Symbol::Flag::CrayPointer)) {
+ context_.Say(source,
+ "The list item `%s` in a LINEAR clause must not be Cray Pointer "
+ "or a variable with POINTER attribute"_err_en_US,
+ listItemName);
+ }
+ if (FindCommonBlockContaining(*name.symbol)) {
+ context_.Say(source,
+ "'%s' is a common block name and must not appear in an "
+ "LINEAR clause"_err_en_US,
+ listItemName);
+ }
+ };
+
+ // 5.4.6 Linear clause Restrictions
+ common::visit(
+ common::visitors{
+ [&](const parser::OmpLinearClause::WithoutModifier &withoutModifier) {
+ for (const auto &name : withoutModifier.names) {
+ if (name.symbol) {
+ checkForValidLinearClause(name, false);
+ }
+ }
+ },
+ [&](const parser::OmpLinearClause::WithModifier &withModifier) {
+ for (const auto &name : withModifier.names) {
+ if (name.symbol) {
+ checkForValidLinearClause(name,
+ (withModifier.modifier.v ==
+ parser::OmpLinearModifier::Type::Ref));
+ std::string listItemName{name.ToString()};
+ if (withModifier.modifier.v !=
+ parser::OmpLinearModifier::Type::Val &&
+ IsDummy(*name.symbol) && IsValue(*name.symbol)) {
+ context_.Say(source,
+ "The list item `%s` specified with the linear-modifier "
+ "`REF` or `UVAL` must be a dummy argument without "
+ "`VALUE` attribute"_err_en_US,
+ listItemName);
+ }
+ if (withModifier.modifier.v ==
+ parser::OmpLinearModifier::Type::Ref &&
+ !(IsAllocatable(*name.symbol) ||
+ IsAssumedShape(*name.symbol) ||
+ IsPolymorphic(*name.symbol))) {
+ context_.Say(source,
+ "The list item `%s` specified with the linear-modifier "
+ "`REF` must be polymorphic variable, assumed-shape "
+ "array, "
+ "or a variable with the `ALLOCATABLE` attribute"_err_en_US,
+ listItemName);
+ }
+ }
+ }
+ },
+ },
+ x.v.u);
}
void OmpStructureChecker::CheckAllowedMapTypes(
>From 520ecc7ababf1dcd81e93612ccdc12ee1a2ccd31 Mon Sep 17 00:00:00 2001
From: Thirumalai-Shaktivel <thirumalaishaktivel at gmail.com>
Date: Mon, 7 Oct 2024 10:15:49 +0000
Subject: [PATCH 2/3] [LLVM-Flang][OpenMP] Skip Linear clause semantic check if
ordered clause with (n) is specified
---
flang/lib/Semantics/check-omp-structure.cpp | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 171a74210db798..78a03dcb16cfac 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -3013,8 +3013,17 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Linear &x) {
}
}
- auto checkForValidLinearClause = [&](const parser::Name &name, bool is_ref) {
- parser::CharBlock source{GetContext().clauseSource};
+ // 4.4.4 Ordered clause restriction
+ if (const auto *clause{
+ FindClause(GetContext(), llvm::omp::Clause::OMPC_ordered)}) {
+ const auto &orderedClause{std::get<parser::OmpClause::Ordered>(clause->u)};
+ if (orderedClause.v) {
+ return;
+ }
+ }
+
+ auto checkForValidLinearClaue = [&](const parser::Name &name, bool is_ref) {
+ parser::CharBlock source = GetContext().clauseSource;
std::string listItemName{name.ToString()};
if (!is_ref && !name.symbol->GetType()->IsNumeric(TypeCategory::Integer)) {
context_.Say(source,
>From 592250302625cfda8c37f03f1074644628bf27f6 Mon Sep 17 00:00:00 2001
From: Thirumalai-Shaktivel <thirumalaishaktivel at gmail.com>
Date: Mon, 7 Oct 2024 10:16:36 +0000
Subject: [PATCH 3/3] [Test] Add a test and update a check
---
.../OpenMP/declarative-directive.f90 | 1 +
.../test/Semantics/OpenMP/linear-clause01.f90 | 50 +++++++++++++++++++
2 files changed, 51 insertions(+)
create mode 100644 flang/test/Semantics/OpenMP/linear-clause01.f90
diff --git a/flang/test/Semantics/OpenMP/declarative-directive.f90 b/flang/test/Semantics/OpenMP/declarative-directive.f90
index 8d6762b87adb95..17dc50b70e5421 100644
--- a/flang/test/Semantics/OpenMP/declarative-directive.f90
+++ b/flang/test/Semantics/OpenMP/declarative-directive.f90
@@ -23,6 +23,7 @@ end subroutine requires_2
subroutine declare_simd_1(a, b)
real(8), intent(inout) :: a, b
+ !ERROR: 'a' in ALIGNED clause must be of type C_PTR, POINTER or ALLOCATABLE
!$omp declare simd(declare_simd_1) aligned(a)
a = 3.14 + b
end subroutine declare_simd_1
diff --git a/flang/test/Semantics/OpenMP/linear-clause01.f90 b/flang/test/Semantics/OpenMP/linear-clause01.f90
new file mode 100644
index 00000000000000..a56709aae7ad73
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/linear-clause01.f90
@@ -0,0 +1,50 @@
+! REQUIRES: openmp_runtime
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags
+! OpenMP Version 5.2
+! Various checks for the linear clause
+! 5.4.6 `linear` Clause
+
+! Case 1
+subroutine linear_clause_01(arg)
+ integer, intent(in) :: arg(:)
+ !ERROR: A modifier may not be specified in a LINEAR clause on the DO directive
+ !$omp do linear(uval(arg))
+ do i = 1, 5
+ print *, arg(i)
+ end do
+end subroutine linear_clause_01
+
+! Case 2
+subroutine linear_clause_02(arg_01, arg_02, arg_03)
+ !ERROR: The list item `arg_01` specified with other than linear-modifier `REF` must be of type INTEGER
+ !$omp declare simd linear(val(arg_01))
+ real, intent(in) :: arg_01(:)
+
+ !ERROR: The list item `arg_02` specified with the linear-modifier `REF` or `UVAL` must be a dummy argument without `VALUE` attribute
+ !$omp declare simd linear(uval(arg_02))
+ integer, value, intent(in) :: arg_02
+
+ !ERROR: The list item `arg_03` specified with other than linear-modifier `REF` must be of type INTEGER
+ !ERROR: The list item `arg_03` in a LINEAR clause must not be Cray Pointer or a variable with POINTER attribute
+ !$omp declare simd linear(arg_03)
+ real, pointer :: arg_03
+
+ !ERROR: The list item `var` must be a dummy argument
+ !ERROR: The list item `var` in a LINEAR clause must not be Cray Pointer or a variable with POINTER attribute
+ !$omp declare simd linear(uval(var))
+ integer, pointer :: var
+end subroutine linear_clause_02
+
+! Case 3
+subroutine linear_clause_03(arg)
+ integer, intent(in) :: arg
+ !ERROR: The list item `arg` specified with the linear-modifier `REF` must be polymorphic variable, assumed-shape array, or a variable with the `ALLOCATABLE` attribute
+ !ERROR: List item 'arg' present at multiple LINEAR clauses
+ !$omp declare simd linear(ref(arg)) linear(arg)
+
+ integer :: i
+ common /cc/ i
+ !ERROR: The list item `i` must be a dummy argument
+ !ERROR: 'i' is a common block name and must not appear in an LINEAR clause
+ !$omp declare simd linear(i)
+end subroutine linear_clause_03
More information about the flang-commits
mailing list