Skip to content

Commit a73bdba

Browse files
authored
[flang][OpenMP] Update semantic checks for LINEAR clause (llvm#177055)
Fixes llvm#173980. In particular, make step-simple-modifier be compatible (i.e. not exclusive) for OpenMP spec versions < 52, and update the modifier validity checks for the construct on which the clause is located.
1 parent 48565d9 commit a73bdba

File tree

4 files changed

+74
-41
lines changed

4 files changed

+74
-41
lines changed

flang/lib/Semantics/check-omp-loop.cpp

Lines changed: 45 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -775,54 +775,62 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Linear &x) {
775775
auto &modifiers{OmpGetModifiers(x.v)};
776776
linearMod = OmpGetUniqueModifier<parser::OmpLinearModifier>(modifiers);
777777
if (linearMod) {
778-
// 2.7 Loop Construct Restriction
779-
if ((llvm::omp::allDoSet | llvm::omp::allSimdSet).test(dir)) {
780-
context_.Say(clauseSource,
781-
"A modifier may not be specified in a LINEAR clause on the %s directive"_err_en_US,
782-
ContextDirectiveAsFortran());
783-
// Don't return early - continue to check other restrictions
784-
}
785-
786778
auto &desc{OmpGetDescriptor<parser::OmpLinearModifier>()};
787-
for (auto &[symbol, source] : symbols) {
788-
if (linearMod->v != parser::OmpLinearModifier::Value::Ref) {
789-
CheckIntegerNoRef(symbol, source);
790-
} else {
791-
if (!IsAllocatable(*symbol) && !IsAssumedShape(*symbol) &&
792-
!IsPolymorphic(*symbol)) {
793-
context_.Say(source,
794-
"The list item `%s` specified with the REF '%s' must be polymorphic variable, assumed-shape array, or a variable with the `ALLOCATABLE` attribute"_err_en_US,
795-
symbol->name(), desc.name.str());
796-
}
779+
parser::CharBlock modSource{OmpGetModifierSource(modifiers, linearMod)};
780+
bool valid{true};
781+
782+
if (version < 52) {
783+
// Modifiers on LINEAR are only allowed on DECLARE SIMD
784+
if (dir != llvm::omp::Directive::OMPD_declare_simd) {
785+
context_.Say(modSource,
786+
"A modifier may not be specified in a LINEAR clause on the %s directive"_err_en_US,
787+
parser::ToUpperCaseLetters(getDirectiveName(dir)));
788+
valid = false;
797789
}
790+
} else {
798791
if (linearMod->v == parser::OmpLinearModifier::Value::Ref ||
799792
linearMod->v == parser::OmpLinearModifier::Value::Uval) {
800-
if (!IsDummy(*symbol) || IsValue(*symbol)) {
801-
context_.Say(source,
802-
"If the `%s` is REF or UVAL, the list item '%s' must be a dummy argument without the VALUE attribute"_err_en_US,
803-
desc.name.str(), symbol->name());
793+
if (dir != llvm::omp::Directive::OMPD_declare_simd) {
794+
context_.Say(modSource,
795+
"A REF or UVAL '%s' may not be specified in a LINEAR clause on the %s directive"_err_en_US,
796+
desc.name.str(),
797+
parser::ToUpperCaseLetters(getDirectiveName(dir)));
798+
valid = false;
804799
}
805800
}
806-
} // for (symbol, source)
807-
808-
if (version >= 52 && !std::get</*PostModified=*/bool>(x.v.t)) {
809-
context_.Say(OmpGetModifierSource(modifiers, linearMod),
810-
"The 'modifier(<list>)' syntax is deprecated in %s, use '<list> : modifier' instead"_warn_en_US,
811-
ThisVersion(version));
801+
if (!std::get</*PostModified=*/bool>(x.v.t)) {
802+
context_.Say(modSource,
803+
"The 'modifier(<list>)' syntax is deprecated in %s, use '<list> : modifier' instead"_warn_en_US,
804+
ThisVersion(version));
805+
}
812806
}
813-
}
814-
}
815807

816-
// OpenMP 5.2: Ordered clause restriction
817-
if (const auto *clause{
818-
FindClause(GetContext(), llvm::omp::Clause::OMPC_ordered)}) {
819-
const auto &orderedClause{std::get<parser::OmpClause::Ordered>(clause->u)};
820-
if (orderedClause.v) {
821-
return;
808+
if (valid) {
809+
for (auto &[symbol, source] : symbols) {
810+
if (linearMod->v != parser::OmpLinearModifier::Value::Ref) {
811+
CheckIntegerNoRef(symbol, source);
812+
} else {
813+
if (!IsAllocatable(*symbol) && !IsAssumedShape(*symbol) &&
814+
!IsPolymorphic(*symbol)) {
815+
context_.Say(source,
816+
"The list item `%s` specified with the REF '%s' must be polymorphic variable, assumed-shape array, or a variable with the `ALLOCATABLE` attribute"_err_en_US,
817+
symbol->name(), desc.name.str());
818+
}
819+
}
820+
if (linearMod->v == parser::OmpLinearModifier::Value::Ref ||
821+
linearMod->v == parser::OmpLinearModifier::Value::Uval) {
822+
if (!IsDummy(*symbol) || IsValue(*symbol)) {
823+
context_.Say(source,
824+
"If the `%s` is REF or UVAL, the list item '%s' must be a dummy argument without the VALUE attribute"_err_en_US,
825+
desc.name.str(), symbol->name());
826+
}
827+
}
828+
} // for (symbol, source)
829+
}
822830
}
823831
}
824832

825-
// OpenMP 5.2: Linear clause Restrictions
833+
// Linear clause restrictions.
826834
for (auto &[symbol, source] : symbols) {
827835
// Check that the list item is a scalar variable (rank 0)
828836
// For declare simd with REF modifier, arrays are allowed

flang/lib/Semantics/openmp-modifiers.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -693,7 +693,8 @@ const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpStepSimpleModifier>() {
693693
/*name=*/"step-simple-modifier",
694694
/*props=*/
695695
{
696-
{45, {OmpProperty::Unique, OmpProperty::Exclusive}},
696+
{45, {OmpProperty::Unique}},
697+
{52, {OmpProperty::Unique, OmpProperty::Exclusive}},
697698
},
698699
/*clauses=*/
699700
{

flang/test/Semantics/OpenMP/clause-validity01.f90

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,6 @@
200200
a = 3.14
201201
enddo
202202

203-
!ERROR: A modifier may not be specified in a LINEAR clause on the DO directive
204203
!$omp do linear(b: val)
205204
do i = 1, N
206205
a = 3.14
@@ -221,13 +220,15 @@
221220
!ERROR: Clause LINEAR is not allowed if clause ORDERED appears on the DO directive
222221
!ERROR: The parameter of the ORDERED clause must be a constant positive integer expression
223222
!ERROR: 'b' appears in more than one data-sharing clause on the same OpenMP directive
223+
!ERROR: The list item 'a' specified without the REF 'linear-modifier' must be of INTEGER type
224224
!$omp do ordered(1-1) private(b) linear(b) linear(a)
225225
do i = 1, N
226226
a = 3.14
227227
enddo
228228

229229
!ERROR: Clause LINEAR is not allowed if clause ORDERED appears on the DO directive
230230
!ERROR: The parameter of the ORDERED clause must be a constant positive integer expression
231+
!ERROR: The list item 'a' specified without the REF 'linear-modifier' must be of INTEGER type
231232
!$omp do ordered(1-1) linear(a)
232233
do i = 1, N
233234
a = 3.14
@@ -407,8 +408,8 @@
407408
! do-clause
408409

409410
!ERROR: At most one PROC_BIND clause can appear on the PARALLEL DO directive
410-
!ERROR: A modifier may not be specified in a LINEAR clause on the PARALLEL DO directive
411-
!$omp parallel do proc_bind(master) proc_bind(close) linear(b: val)
411+
!ERROR: A REF or UVAL 'linear-modifier' may not be specified in a LINEAR clause on the PARALLEL DO directive
412+
!$omp parallel do proc_bind(master) proc_bind(close) linear(b: uval)
412413
do i = 1, N
413414
a = 3.14
414415
enddo
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
!RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp -fopenmp-version=50
2+
3+
module m
4+
5+
interface
6+
subroutine f(x, y)
7+
integer, allocatable :: x
8+
integer :: y
9+
!$omp declare simd(f) linear(ref(x) : 1) linear(uval(y))
10+
end
11+
end interface
12+
13+
contains
14+
15+
subroutine g
16+
integer :: i
17+
!ERROR: Clause LINEAR is not allowed if clause ORDERED appears on the DO directive
18+
!$omp do ordered(1) linear(i)
19+
do i = 1, 10
20+
end do
21+
end
22+
23+
end module

0 commit comments

Comments
 (0)