[flang][OpenMP] Added semantic checks for hint clause
This patch improves semantic checks for hint clause. It checks "hint-expression is a constant expression that evaluates to a scalar value with kind `omp_sync_hint_kind` and a value that is a valid synchronization hint." Reviewed By: peixin Differential Revision: https://reviews.llvm.org/D127615
This commit is contained in:
parent
a56b76d9ca
commit
7dc18a62e4
|
@ -314,6 +314,48 @@ void OmpStructureChecker::CheckPredefinedAllocatorRestriction(
|
|||
}
|
||||
}
|
||||
|
||||
template <class D>
|
||||
void OmpStructureChecker::CheckHintClause(
|
||||
D *leftOmpClauseList, D *rightOmpClauseList) {
|
||||
auto checkForValidHintClause = [&](const D *clauseList) {
|
||||
for (const auto &clause : clauseList->v) {
|
||||
const Fortran::parser::OmpClause *ompClause = nullptr;
|
||||
if constexpr (std::is_same_v<D,
|
||||
const Fortran::parser::OmpAtomicClauseList>) {
|
||||
ompClause = std::get_if<Fortran::parser::OmpClause>(&clause.u);
|
||||
if (!ompClause)
|
||||
continue;
|
||||
} else if constexpr (std::is_same_v<D,
|
||||
const Fortran::parser::OmpClauseList>) {
|
||||
ompClause = &clause;
|
||||
}
|
||||
if (const Fortran::parser::OmpClause::Hint *
|
||||
hintClause{
|
||||
std::get_if<Fortran::parser::OmpClause::Hint>(&ompClause->u)}) {
|
||||
std::optional<std::int64_t> hintValue = GetIntValue(hintClause->v);
|
||||
if (hintValue && hintValue.value() >= 0) {
|
||||
if((hintValue.value() & 0xC) == 0xC /*`omp_sync_hint_nonspeculative` and `omp_lock_hint_speculative`*/
|
||||
|| (hintValue.value() & 0x3) == 0x3 /*`omp_sync_hint_uncontended` and omp_sync_hint_contended*/ )
|
||||
context_.Say(clause.source,
|
||||
"Hint clause value "
|
||||
"is not a valid OpenMP synchronization value"_err_en_US);
|
||||
} else {
|
||||
context_.Say(clause.source,
|
||||
"Hint clause must have non-negative constant "
|
||||
"integer expression"_err_en_US);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (leftOmpClauseList) {
|
||||
checkForValidHintClause(leftOmpClauseList);
|
||||
}
|
||||
if (rightOmpClauseList) {
|
||||
checkForValidHintClause(rightOmpClauseList);
|
||||
}
|
||||
}
|
||||
|
||||
void OmpStructureChecker::Enter(const parser::OpenMPConstruct &x) {
|
||||
// Simd Construct with Ordered Construct Nesting check
|
||||
// We cannot use CurrentDirectiveIsNested() here because
|
||||
|
@ -1277,6 +1319,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPCriticalConstruct &x) {
|
|||
parser::MessageFormattedText{
|
||||
"Hint clause other than omp_sync_hint_none cannot be specified for an unnamed CRITICAL directive"_err_en_US});
|
||||
}
|
||||
CheckHintClause<const parser::OmpClauseList>(&ompClause, nullptr);
|
||||
}
|
||||
|
||||
void OmpStructureChecker::Leave(const parser::OpenMPCriticalConstruct &) {
|
||||
|
@ -1580,6 +1623,9 @@ void OmpStructureChecker::Enter(const parser::OpenMPAtomicConstruct &x) {
|
|||
CheckAtomicMemoryOrderClause(
|
||||
&std::get<parser::OmpAtomicClauseList>(atomicConstruct.t),
|
||||
nullptr);
|
||||
CheckHintClause<const parser::OmpAtomicClauseList>(
|
||||
&std::get<parser::OmpAtomicClauseList>(atomicConstruct.t),
|
||||
nullptr);
|
||||
},
|
||||
[&](const parser::OmpAtomicUpdate &atomicUpdate) {
|
||||
const auto &dir{std::get<parser::Verbatim>(atomicUpdate.t)};
|
||||
|
@ -1591,6 +1637,8 @@ void OmpStructureChecker::Enter(const parser::OpenMPAtomicConstruct &x) {
|
|||
.statement);
|
||||
CheckAtomicMemoryOrderClause(
|
||||
&std::get<0>(atomicUpdate.t), &std::get<2>(atomicUpdate.t));
|
||||
CheckHintClause<const parser::OmpAtomicClauseList>(
|
||||
&std::get<0>(atomicUpdate.t), &std::get<2>(atomicUpdate.t));
|
||||
},
|
||||
[&](const auto &atomicConstruct) {
|
||||
const auto &dir{std::get<parser::Verbatim>(atomicConstruct.t)};
|
||||
|
@ -1598,6 +1646,9 @@ void OmpStructureChecker::Enter(const parser::OpenMPAtomicConstruct &x) {
|
|||
dir.source, llvm::omp::Directive::OMPD_atomic);
|
||||
CheckAtomicMemoryOrderClause(&std::get<0>(atomicConstruct.t),
|
||||
&std::get<2>(atomicConstruct.t));
|
||||
CheckHintClause<const parser::OmpAtomicClauseList>(
|
||||
&std::get<0>(atomicConstruct.t),
|
||||
&std::get<2>(atomicConstruct.t));
|
||||
},
|
||||
},
|
||||
x.u);
|
||||
|
|
|
@ -268,6 +268,7 @@ private:
|
|||
void EnterDirectiveNest(const int index) { directiveNest_[index]++; }
|
||||
void ExitDirectiveNest(const int index) { directiveNest_[index]--; }
|
||||
int GetDirectiveNest(const int index) { return directiveNest_[index]; }
|
||||
template <typename D> void CheckHintClause(D *, D *);
|
||||
|
||||
enum directiveNestType {
|
||||
SIMDNest,
|
||||
|
|
105
flang/test/Semantics/OpenMP/omp-atomic-hint-clause.f90
Normal file
105
flang/test/Semantics/OpenMP/omp-atomic-hint-clause.f90
Normal file
|
@ -0,0 +1,105 @@
|
|||
! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
|
||||
! Semantic checks on hint clauses, as they appear on atomic constructs
|
||||
|
||||
program sample
|
||||
use omp_lib
|
||||
integer :: x, y
|
||||
logical :: z
|
||||
real :: k
|
||||
integer :: p(1)
|
||||
integer, parameter :: a = 1
|
||||
!$omp atomic hint(1) write
|
||||
y = 2
|
||||
|
||||
!$omp atomic read hint(2)
|
||||
y = x
|
||||
|
||||
!ERROR: Hint clause value is not a valid OpenMP synchronization value
|
||||
!$omp atomic hint(3)
|
||||
y = y + 10
|
||||
|
||||
!$omp atomic update hint(5)
|
||||
y = x
|
||||
|
||||
!ERROR: Hint clause value is not a valid OpenMP synchronization value
|
||||
!$omp atomic hint(7) capture
|
||||
y = x
|
||||
x = y
|
||||
!$omp end atomic
|
||||
|
||||
!ERROR: Hint clause must have non-negative constant integer expression
|
||||
!ERROR: Must be a constant value
|
||||
!$omp atomic update hint(x)
|
||||
y = y * 1
|
||||
|
||||
!$omp atomic read hint(4)
|
||||
y = x
|
||||
|
||||
!$omp atomic hint(8)
|
||||
x = x * y
|
||||
|
||||
!$omp atomic write hint(omp_sync_hint_uncontended)
|
||||
x = 10 * y
|
||||
|
||||
!$omp atomic hint(omp_lock_hint_speculative)
|
||||
x = y + x
|
||||
|
||||
!ERROR: Hint clause must have non-negative constant integer expression
|
||||
!ERROR: Must be a constant value
|
||||
!$omp atomic hint(omp_sync_hint_uncontended + omp_sync_hint) read
|
||||
y = x
|
||||
|
||||
!$omp atomic hint(omp_sync_hint_nonspeculative)
|
||||
y = y * 9
|
||||
|
||||
!$omp atomic hint(omp_sync_hint_none) read
|
||||
y = x
|
||||
|
||||
!$omp atomic read hint(omp_sync_hint_uncontended + omp_lock_hint_speculative)
|
||||
y = x
|
||||
|
||||
!$omp atomic hint(omp_lock_hint_nonspeculative + omp_lock_hint_uncontended)
|
||||
x = x * y
|
||||
|
||||
!$omp atomic write hint(omp_lock_hint_contended + omp_sync_hint_speculative)
|
||||
x = 10 * y
|
||||
|
||||
!$omp atomic hint(omp_lock_hint_contended + omp_sync_hint_nonspeculative)
|
||||
x = y + x
|
||||
|
||||
!ERROR: Hint clause value is not a valid OpenMP synchronization value
|
||||
!$omp atomic hint(omp_sync_hint_uncontended + omp_sync_hint_contended) read
|
||||
y = x
|
||||
|
||||
!ERROR: Hint clause value is not a valid OpenMP synchronization value
|
||||
!$omp atomic hint(omp_sync_hint_nonspeculative + omp_lock_hint_speculative)
|
||||
y = y * 9
|
||||
|
||||
!ERROR: Hint clause must have non-negative constant integer expression
|
||||
!$omp atomic hint(1.0) read
|
||||
y = x
|
||||
|
||||
!ERROR: Hint clause must have non-negative constant integer expression
|
||||
!ERROR: Operands of + must be numeric; have LOGICAL(4) and INTEGER(4)
|
||||
!$omp atomic hint(z + omp_sync_hint_nonspeculative) read
|
||||
y = x
|
||||
|
||||
!ERROR: Hint clause must have non-negative constant integer expression
|
||||
!ERROR: Must be a constant value
|
||||
!$omp atomic hint(k + omp_sync_hint_speculative) read
|
||||
y = x
|
||||
|
||||
!ERROR: Hint clause must have non-negative constant integer expression
|
||||
!ERROR: Must be a constant value
|
||||
!$omp atomic hint(p(1) + omp_sync_hint_uncontended) write
|
||||
x = 10 * y
|
||||
|
||||
!$omp atomic write hint(a)
|
||||
x = y + x
|
||||
|
||||
!$omp atomic hint(abs(-1)) write
|
||||
x = 7
|
||||
|
||||
!$omp atomic hint(omp_sync_hint_uncontended + omp_sync_hint_uncontended + omp_sync_hint_speculative) write
|
||||
x = 7
|
||||
end program
|
118
flang/test/Semantics/OpenMP/omp-critical-hint-clause.f90
Normal file
118
flang/test/Semantics/OpenMP/omp-critical-hint-clause.f90
Normal file
|
@ -0,0 +1,118 @@
|
|||
! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
|
||||
! Semantic checks on hint clauses, as they appear on critical construct
|
||||
|
||||
program sample
|
||||
use omp_lib
|
||||
integer :: y
|
||||
logical :: z
|
||||
real :: k
|
||||
integer :: p(1)
|
||||
|
||||
!$omp critical (name) hint(1)
|
||||
y = 2
|
||||
!$omp end critical (name)
|
||||
|
||||
!$omp critical (name) hint(2)
|
||||
y = 2
|
||||
!$omp end critical (name)
|
||||
|
||||
!ERROR: Hint clause value is not a valid OpenMP synchronization value
|
||||
!$omp critical (name) hint(3)
|
||||
y = 2
|
||||
!$omp end critical (name)
|
||||
|
||||
!$omp critical (name) hint(5)
|
||||
y = 2
|
||||
!$omp end critical (name)
|
||||
|
||||
!ERROR: Hint clause value is not a valid OpenMP synchronization value
|
||||
!$omp critical (name) hint(7)
|
||||
y = 2
|
||||
!$omp end critical (name)
|
||||
|
||||
!ERROR: Hint clause must have non-negative constant integer expression
|
||||
!ERROR: Must be a constant value
|
||||
!$omp critical (name) hint(x)
|
||||
y = 2
|
||||
!$omp end critical (name)
|
||||
|
||||
!$omp critical (name) hint(4)
|
||||
y = 2
|
||||
!$omp end critical (name)
|
||||
|
||||
!$omp critical (name) hint(8)
|
||||
y = 2
|
||||
!$omp end critical (name)
|
||||
|
||||
!$omp critical (name) hint(omp_sync_hint_uncontended)
|
||||
y = 2
|
||||
!$omp end critical (name)
|
||||
|
||||
!$omp critical (name) hint(omp_lock_hint_speculative)
|
||||
y = 2
|
||||
!$omp end critical (name)
|
||||
|
||||
!ERROR: Hint clause must have non-negative constant integer expression
|
||||
!ERROR: Must be a constant value
|
||||
!$omp critical (name) hint(omp_sync_hint_uncontended + omp_sync_hint)
|
||||
y = 2
|
||||
!$omp end critical (name)
|
||||
|
||||
!$omp critical (name) hint(omp_sync_hint_nonspeculative)
|
||||
y = 2
|
||||
!$omp end critical (name)
|
||||
|
||||
!$omp critical (name) hint(omp_sync_hint_none)
|
||||
y = 2
|
||||
!$omp end critical (name)
|
||||
|
||||
!$omp critical (name) hint(omp_sync_hint_uncontended + omp_lock_hint_speculative)
|
||||
y = 2
|
||||
!$omp end critical (name)
|
||||
|
||||
!$omp critical (name) hint(omp_lock_hint_nonspeculative + omp_lock_hint_uncontended)
|
||||
y = 2
|
||||
!$omp end critical (name)
|
||||
|
||||
!$omp critical (name) hint(omp_lock_hint_contended + omp_sync_hint_speculative)
|
||||
y = 2
|
||||
!$omp end critical (name)
|
||||
|
||||
!$omp critical (name) hint(omp_lock_hint_contended + omp_sync_hint_nonspeculative)
|
||||
y = 2
|
||||
!$omp end critical (name)
|
||||
|
||||
!ERROR: Hint clause value is not a valid OpenMP synchronization value
|
||||
!$omp critical (name) hint(omp_sync_hint_uncontended + omp_sync_hint_contended)
|
||||
y = 2
|
||||
!$omp end critical (name)
|
||||
|
||||
!ERROR: Hint clause value is not a valid OpenMP synchronization value
|
||||
!$omp critical (name) hint(omp_sync_hint_nonspeculative + omp_lock_hint_speculative)
|
||||
y = 2
|
||||
!$omp end critical (name)
|
||||
|
||||
!ERROR: Hint clause must have non-negative constant integer expression
|
||||
!$omp critical (name) hint(1.0)
|
||||
y = 2
|
||||
!$omp end critical (name)
|
||||
|
||||
!ERROR: Hint clause must have non-negative constant integer expression
|
||||
!ERROR: Operands of + must be numeric; have LOGICAL(4) and INTEGER(4)
|
||||
!$omp critical (name) hint(z + omp_sync_hint_nonspeculative)
|
||||
y = 2
|
||||
!$omp end critical (name)
|
||||
|
||||
!ERROR: Hint clause must have non-negative constant integer expression
|
||||
!ERROR: Must be a constant value
|
||||
!$omp critical (name) hint(k + omp_sync_hint_speculative)
|
||||
y = 2
|
||||
!$omp end critical (name)
|
||||
|
||||
!ERROR: Hint clause must have non-negative constant integer expression
|
||||
!ERROR: Must be a constant value
|
||||
!$omp critical (name) hint(p(1) + omp_sync_hint_uncontended)
|
||||
y = 2
|
||||
!$omp end critical (name)
|
||||
end program
|
||||
|
Loading…
Reference in a new issue