From e361afb6c5c9e0360d1782a23f143f80da94cee8 Mon Sep 17 00:00:00 2001 From: Arnamoy Bhattacharyya Date: Thu, 11 Mar 2021 08:15:55 -0500 Subject: [PATCH] [flang][OpenMP] Add semantic check for occurrence of multiple list items in aligned clause for simd directive Reviewed By: kiranchandramohan, clementval Differential Revision: https://reviews.llvm.org/D97964 --- .../lib/Semantics/check-directive-structure.h | 9 +++- flang/lib/Semantics/check-omp-structure.cpp | 19 ++++++- flang/test/Semantics/omp-simd-aligned.f90 | 54 +++++++++++++++++++ 3 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 flang/test/Semantics/omp-simd-aligned.f90 diff --git a/flang/lib/Semantics/check-directive-structure.h b/flang/lib/Semantics/check-directive-structure.h index 468aa07bd174..5d0750eda402 100644 --- a/flang/lib/Semantics/check-directive-structure.h +++ b/flang/lib/Semantics/check-directive-structure.h @@ -123,6 +123,7 @@ protected: : context_{context}, directiveClausesMap_(directiveClausesMap) {} virtual ~DirectiveStructureChecker() {} + using ClauseMapTy = std::multimap; struct DirectiveContext { DirectiveContext(parser::CharBlock source, D d) : directiveSource{source}, directive{d} {} @@ -136,7 +137,7 @@ protected: common::EnumSet requiredClauses{}; const PC *clause{nullptr}; - std::multimap clauseInfo; + ClauseMapTy clauseInfo; std::list actualClauses; Symbol *loopIV{nullptr}; }; @@ -205,6 +206,12 @@ protected: return nullptr; } + std::pair + FindClauses(C type) { + auto it{GetContext().clauseInfo.equal_range(type)}; + return it; + } + void PushContext(const parser::CharBlock &source, D dir) { dirContext_.emplace_back(source, dir); } diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index 790072b9f6a9..d41e37fed1e3 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -606,7 +606,24 @@ void OmpStructureChecker::Leave(const parser::OmpClauseList &) { } } } - // TODO: A list-item cannot appear in more than one aligned clause + // A list-item cannot appear in more than one aligned clause + semantics::SymbolSet alignedVars; + auto clauseAll = FindClauses(llvm::omp::Clause::OMPC_aligned); + for (auto itr = clauseAll.first; itr != clauseAll.second; ++itr) { + const auto &alignedClause{ + std::get(itr->second->u)}; + const auto &alignedNameList{ + std::get>(alignedClause.v.t)}; + for (auto const &var : alignedNameList) { + if (alignedVars.count(*(var.symbol)) == 1) { + context_.Say(itr->second->source, + "List item '%s' present at multiple ALIGNED clauses"_err_en_US, + var.ToString()); + break; + } + alignedVars.insert(*(var.symbol)); + } + } } // SIMD // 2.7.3 Single Construct Restriction diff --git a/flang/test/Semantics/omp-simd-aligned.f90 b/flang/test/Semantics/omp-simd-aligned.f90 new file mode 100644 index 000000000000..5626608114d5 --- /dev/null +++ b/flang/test/Semantics/omp-simd-aligned.f90 @@ -0,0 +1,54 @@ +! RUN: %S/test_errors.sh %s %t %flang -fopenmp + +! OpenMP Version 4.5 +! 2.8.1 simd Construct +! Semantic error for correct test case + +program omp_simd + integer i, j, k + integer, allocatable :: a(:), b(:) + + allocate(a(10)) + allocate(b(10)) + + !ERROR: List item 'a' present at multiple ALIGNED clauses + !$omp simd aligned(a, a) + do i = 1, 10 + a(i) = i + end do + !$omp end simd + + !ERROR: List item 'a' present at multiple ALIGNED clauses + !ERROR: List item 'b' present at multiple ALIGNED clauses + !$omp simd aligned(a,a) aligned(b) aligned(b) + do i = 1, 10 + a(i) = i + b(i) = i + end do + !$omp end simd + + !ERROR: List item 'a' present at multiple ALIGNED clauses + !$omp simd aligned(a) aligned(a) + do i = 1, 10 + a(i) = i + end do + !$omp end simd + + !$omp simd aligned(a) aligned(b) + do i = 1, 10 + a(i) = i + b(i) = i + end do + !$omp end simd + + !ERROR: List item 'a' present at multiple ALIGNED clauses + !$omp simd aligned(a) private(a) aligned(a) + do i = 1, 10 + a(i) = i + b(i) = i + end do + !$omp end simd + + print *, a + +end program omp_simd