-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[Flang][OpenMP] Add some semantic checks for Linear clause #111354
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
617b8bf
7a7ebee
f1a28c4
4c63c16
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -383,6 +383,19 @@ void OmpStructureChecker::CheckMultListItems() { | |
CheckMultipleOccurrence( | ||
listVars, nontempNameList, clause->source, "NONTEMPORAL"); | ||
} | ||
|
||
// Linear clause | ||
for (auto [_, clause] : FindClauses(llvm::omp::Clause::OMPC_linear)) { | ||
const auto &linearClause{std::get<parser::OmpClause::Linear>(clause->u)}; | ||
std::list<parser::Name> nameList; | ||
common::visit( | ||
[&](const auto &u) { | ||
std::copy( | ||
u.names.begin(), u.names.end(), std::back_inserter(nameList)); | ||
}, | ||
linearClause.v.u); | ||
CheckMultipleOccurrence(listVars, nameList, clause->source, "LINEAR"); | ||
} | ||
} | ||
|
||
bool OmpStructureChecker::HasInvalidWorksharingNesting( | ||
|
@@ -2686,12 +2699,12 @@ void OmpStructureChecker::Leave(const parser::OmpClauseList &) { | |
} | ||
} | ||
} | ||
|
||
// Sema checks related to presence of multiple list items within the same | ||
// clause | ||
CheckMultListItems(); | ||
} // SIMD | ||
|
||
// Semantic 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( | ||
|
@@ -3542,16 +3555,95 @@ 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; | ||
} | ||
} | ||
|
||
// OpenMP 5.2: 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 checkForValidLinearClause_01 = [&](const parser::Name &name, | ||
bool is_ref) { | ||
Comment on lines
+3580
to
+3581
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please concatenate all error message strings in this function. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm sorry, but I'm not getting this. Concatenate in the sense, for the following:
should I do?
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes |
||
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); | ||
} | ||
}; | ||
|
||
auto checkForValidLinearClause_02 = [&](const parser::Name &name, | ||
const parser::OmpLinearModifier::Value | ||
&modifierValue) { | ||
std::string listItemName{name.ToString()}; | ||
checkForValidLinearClause_01( | ||
name, (modifierValue == parser::OmpLinearModifier::Value::Ref)); | ||
if (modifierValue != parser::OmpLinearModifier::Value::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 (modifierValue == parser::OmpLinearModifier::Value::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); | ||
} | ||
}; | ||
|
||
// OpenMP 5.2: Linear clause Restrictions | ||
common::visit( | ||
common::visitors{ | ||
[&](const parser::OmpLinearClause::WithoutModifier &withoutModifier) { | ||
for (const auto &name : withoutModifier.names) { | ||
if (name.symbol) { | ||
checkForValidLinearClause_01(name, false); | ||
} | ||
} | ||
}, | ||
[&](const parser::OmpLinearClause::WithModifier &withModifier) { | ||
for (const auto &name : withModifier.names) { | ||
if (name.symbol) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can extract this into a lamda to reduce indentation. |
||
checkForValidLinearClause_02(name, withModifier.modifier.v); | ||
} | ||
} | ||
}, | ||
}, | ||
x.v.u); | ||
} | ||
|
||
void OmpStructureChecker::CheckAllowedMapTypes( | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
! 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) | ||
!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 `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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Flang-new already throws an error,
Clause LINEAR is not allowed if clause ORDERED appears on the DO directive
. So, I skipped here.