Skip to content

Commit

Permalink
[flang][OpenMP] Add version checks for clauses
Browse files Browse the repository at this point in the history
If there is a clause that is allowed on a given directive in a later
version of the OpenMP spec, report an error and provide the minimal
spec version that allows the clause.

The case where a clause is not allowed on a directive at all is already
handled elsewhere.
  • Loading branch information
kparzysz committed Sep 25, 2024
1 parent cfbea65 commit 2474373
Show file tree
Hide file tree
Showing 43 changed files with 137 additions and 99 deletions.
93 changes: 65 additions & 28 deletions flang/lib/Semantics/check-omp-structure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,25 @@ namespace Fortran::semantics {
// Use when clause falls under 'struct OmpClause' in 'parse-tree.h'.
#define CHECK_SIMPLE_CLAUSE(X, Y) \
void OmpStructureChecker::Enter(const parser::OmpClause::X &) { \
CheckAllowed(llvm::omp::Clause::Y); \
CheckAllowedClause(llvm::omp::Clause::Y); \
}

#define CHECK_REQ_CONSTANT_SCALAR_INT_CLAUSE(X, Y) \
void OmpStructureChecker::Enter(const parser::OmpClause::X &c) { \
CheckAllowed(llvm::omp::Clause::Y); \
CheckAllowedClause(llvm::omp::Clause::Y); \
RequiresConstantPositiveParameter(llvm::omp::Clause::Y, c.v); \
}

#define CHECK_REQ_SCALAR_INT_CLAUSE(X, Y) \
void OmpStructureChecker::Enter(const parser::OmpClause::X &c) { \
CheckAllowed(llvm::omp::Clause::Y); \
CheckAllowedClause(llvm::omp::Clause::Y); \
RequiresPositiveParameter(llvm::omp::Clause::Y, c.v); \
}

// Use when clause don't falls under 'struct OmpClause' in 'parse-tree.h'.
#define CHECK_SIMPLE_PARSER_CLAUSE(X, Y) \
void OmpStructureChecker::Enter(const parser::X &) { \
CheckAllowed(llvm::omp::Y); \
CheckAllowedClause(llvm::omp::Y); \
}

// 'OmpWorkshareBlockChecker' is used to check the validity of the assignment
Expand Down Expand Up @@ -163,6 +163,43 @@ class AssociatedLoopChecker {
std::map<std::string, std::int64_t> constructNamesAndLevels_;
};

bool OmpStructureChecker::CheckAllowedClause(llvmOmpClause clause) {
unsigned version{context_.langOptions().OpenMPVersion};
DirectiveContext &dirCtx = GetContext();
llvm::omp::Directive dir{dirCtx.directive};

if (!llvm::omp::isAllowedClauseForDirective(dir, clause, version)) {
unsigned allowedInVersion{[&] {
for (unsigned v : {45, 50, 51, 52, 60}) {
if (v <= version) {
continue;
}
if (llvm::omp::isAllowedClauseForDirective(dir, clause, v)) {
return v;
}
}
return 0u;
}()};

auto clauseName{parser::ToUpperCaseLetters(getClauseName(clause).str())};
auto dirName{parser::ToUpperCaseLetters(getDirectiveName(dir).str())};

// Only report it if there is a later version that allows it.
// If it's not allowed at all, it will be reported by CheckAllowed.
if (allowedInVersion != 0) {
std::string thisVersion{std::to_string(version / 10) + "." +
std::to_string(version % 10)};
std::string goodVersion{std::to_string(allowedInVersion)};

context_.Say(dirCtx.clauseSource,
"%s clause is not allowed on directive %s in OpenMP v%s, "
"try -fopenmp-version=%d"_err_en_US,
clauseName, dirName, thisVersion, allowedInVersion);
}
}
return CheckAllowed(clause);
}

bool OmpStructureChecker::IsCloselyNestedRegion(const OmpDirectiveSet &set) {
// Definition of close nesting:
//
Expand Down Expand Up @@ -1156,7 +1193,7 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclarativeAllocate &x) {
}

void OmpStructureChecker::Enter(const parser::OmpClause::Allocator &x) {
CheckAllowed(llvm::omp::Clause::OMPC_allocator);
CheckAllowedClause(llvm::omp::Clause::OMPC_allocator);
// Note: Predefined allocators are stored in ScalarExpr as numbers
// whereas custom allocators are stored as strings, so if the ScalarExpr
// actually has an int value, then it must be a predefined allocator
Expand All @@ -1165,7 +1202,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Allocator &x) {
}

void OmpStructureChecker::Enter(const parser::OmpClause::Allocate &x) {
CheckAllowed(llvm::omp::Clause::OMPC_allocate);
CheckAllowedClause(llvm::omp::Clause::OMPC_allocate);
if (const auto &modifier{
std::get<std::optional<parser::OmpAllocateClause::AllocateModifier>>(
x.v.t)}) {
Expand Down Expand Up @@ -2310,7 +2347,7 @@ CHECK_REQ_CONSTANT_SCALAR_INT_CLAUSE(Simdlen, OMPC_simdlen)
// Restrictions specific to each clause are implemented apart from the
// generalized restrictions.
void OmpStructureChecker::Enter(const parser::OmpClause::Reduction &x) {
CheckAllowed(llvm::omp::Clause::OMPC_reduction);
CheckAllowedClause(llvm::omp::Clause::OMPC_reduction);
if (CheckReductionOperators(x)) {
CheckReductionTypeList(x);
}
Expand Down Expand Up @@ -2634,7 +2671,7 @@ void OmpStructureChecker::CheckSharedBindingInOuterContext(
}

void OmpStructureChecker::Enter(const parser::OmpClause::Ordered &x) {
CheckAllowed(llvm::omp::Clause::OMPC_ordered);
CheckAllowedClause(llvm::omp::Clause::OMPC_ordered);
// the parameter of ordered clause is optional
if (const auto &expr{x.v}) {
RequiresConstantPositiveParameter(llvm::omp::Clause::OMPC_ordered, *expr);
Expand All @@ -2649,17 +2686,17 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Ordered &x) {
}

void OmpStructureChecker::Enter(const parser::OmpClause::Shared &x) {
CheckAllowed(llvm::omp::Clause::OMPC_shared);
CheckAllowedClause(llvm::omp::Clause::OMPC_shared);
CheckIsVarPartOfAnotherVar(GetContext().clauseSource, x.v, "SHARED");
}
void OmpStructureChecker::Enter(const parser::OmpClause::Private &x) {
CheckAllowed(llvm::omp::Clause::OMPC_private);
CheckAllowedClause(llvm::omp::Clause::OMPC_private);
CheckIsVarPartOfAnotherVar(GetContext().clauseSource, x.v, "PRIVATE");
CheckIntentInPointer(x.v, llvm::omp::Clause::OMPC_private);
}

void OmpStructureChecker::Enter(const parser::OmpClause::Nowait &x) {
CheckAllowed(llvm::omp::Clause::OMPC_nowait);
CheckAllowedClause(llvm::omp::Clause::OMPC_nowait);
if (llvm::omp::noWaitClauseNotAllowedSet.test(GetContext().directive)) {
context_.Say(GetContext().clauseSource,
"%s clause is not allowed on the OMP %s directive,"
Expand Down Expand Up @@ -2732,7 +2769,7 @@ void OmpStructureChecker::CheckIsVarPartOfAnotherVar(
}

void OmpStructureChecker::Enter(const parser::OmpClause::Firstprivate &x) {
CheckAllowed(llvm::omp::Clause::OMPC_firstprivate);
CheckAllowedClause(llvm::omp::Clause::OMPC_firstprivate);

CheckIsVarPartOfAnotherVar(GetContext().clauseSource, x.v, "FIRSTPRIVATE");
CheckIsLoopIvPartOfClause(llvmOmpClause::OMPC_firstprivate, x.v);
Expand Down Expand Up @@ -2819,7 +2856,7 @@ void OmpStructureChecker::Leave(const parser::OmpAtomic &) {
// Restrictions specific to each clause are implemented apart from the
// generalized restrictions.
void OmpStructureChecker::Enter(const parser::OmpClause::Aligned &x) {
CheckAllowed(llvm::omp::Clause::OMPC_aligned);
CheckAllowedClause(llvm::omp::Clause::OMPC_aligned);

if (const auto &expr{
std::get<std::optional<parser::ScalarIntConstantExpr>>(x.v.t)}) {
Expand All @@ -2828,7 +2865,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Aligned &x) {
// 2.8.1 TODO: list-item attribute check
}
void OmpStructureChecker::Enter(const parser::OmpClause::Defaultmap &x) {
CheckAllowed(llvm::omp::Clause::OMPC_defaultmap);
CheckAllowedClause(llvm::omp::Clause::OMPC_defaultmap);
using VariableCategory = parser::OmpDefaultmapClause::VariableCategory;
if (!std::get<std::optional<VariableCategory>>(x.v.t)) {
context_.Say(GetContext().clauseSource,
Expand All @@ -2837,7 +2874,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Defaultmap &x) {
}
}
void OmpStructureChecker::Enter(const parser::OmpClause::If &x) {
CheckAllowed(llvm::omp::Clause::OMPC_if);
CheckAllowedClause(llvm::omp::Clause::OMPC_if);
using dirNameModifier = parser::OmpIfClause::DirectiveNameModifier;
// TODO Check that, when multiple 'if' clauses are applied to a combined
// construct, at most one of them applies to each directive.
Expand Down Expand Up @@ -2873,7 +2910,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::If &x) {
}

void OmpStructureChecker::Enter(const parser::OmpClause::Linear &x) {
CheckAllowed(llvm::omp::Clause::OMPC_linear);
CheckAllowedClause(llvm::omp::Clause::OMPC_linear);

// 2.7 Loop Construct Restriction
if ((llvm::omp::allDoSet | llvm::omp::allSimdSet)
Expand Down Expand Up @@ -2907,7 +2944,7 @@ void OmpStructureChecker::CheckAllowedMapTypes(
}

void OmpStructureChecker::Enter(const parser::OmpClause::Map &x) {
CheckAllowed(llvm::omp::Clause::OMPC_map);
CheckAllowedClause(llvm::omp::Clause::OMPC_map);

if (const auto &maptype{std::get<std::optional<parser::OmpMapType>>(x.v.t)}) {
using Type = parser::OmpMapType::Type;
Expand Down Expand Up @@ -2953,7 +2990,7 @@ bool OmpStructureChecker::ScheduleModifierHasType(
return false;
}
void OmpStructureChecker::Enter(const parser::OmpClause::Schedule &x) {
CheckAllowed(llvm::omp::Clause::OMPC_schedule);
CheckAllowedClause(llvm::omp::Clause::OMPC_schedule);
const parser::OmpScheduleClause &scheduleClause = x.v;

// 2.7 Loop Construct Restriction
Expand Down Expand Up @@ -2989,7 +3026,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Schedule &x) {
}

void OmpStructureChecker::Enter(const parser::OmpClause::Device &x) {
CheckAllowed(llvm::omp::Clause::OMPC_device);
CheckAllowedClause(llvm::omp::Clause::OMPC_device);
const parser::OmpDeviceClause &deviceClause = x.v;
const auto &device{std::get<1>(deviceClause.t)};
RequiresPositiveParameter(
Expand All @@ -3008,7 +3045,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Device &x) {
}

void OmpStructureChecker::Enter(const parser::OmpClause::Depend &x) {
CheckAllowed(llvm::omp::Clause::OMPC_depend);
CheckAllowedClause(llvm::omp::Clause::OMPC_depend);
if ((std::holds_alternative<parser::OmpDependClause::Source>(x.v.u) ||
std::holds_alternative<parser::OmpDependClause::Sink>(x.v.u)) &&
GetContext().directive != llvm::omp::OMPD_ordered) {
Expand Down Expand Up @@ -3051,7 +3088,7 @@ void OmpStructureChecker::CheckCopyingPolymorphicAllocatable(
}

void OmpStructureChecker::Enter(const parser::OmpClause::Copyprivate &x) {
CheckAllowed(llvm::omp::Clause::OMPC_copyprivate);
CheckAllowedClause(llvm::omp::Clause::OMPC_copyprivate);
CheckIntentInPointer(x.v, llvm::omp::Clause::OMPC_copyprivate);
SymbolSourceMap currSymbols;
GetSymbolsInObjectList(x.v, currSymbols);
Expand All @@ -3069,7 +3106,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Copyprivate &x) {
}

void OmpStructureChecker::Enter(const parser::OmpClause::Lastprivate &x) {
CheckAllowed(llvm::omp::Clause::OMPC_lastprivate);
CheckAllowedClause(llvm::omp::Clause::OMPC_lastprivate);

CheckIsVarPartOfAnotherVar(GetContext().clauseSource, x.v, "LASTPRIVATE");

Expand All @@ -3093,7 +3130,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Lastprivate &x) {
}

void OmpStructureChecker::Enter(const parser::OmpClause::Copyin &x) {
CheckAllowed(llvm::omp::Clause::OMPC_copyin);
CheckAllowedClause(llvm::omp::Clause::OMPC_copyin);

SymbolSourceMap currSymbols;
GetSymbolsInObjectList(x.v, currSymbols);
Expand Down Expand Up @@ -3128,7 +3165,7 @@ void OmpStructureChecker::CheckStructureElement(

void OmpStructureChecker::Enter(const parser::OmpClause::UseDevicePtr &x) {
CheckStructureElement(x.v, llvm::omp::Clause::OMPC_use_device_ptr);
CheckAllowed(llvm::omp::Clause::OMPC_use_device_ptr);
CheckAllowedClause(llvm::omp::Clause::OMPC_use_device_ptr);
SymbolSourceMap currSymbols;
GetSymbolsInObjectList(x.v, currSymbols);
semantics::UnorderedSymbolSet listVars;
Expand Down Expand Up @@ -3161,7 +3198,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::UseDevicePtr &x) {

void OmpStructureChecker::Enter(const parser::OmpClause::UseDeviceAddr &x) {
CheckStructureElement(x.v, llvm::omp::Clause::OMPC_use_device_addr);
CheckAllowed(llvm::omp::Clause::OMPC_use_device_addr);
CheckAllowedClause(llvm::omp::Clause::OMPC_use_device_addr);
SymbolSourceMap currSymbols;
GetSymbolsInObjectList(x.v, currSymbols);
semantics::UnorderedSymbolSet listVars;
Expand All @@ -3186,7 +3223,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::UseDeviceAddr &x) {
}

void OmpStructureChecker::Enter(const parser::OmpClause::IsDevicePtr &x) {
CheckAllowed(llvm::omp::Clause::OMPC_is_device_ptr);
CheckAllowedClause(llvm::omp::Clause::OMPC_is_device_ptr);
SymbolSourceMap currSymbols;
GetSymbolsInObjectList(x.v, currSymbols);
semantics::UnorderedSymbolSet listVars;
Expand Down Expand Up @@ -3224,7 +3261,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::IsDevicePtr &x) {
}

void OmpStructureChecker::Enter(const parser::OmpClause::HasDeviceAddr &x) {
CheckAllowed(llvm::omp::Clause::OMPC_has_device_addr);
CheckAllowedClause(llvm::omp::Clause::OMPC_has_device_addr);
SymbolSourceMap currSymbols;
GetSymbolsInObjectList(x.v, currSymbols);
semantics::UnorderedSymbolSet listVars;
Expand Down Expand Up @@ -3569,7 +3606,7 @@ void OmpStructureChecker::Enter(
}

void OmpStructureChecker::CheckAllowedRequiresClause(llvmOmpClause clause) {
CheckAllowed(clause);
CheckAllowedClause(clause);

if (clause != llvm::omp::Clause::OMPC_atomic_default_mem_order) {
// Check that it does not appear after a device construct
Expand Down
1 change: 1 addition & 0 deletions flang/lib/Semantics/check-omp-structure.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ class OmpStructureChecker
}

private:
bool CheckAllowedClause(llvmOmpClause clause);
void CheckMultipleOccurrence(semantics::UnorderedSymbolSet &listVars,
const std::list<parser::Name> &nameList, const parser::CharBlock &item,
const std::string &clauseName);
Expand Down
4 changes: 2 additions & 2 deletions flang/test/Lower/OpenMP/atomic-capture.f90
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

! This test checks the lowering of atomic capture

! RUN: bbc %openmp_flags -emit-hlfir %s -o - | FileCheck %s
! RUN: %flang_fc1 -emit-hlfir %openmp_flags %s -o - | FileCheck %s
! RUN: bbc %openmp_flags -fopenmp-version=50 -emit-hlfir %s -o - | FileCheck %s
! RUN: %flang_fc1 -emit-hlfir %openmp_flags -fopenmp-version=50 %s -o - | FileCheck %s


program OmpAtomicCapture
Expand Down
2 changes: 1 addition & 1 deletion flang/test/Lower/OpenMP/atomic-read.f90
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
! REQUIRES: openmp_runtime

! RUN: bbc %openmp_flags -emit-hlfir %s -o - | FileCheck %s
! RUN: bbc %openmp_flags -fopenmp-version=50 -emit-hlfir %s -o - | FileCheck %s

! This test checks the lowering of atomic read

Expand Down
4 changes: 2 additions & 2 deletions flang/test/Lower/OpenMP/atomic-update.f90
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
! REQUIRES: openmp_runtime

! This test checks lowering of atomic and atomic update constructs
! RUN: bbc %openmp_flags -emit-hlfir %s -o - | FileCheck %s
! RUN: %flang_fc1 -emit-hlfir %openmp_flags %s -o - | FileCheck %s
! RUN: bbc %openmp_flags -fopenmp-version=50 -emit-hlfir %s -o - | FileCheck %s
! RUN: %flang_fc1 -emit-hlfir %openmp_flags -fopenmp-version=50 %s -o - | FileCheck %s

program OmpAtomicUpdate
use omp_lib
Expand Down
2 changes: 1 addition & 1 deletion flang/test/Lower/OpenMP/atomic-write.f90
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
! REQUIRES: openmp_runtime

! RUN: bbc %openmp_flags -emit-hlfir %s -o - | FileCheck %s
! RUN: bbc %openmp_flags -fopenmp-version=50 -emit-hlfir %s -o - | FileCheck %s

! This test checks the lowering of atomic write

Expand Down
4 changes: 2 additions & 2 deletions flang/test/Lower/OpenMP/declare-target-data.f90
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
!RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
!RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-is-target-device %s -o - | FileCheck %s
!RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=52 %s -o - | FileCheck %s
!RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=52 -fopenmp-is-target-device %s -o - | FileCheck %s

module test_0
implicit none
Expand Down
4 changes: 2 additions & 2 deletions flang/test/Lower/OpenMP/declare-target-deferred-marking.f90
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
!RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s --check-prefixes ALL,HOST
!RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-is-device %s -o - | FileCheck %s --check-prefixes ALL
!RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=52 %s -o - | FileCheck %s --check-prefixes ALL,HOST
!RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=52 -fopenmp-is-device %s -o - | FileCheck %s --check-prefixes ALL

program main
use, intrinsic :: iso_c_binding
Expand Down
4 changes: 2 additions & 2 deletions flang/test/Lower/OpenMP/declare-target-func-and-subr.f90
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
!RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s --check-prefixes ALL,HOST
!RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-is-device %s -o - | FileCheck %s --check-prefixes ALL,DEVICE
!RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=52 %s -o - | FileCheck %s --check-prefixes ALL,HOST
!RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=52 -fopenmp-is-device %s -o - | FileCheck %s --check-prefixes ALL,DEVICE

! Check specification valid forms of declare target with functions
! utilising device_type and to clauses as well as the default
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
!RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
!RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-is-target-device %s -o - | FileCheck %s --check-prefix=DEVICE
!RUN: bbc -emit-hlfir -fopenmp %s -o - | FileCheck %s
!RUN: bbc -emit-hlfir -fopenmp -fopenmp-is-target-device %s -o - | FileCheck %s --check-prefix=DEVICE
!RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=52 %s -o - | FileCheck %s
!RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=52 -fopenmp-is-target-device %s -o - | FileCheck %s --check-prefix=DEVICE
!RUN: bbc -emit-hlfir -fopenmp -fopenmp-version=52 %s -o - | FileCheck %s
!RUN: bbc -emit-hlfir -fopenmp -fopenmp-version=52 -fopenmp-is-target-device %s -o - | FileCheck %s --check-prefix=DEVICE

! CHECK-LABEL: func.func @_QPimplicitly_captured_twice
! CHECK-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (enter)>{{.*}}}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
!RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
!RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-is-target-device %s -o - | FileCheck %s --check-prefix=DEVICE
!RUN: bbc -emit-hlfir -fopenmp %s -o - | FileCheck %s
!RUN: bbc -emit-hlfir -fopenmp -fopenmp-is-target-device %s -o - | FileCheck %s --check-prefix=DEVICE
!RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 %s -o - | FileCheck %s
!RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 -fopenmp-is-target-device %s -o - | FileCheck %s --check-prefix=DEVICE
!RUN: bbc -emit-hlfir -fopenmp -fopenmp-version=50 %s -o - | FileCheck %s
!RUN: bbc -emit-hlfir -fopenmp -fopenmp-version=50 -fopenmp-is-target-device %s -o - | FileCheck %s --check-prefix=DEVICE

! CHECK-LABEL: func.func @_QPimplicitly_captured
! CHECK-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (any), capture_clause = (to)>{{.*}}}
Expand Down
8 changes: 4 additions & 4 deletions flang/test/Lower/OpenMP/declare-target-implicit-tarop-cap.f90
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
!RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
!RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-is-device %s -o - | FileCheck %s --check-prefix=DEVICE
!RUN: bbc -emit-hlfir -fopenmp %s -o - | FileCheck %s
!RUN: bbc -emit-hlfir -fopenmp -fopenmp-is-target-device %s -o - | FileCheck %s --check-prefix=DEVICE
!RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=52 %s -o - | FileCheck %s
!RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=52 -fopenmp-is-device %s -o - | FileCheck %s --check-prefix=DEVICE
!RUN: bbc -emit-hlfir -fopenmp -fopenmp-version=52 %s -o - | FileCheck %s
!RUN: bbc -emit-hlfir -fopenmp -fopenmp-version=52 -fopenmp-is-target-device %s -o - | FileCheck %s --check-prefix=DEVICE

! DEVICE-LABEL: func.func @_QPimplicit_capture
! DEVICE-SAME: {{.*}}attributes {omp.declare_target = #omp.declaretarget<device_type = (nohost), capture_clause = (to)>{{.*}}}
Expand Down
Loading

0 comments on commit 2474373

Please sign in to comment.