diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -3462,8 +3462,8 @@ // 2.12 if-clause -> IF ([ directive-name-modifier :] scalar-logical-expr) struct OmpIfClause { TUPLE_CLASS_BOILERPLATE(OmpIfClause); - ENUM_CLASS(DirectiveNameModifier, Parallel, Target, TargetEnterData, - TargetExitData, TargetData, TargetUpdate, Taskloop, Task) + ENUM_CLASS(DirectiveNameModifier, Parallel, Simd, Target, TargetData, + TargetEnterData, TargetExitData, TargetUpdate, Task, Taskloop, Teams) std::tuple, ScalarLogicalExpr> t; }; diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp --- a/flang/lib/Lower/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP.cpp @@ -509,8 +509,10 @@ bool processCopyin() const; bool processDepend(llvm::SmallVectorImpl &dependTypeOperands, llvm::SmallVectorImpl &dependOperands) const; - bool processIf(Fortran::lower::StatementContext &stmtCtx, - mlir::Value &result) const; + bool + processIf(Fortran::lower::StatementContext &stmtCtx, + Fortran::parser::OmpIfClause::DirectiveNameModifier directiveName, + mlir::Value &result) const; bool processLink(llvm::SmallVectorImpl &result) const; bool processMap(llvm::SmallVectorImpl &mapOperands, @@ -1040,11 +1042,19 @@ pbKind); } -static mlir::Value -getIfClauseOperand(Fortran::lower::AbstractConverter &converter, - Fortran::lower::StatementContext &stmtCtx, - const Fortran::parser::OmpClause::If *ifClause, - mlir::Location clauseLocation) { +static mlir::Value getIfClauseOperand( + Fortran::lower::AbstractConverter &converter, + Fortran::lower::StatementContext &stmtCtx, + const Fortran::parser::OmpClause::If *ifClause, + Fortran::parser::OmpIfClause::DirectiveNameModifier directiveName, + mlir::Location clauseLocation) { + // Only consider the clause if it's intended for the given directive. + auto &directive = std::get< + std::optional>( + ifClause->v.t); + if (directive && directive.value() != directiveName) + return nullptr; + fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); auto &expr = std::get(ifClause->v.t); mlir::Value ifVal = fir::getBase( @@ -1563,17 +1573,25 @@ }); } -bool ClauseProcessor::processIf(Fortran::lower::StatementContext &stmtCtx, - mlir::Value &result) const { - return findRepeatableClause( +bool ClauseProcessor::processIf( + Fortran::lower::StatementContext &stmtCtx, + Fortran::parser::OmpIfClause::DirectiveNameModifier directiveName, + mlir::Value &result) const { + bool found = false; + findRepeatableClause( [&](const ClauseTy::If *ifClause, const Fortran::parser::CharBlock &source) { mlir::Location clauseLocation = converter.genLocation(source); - // TODO Consider DirectiveNameModifier of the `ifClause` to only search - // for an applicable 'if' clause. - result = - getIfClauseOperand(converter, stmtCtx, ifClause, clauseLocation); + mlir::Value operand = getIfClauseOperand(converter, stmtCtx, ifClause, + directiveName, clauseLocation); + // Assume that, at most, a single 'if' clause will be applicable to the + // given directive. + if (operand) { + result = operand; + found = true; + } }); + return found; } bool ClauseProcessor::processLink( @@ -2083,8 +2101,30 @@ llvm::SmallVector useDeviceLocs; llvm::SmallVector useDeviceSymbols; + Fortran::parser::OmpIfClause::DirectiveNameModifier directiveName; + switch (directive) { + case llvm::omp::Directive::OMPD_target: + directiveName = Fortran::parser::OmpIfClause::DirectiveNameModifier::Target; + break; + case llvm::omp::Directive::OMPD_target_data: + directiveName = + Fortran::parser::OmpIfClause::DirectiveNameModifier::TargetData; + break; + case llvm::omp::Directive::OMPD_target_enter_data: + directiveName = + Fortran::parser::OmpIfClause::DirectiveNameModifier::TargetEnterData; + break; + case llvm::omp::Directive::OMPD_target_exit_data: + directiveName = + Fortran::parser::OmpIfClause::DirectiveNameModifier::TargetExitData; + break; + default: + TODO(currentLocation, "OMPD_target directive unknown"); + break; + } + ClauseProcessor cp(converter, opClauseList); - cp.processIf(stmtCtx, ifClauseOperand); + cp.processIf(stmtCtx, directiveName, ifClauseOperand); cp.processDevice(stmtCtx, deviceOperand); cp.processThreadLimit(stmtCtx, threadLmtOperand); cp.processNowait(nowaitAttr); @@ -2131,8 +2171,6 @@ firOpBuilder.create(currentLocation, ifClauseOperand, deviceOperand, nowaitAttr, mapOperands, mapTypesArrayAttr); - } else { - TODO(currentLocation, "OMPD_target directive unknown"); } } @@ -2230,7 +2268,9 @@ // 1. default // Note: rest of the clauses are handled when the inner operation is created ClauseProcessor cp(converter, opClauseList); - cp.processIf(stmtCtx, ifClauseOperand); + cp.processIf(stmtCtx, + Fortran::parser::OmpIfClause::DirectiveNameModifier::Parallel, + ifClauseOperand); cp.processNumThreads(stmtCtx, numThreadsClauseOperand); cp.processProcBind(procBindKindAttr); @@ -2289,7 +2329,9 @@ cp.processCollapse(currentLocation, eval, lowerBound, upperBound, step, iv, loopVarTypeSize); cp.processScheduleChunk(stmtCtx, scheduleChunkClauseOperand); - cp.processIf(stmtCtx, ifClauseOperand); + cp.processIf(stmtCtx, + Fortran::parser::OmpIfClause::DirectiveNameModifier::Simd, + ifClauseOperand); cp.processReduction(currentLocation, reductionVars, reductionDeclSymbols); cp.processSimdlen(simdlenClauseOperand); cp.processSafelen(safelenClauseOperand); @@ -2390,10 +2432,36 @@ llvm::SmallVector dependTypeOperands, reductionDeclSymbols; mlir::UnitAttr nowaitAttr, untiedAttr, mergeableAttr; + // Use placeholder value to avoid uninitialized `directiveName` compiler + // errors. The 'if clause' obtained won't be used for these directives. + Fortran::parser::OmpIfClause::DirectiveNameModifier directiveName = + Fortran::parser::OmpIfClause::DirectiveNameModifier::Parallel; + switch (blockDirective.v) { + case llvm::omp::OMPD_parallel: + directiveName = + Fortran::parser::OmpIfClause::DirectiveNameModifier::Parallel; + break; + case llvm::omp::OMPD_task: + directiveName = Fortran::parser::OmpIfClause::DirectiveNameModifier::Task; + break; + // Target-related 'if' clauses handled by createTargetOp(). + case llvm::omp::OMPD_target: + case llvm::omp::OMPD_target_data: + // These block directives do not accept an 'if' clause. + case llvm::omp::OMPD_master: + case llvm::omp::OMPD_single: + case llvm::omp::OMPD_ordered: + case llvm::omp::OMPD_taskgroup: + break; + default: + TODO(currentLocation, "Unhandled block directive"); + break; + } + const auto &opClauseList = std::get(beginBlockDirective.t); ClauseProcessor cp(converter, opClauseList); - cp.processIf(stmtCtx, ifClauseOperand); + cp.processIf(stmtCtx, directiveName, ifClauseOperand); cp.processNumThreads(stmtCtx, numThreadsClauseOperand); cp.processProcBind(procBindKindAttr); cp.processAllocate(allocatorOperands, allocateOperands); @@ -2491,8 +2559,6 @@ } else if (blockDirective.v == llvm::omp::OMPD_target_data) { createTargetOp(converter, opClauseList, blockDirective.v, currentLocation, &eval); - } else { - TODO(currentLocation, "Unhandled block directive"); } } diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -115,6 +115,7 @@ TYPE_PARSER(construct( maybe( ("PARALLEL" >> pure(OmpIfClause::DirectiveNameModifier::Parallel) || + "SIMD" >> pure(OmpIfClause::DirectiveNameModifier::Simd) || "TARGET ENTER DATA" >> pure(OmpIfClause::DirectiveNameModifier::TargetEnterData) || "TARGET EXIT DATA" >> @@ -125,7 +126,8 @@ pure(OmpIfClause::DirectiveNameModifier::TargetUpdate) || "TARGET" >> pure(OmpIfClause::DirectiveNameModifier::Target) || "TASK"_id >> pure(OmpIfClause::DirectiveNameModifier::Task) || - "TASKLOOP" >> pure(OmpIfClause::DirectiveNameModifier::Taskloop)) / + "TASKLOOP" >> pure(OmpIfClause::DirectiveNameModifier::Taskloop) || + "TEAMS" >> pure(OmpIfClause::DirectiveNameModifier::Teams)) / ":"), scalarLogicalExpr)) diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h --- a/flang/lib/Semantics/check-omp-structure.h +++ b/flang/lib/Semantics/check-omp-structure.h @@ -66,22 +66,21 @@ Directive::OMPD_target_parallel, Directive::OMPD_target_parallel_do, Directive::OMPD_target_parallel_do_simd, Directive::OMPD_target_simd, Directive::OMPD_target_teams, Directive::OMPD_target_teams_distribute, + Directive::OMPD_target_teams_distribute_parallel_do, + Directive::OMPD_target_teams_distribute_parallel_do_simd, Directive::OMPD_target_teams_distribute_simd}; static OmpDirectiveSet simdSet{Directive::OMPD_distribute_parallel_do_simd, - Directive::OMPD_distribute_simd, Directive::OMPD_parallel_do_simd, - Directive::OMPD_do_simd, Directive::OMPD_simd, - Directive::OMPD_target_parallel_do_simd, + Directive::OMPD_distribute_simd, Directive::OMPD_do_simd, + Directive::OMPD_parallel_do_simd, Directive::OMPD_simd, + Directive::OMPD_target_parallel_do_simd, Directive::OMPD_target_simd, Directive::OMPD_target_teams_distribute_parallel_do_simd, - Directive::OMPD_target_teams_distribute_simd, Directive::OMPD_target_simd, - Directive::OMPD_taskloop_simd, + Directive::OMPD_target_teams_distribute_simd, Directive::OMPD_taskloop_simd, Directive::OMPD_teams_distribute_parallel_do_simd, Directive::OMPD_teams_distribute_simd}; static OmpDirectiveSet teamSet{Directive::OMPD_teams, Directive::OMPD_teams_distribute, Directive::OMPD_teams_distribute_parallel_do, Directive::OMPD_teams_distribute_parallel_do_simd, - Directive::OMPD_teams_distribute_parallel_for, - Directive::OMPD_teams_distribute_parallel_for_simd, Directive::OMPD_teams_distribute_simd}; static OmpDirectiveSet taskGeneratingSet{ OmpDirectiveSet{Directive::OMPD_task} | taskloopSet}; diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -2331,19 +2331,35 @@ void OmpStructureChecker::Enter(const parser::OmpClause::If &x) { CheckAllowed(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. + // Need to define set here because llvm::omp::teamSet does not include target + // teams combined constructs. + OmpDirectiveSet teamSet{llvm::omp::Directive::OMPD_target_teams, + llvm::omp::Directive::OMPD_target_teams_distribute, + llvm::omp::Directive::OMPD_target_teams_distribute_parallel_do, + llvm::omp::Directive::OMPD_target_teams_distribute_parallel_do_simd, + llvm::omp::Directive::OMPD_target_teams_distribute_simd, + llvm::omp::Directive::OMPD_teams, + llvm::omp::Directive::OMPD_teams_distribute, + llvm::omp::Directive::OMPD_teams_distribute_parallel_do, + llvm::omp::Directive::OMPD_teams_distribute_parallel_do_simd, + llvm::omp::Directive::OMPD_teams_distribute_simd}; static std::unordered_map dirNameModifierMap{{dirNameModifier::Parallel, llvm::omp::parallelSet}, + {dirNameModifier::Simd, llvm::omp::simdSet}, {dirNameModifier::Target, llvm::omp::targetSet}, + {dirNameModifier::TargetData, + {llvm::omp::Directive::OMPD_target_data}}, {dirNameModifier::TargetEnterData, {llvm::omp::Directive::OMPD_target_enter_data}}, {dirNameModifier::TargetExitData, {llvm::omp::Directive::OMPD_target_exit_data}}, - {dirNameModifier::TargetData, - {llvm::omp::Directive::OMPD_target_data}}, {dirNameModifier::TargetUpdate, {llvm::omp::Directive::OMPD_target_update}}, {dirNameModifier::Task, {llvm::omp::Directive::OMPD_task}}, - {dirNameModifier::Taskloop, llvm::omp::taskloopSet}}; + {dirNameModifier::Taskloop, llvm::omp::taskloopSet}, + {dirNameModifier::Teams, teamSet}}; if (const auto &directiveName{ std::get>(x.v.t)}) { auto search{dirNameModifierMap.find(*directiveName)}; diff --git a/flang/test/Semantics/OpenMP/if-clause.f90 b/flang/test/Semantics/OpenMP/if-clause.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Semantics/OpenMP/if-clause.f90 @@ -0,0 +1,625 @@ + +! RUN: %python %S/../test_errors.py %s %flang -fopenmp +! Check OpenMP 'if' clause validity for all directives that can have it + +program main + integer :: i + + ! ---------------------------------------------------------------------------- + ! DISTRIBUTE PARALLEL DO + ! ---------------------------------------------------------------------------- + !$omp teams + !$omp distribute parallel do if(.true.) + do i = 1, 10 + end do + !$omp end distribute parallel do + + !$omp distribute parallel do if(parallel: .true.) + do i = 1, 10 + end do + !$omp end distribute parallel do + + !ERROR: Unmatched directive name modifier TARGET on the IF clause + !$omp distribute parallel do if(target: .true.) + do i = 1, 10 + end do + !$omp end distribute parallel do + + !ERROR: At most one IF clause can appear on the DISTRIBUTE PARALLEL DO directive + !$omp distribute parallel do if(.true.) if(parallel: .false.) + do i = 1, 10 + end do + !$omp end distribute parallel do + !$omp end teams + + ! ---------------------------------------------------------------------------- + ! DISTRIBUTE PARALLEL DO SIMD + ! ---------------------------------------------------------------------------- + !$omp teams + !$omp distribute parallel do simd if(.true.) + do i = 1, 10 + end do + !$omp end distribute parallel do simd + + !$omp distribute parallel do simd if(parallel: .true.) if(simd: .false.) + do i = 1, 10 + end do + !$omp end distribute parallel do simd + + !ERROR: Unmatched directive name modifier TARGET on the IF clause + !$omp distribute parallel do simd if(target: .true.) + do i = 1, 10 + end do + !$omp end distribute parallel do simd + !$omp end teams + + ! ---------------------------------------------------------------------------- + ! DISTRIBUTE SIMD + ! ---------------------------------------------------------------------------- + !$omp teams + !$omp distribute simd if(.true.) + do i = 1, 10 + end do + !$omp end distribute simd + + !$omp distribute simd if(simd: .true.) + do i = 1, 10 + end do + !$omp end distribute simd + + !ERROR: Unmatched directive name modifier TARGET on the IF clause + !$omp distribute simd if(target: .true.) + do i = 1, 10 + end do + !$omp end distribute simd + + !ERROR: At most one IF clause can appear on the DISTRIBUTE SIMD directive + !$omp distribute simd if(.true.) if(simd: .false.) + do i = 1, 10 + end do + !$omp end distribute simd + !$omp end teams + + ! ---------------------------------------------------------------------------- + ! DO SIMD + ! ---------------------------------------------------------------------------- + !$omp do simd if(.true.) + do i = 1, 10 + end do + !$omp end do simd + + !$omp do simd if(simd: .true.) + do i = 1, 10 + end do + !$omp end do simd + + !ERROR: Unmatched directive name modifier TARGET on the IF clause + !$omp do simd if(target: .true.) + do i = 1, 10 + end do + !$omp end do simd + + !ERROR: At most one IF clause can appear on the DO SIMD directive + !$omp do simd if(.true.) if(simd: .false.) + do i = 1, 10 + end do + !$omp end do simd + + ! ---------------------------------------------------------------------------- + ! PARALLEL + ! ---------------------------------------------------------------------------- + !$omp parallel if(.true.) + !$omp end parallel + + !$omp parallel if(parallel: .true.) + !$omp end parallel + + !ERROR: Unmatched directive name modifier TARGET on the IF clause + !$omp parallel if(target: .true.) + !$omp end parallel + + !ERROR: At most one IF clause can appear on the PARALLEL directive + !$omp parallel if(.true.) if(parallel: .false.) + !$omp end parallel + + ! ---------------------------------------------------------------------------- + ! PARALLEL DO + ! ---------------------------------------------------------------------------- + !$omp parallel do if(.true.) + do i = 1, 10 + end do + !$omp end parallel do + + !$omp parallel do if(parallel: .true.) + do i = 1, 10 + end do + !$omp end parallel do + + !ERROR: Unmatched directive name modifier TARGET on the IF clause + !$omp parallel do if(target: .true.) + do i = 1, 10 + end do + !$omp end parallel do + + !ERROR: At most one IF clause can appear on the PARALLEL DO directive + !$omp parallel do if(.true.) if(parallel: .false.) + do i = 1, 10 + end do + !$omp end parallel do + + ! ---------------------------------------------------------------------------- + ! PARALLEL DO SIMD + ! ---------------------------------------------------------------------------- + !$omp parallel do simd if(.true.) + do i = 1, 10 + end do + !$omp end parallel do simd + + !$omp parallel do simd if(parallel: .true.) if(simd: .false.) + do i = 1, 10 + end do + !$omp end parallel do simd + + !ERROR: Unmatched directive name modifier TARGET on the IF clause + !$omp parallel do simd if(target: .true.) + do i = 1, 10 + end do + !$omp end parallel do simd + + ! ---------------------------------------------------------------------------- + ! PARALLEL SECTIONS + ! ---------------------------------------------------------------------------- + !$omp parallel sections if(.true.) + !$omp end parallel sections + + !$omp parallel sections if(parallel: .true.) + !$omp end parallel sections + + !ERROR: Unmatched directive name modifier TARGET on the IF clause + !$omp parallel sections if(target: .true.) + !$omp end parallel sections + + !ERROR: At most one IF clause can appear on the PARALLEL SECTIONS directive + !$omp parallel sections if(.true.) if(parallel: .false.) + !$omp end parallel sections + + ! ---------------------------------------------------------------------------- + ! PARALLEL WORKSHARE + ! ---------------------------------------------------------------------------- + !$omp parallel workshare if(.true.) + !$omp end parallel workshare + + !$omp parallel workshare if(parallel: .true.) + !$omp end parallel workshare + + !ERROR: Unmatched directive name modifier TARGET on the IF clause + !$omp parallel workshare if(target: .true.) + !$omp end parallel workshare + + !ERROR: At most one IF clause can appear on the PARALLEL WORKSHARE directive + !$omp parallel workshare if(.true.) if(parallel: .false.) + !$omp end parallel workshare + + ! ---------------------------------------------------------------------------- + ! SIMD + ! ---------------------------------------------------------------------------- + !$omp simd if(.true.) + do i = 1, 10 + end do + !$omp end simd + + !$omp simd if(simd: .true.) + do i = 1, 10 + end do + !$omp end simd + + !ERROR: Unmatched directive name modifier TARGET on the IF clause + !$omp simd if(target: .true.) + do i = 1, 10 + end do + !$omp end simd + + !ERROR: At most one IF clause can appear on the SIMD directive + !$omp simd if(.true.) if(simd: .false.) + do i = 1, 10 + end do + !$omp end simd + + ! ---------------------------------------------------------------------------- + ! TARGET + ! ---------------------------------------------------------------------------- + !$omp target if(.true.) + !$omp end target + + !$omp target if(target: .true.) + !$omp end target + + !ERROR: Unmatched directive name modifier PARALLEL on the IF clause + !$omp target if(parallel: .true.) + !$omp end target + + !ERROR: At most one IF clause can appear on the TARGET directive + !$omp target if(.true.) if(target: .false.) + !$omp end target + + ! ---------------------------------------------------------------------------- + ! TARGET DATA + ! ---------------------------------------------------------------------------- + !$omp target data map(tofrom: i) if(.true.) + !$omp end target data + + !$omp target data map(tofrom: i) if(target data: .true.) + !$omp end target data + + !ERROR: Unmatched directive name modifier TARGET on the IF clause + !$omp target data map(tofrom: i) if(target: .true.) + !$omp end target data + + !ERROR: At most one IF clause can appear on the TARGET DATA directive + !$omp target data map(tofrom: i) if(.true.) if(target data: .false.) + !$omp end target data + + ! ---------------------------------------------------------------------------- + ! TARGET ENTER DATA + ! ---------------------------------------------------------------------------- + !$omp target enter data map(to: i) if(.true.) + + !$omp target enter data map(to: i) if(target enter data: .true.) + + !ERROR: Unmatched directive name modifier TARGET on the IF clause + !$omp target enter data map(to: i) if(target: .true.) + + !ERROR: At most one IF clause can appear on the TARGET ENTER DATA directive + !$omp target enter data map(to: i) if(.true.) if(target enter data: .false.) + + ! ---------------------------------------------------------------------------- + ! TARGET EXIT DATA + ! ---------------------------------------------------------------------------- + !$omp target exit data map(from: i) if(.true.) + + !$omp target exit data map(from: i) if(target exit data: .true.) + + !ERROR: Unmatched directive name modifier TARGET on the IF clause + !$omp target exit data map(from: i) if(target: .true.) + + !ERROR: At most one IF clause can appear on the TARGET EXIT DATA directive + !$omp target exit data map(from: i) if(.true.) if(target exit data: .false.) + + ! ---------------------------------------------------------------------------- + ! TARGET PARALLEL + ! ---------------------------------------------------------------------------- + !$omp target parallel if(.true.) + !$omp end target parallel + + !$omp target parallel if(target: .true.) if(parallel: .false.) + !$omp end target parallel + + !ERROR: Unmatched directive name modifier SIMD on the IF clause + !$omp target parallel if(simd: .true.) + !$omp end target parallel + + ! ---------------------------------------------------------------------------- + ! TARGET PARALLEL DO + ! ---------------------------------------------------------------------------- + !$omp target parallel do if(.true.) + do i = 1, 10 + end do + !$omp end target parallel do + + !$omp target parallel do if(target: .true.) if(parallel: .false.) + do i = 1, 10 + end do + !$omp end target parallel do + + !ERROR: Unmatched directive name modifier SIMD on the IF clause + !$omp target parallel do if(simd: .true.) + do i = 1, 10 + end do + !$omp end target parallel do + + ! ---------------------------------------------------------------------------- + ! TARGET PARALLEL DO SIMD + ! ---------------------------------------------------------------------------- + !$omp target parallel do simd if(.true.) + do i = 1, 10 + end do + !$omp end target parallel do simd + + !$omp target parallel do simd if(target: .true.) if(parallel: .false.) & + !$omp& if(simd: .true.) + do i = 1, 10 + end do + !$omp end target parallel do simd + + !ERROR: Unmatched directive name modifier TEAMS on the IF clause + !$omp target parallel do simd if(teams: .true.) + do i = 1, 10 + end do + !$omp end target parallel do simd + + ! ---------------------------------------------------------------------------- + ! TARGET SIMD + ! ---------------------------------------------------------------------------- + !$omp target simd if(.true.) + do i = 1, 10 + end do + !$omp end target simd + + !$omp target simd if(target: .true.) if(simd: .false.) + do i = 1, 10 + end do + !$omp end target simd + + !ERROR: Unmatched directive name modifier PARALLEL on the IF clause + !$omp target simd if(parallel: .true.) + do i = 1, 10 + end do + !$omp end target simd + + ! ---------------------------------------------------------------------------- + ! TARGET TEAMS + ! ---------------------------------------------------------------------------- + !$omp target teams if(.true.) + !$omp end target teams + + !$omp target teams if(target: .true.) if(teams: .false.) + !$omp end target teams + + !ERROR: Unmatched directive name modifier PARALLEL on the IF clause + !$omp target teams if(parallel: .true.) + !$omp end target teams + + ! ---------------------------------------------------------------------------- + ! TARGET TEAMS DISTRIBUTE + ! ---------------------------------------------------------------------------- + !$omp target teams distribute if(.true.) + do i = 1, 10 + end do + !$omp end target teams distribute + + !$omp target teams distribute if(target: .true.) if(teams: .false.) + do i = 1, 10 + end do + !$omp end target teams distribute + + !ERROR: Unmatched directive name modifier PARALLEL on the IF clause + !$omp target teams distribute if(parallel: .true.) + do i = 1, 10 + end do + !$omp end target teams distribute + + ! ---------------------------------------------------------------------------- + ! TARGET TEAMS DISTRIBUTE PARALLEL DO + ! ---------------------------------------------------------------------------- + !$omp target teams distribute parallel do if(.true.) + do i = 1, 10 + end do + !$omp end target teams distribute parallel do + + !$omp target teams distribute parallel do & + !$omp& if(target: .true.) if(teams: .false.) if(parallel: .true.) + do i = 1, 10 + end do + !$omp end target teams distribute parallel do + + !ERROR: Unmatched directive name modifier SIMD on the IF clause + !$omp target teams distribute parallel do if(simd: .true.) + do i = 1, 10 + end do + !$omp end target teams distribute parallel do + + ! ---------------------------------------------------------------------------- + ! TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD + ! ---------------------------------------------------------------------------- + !$omp target teams distribute parallel do simd if(.true.) + do i = 1, 10 + end do + !$omp end target teams distribute parallel do simd + + !$omp target teams distribute parallel do simd & + !$omp& if(target: .true.) if(teams: .false.) if(parallel: .true.) & + !$omp& if(simd: .false.) + do i = 1, 10 + end do + !$omp end target teams distribute parallel do simd + + !ERROR: Unmatched directive name modifier TASK on the IF clause + !$omp target teams distribute parallel do simd if(task: .true.) + do i = 1, 10 + end do + !$omp end target teams distribute parallel do simd + + ! ---------------------------------------------------------------------------- + ! TARGET TEAMS DISTRIBUTE SIMD + ! ---------------------------------------------------------------------------- + !$omp target teams distribute simd if(.true.) + do i = 1, 10 + end do + !$omp end target teams distribute simd + + !$omp target teams distribute simd & + !$omp& if(target: .true.) if(teams: .false.) if(simd: .true.) + do i = 1, 10 + end do + !$omp end target teams distribute simd + + !ERROR: Unmatched directive name modifier PARALLEL on the IF clause + !$omp target teams distribute simd if(parallel: .true.) + do i = 1, 10 + end do + !$omp end target teams distribute simd + + ! ---------------------------------------------------------------------------- + ! TARGET UPDATE + ! ---------------------------------------------------------------------------- + !$omp target update if(.true.) + + !$omp target update if(target update: .true.) + + !ERROR: Unmatched directive name modifier TARGET on the IF clause + !$omp target update if(target: .true.) + + !ERROR: At most one IF clause can appear on the TARGET UPDATE directive + !$omp target update if(.true.) if(target update: .false.) + + ! ---------------------------------------------------------------------------- + ! TASK + ! ---------------------------------------------------------------------------- + !$omp task if(.true.) + !$omp end task + + !$omp task if(task: .true.) + !$omp end task + + !ERROR: Unmatched directive name modifier TARGET on the IF clause + !$omp task if(target: .true.) + !$omp end task + + !ERROR: At most one IF clause can appear on the TASK directive + !$omp task if(.true.) if(task: .false.) + !$omp end task + + ! ---------------------------------------------------------------------------- + ! TASKLOOP + ! ---------------------------------------------------------------------------- + !$omp taskloop if(.true.) + do i = 1, 10 + end do + !$omp end taskloop + + !$omp taskloop if(taskloop: .true.) + do i = 1, 10 + end do + !$omp end taskloop + + !ERROR: Unmatched directive name modifier TARGET on the IF clause + !$omp taskloop if(target: .true.) + do i = 1, 10 + end do + !$omp end taskloop + + !ERROR: At most one IF clause can appear on the TASKLOOP directive + !$omp taskloop if(.true.) if(taskloop: .false.) + do i = 1, 10 + end do + !$omp end taskloop + + ! ---------------------------------------------------------------------------- + ! TASKLOOP SIMD + ! ---------------------------------------------------------------------------- + !$omp taskloop simd if(.true.) + do i = 1, 10 + end do + !$omp end taskloop simd + + !$omp taskloop simd if(taskloop: .true.) if(simd: .false.) + do i = 1, 10 + end do + !$omp end taskloop simd + + !ERROR: Unmatched directive name modifier TARGET on the IF clause + !$omp taskloop simd if(target: .true.) + do i = 1, 10 + end do + !$omp end taskloop simd + + ! ---------------------------------------------------------------------------- + ! TEAMS + ! ---------------------------------------------------------------------------- + !$omp teams if(.true.) + !$omp end teams + + !$omp teams if(teams: .true.) + !$omp end teams + + !ERROR: Unmatched directive name modifier TARGET on the IF clause + !$omp teams if(target: .true.) + !$omp end teams + + !ERROR: At most one IF clause can appear on the TEAMS directive + !$omp teams if(.true.) if(teams: .false.) + !$omp end teams + + ! ---------------------------------------------------------------------------- + ! TEAMS DISTRIBUTE + ! ---------------------------------------------------------------------------- + !$omp teams distribute if(.true.) + do i = 1, 10 + end do + !$omp end teams distribute + + !$omp teams distribute if(teams: .true.) + do i = 1, 10 + end do + !$omp end teams distribute + + !ERROR: Unmatched directive name modifier TARGET on the IF clause + !$omp teams distribute if(target: .true.) + do i = 1, 10 + end do + !$omp end teams distribute + + !ERROR: At most one IF clause can appear on the TEAMS DISTRIBUTE directive + !$omp teams distribute if(.true.) if(teams: .true.) + do i = 1, 10 + end do + !$omp end teams distribute + + ! ---------------------------------------------------------------------------- + ! TEAMS DISTRIBUTE PARALLEL DO + ! ---------------------------------------------------------------------------- + !$omp teams distribute parallel do if(.true.) + do i = 1, 10 + end do + !$omp end teams distribute parallel do + + !$omp teams distribute parallel do if(teams: .true.) if(parallel: .false.) + do i = 1, 10 + end do + !$omp end teams distribute parallel do + + !ERROR: Unmatched directive name modifier TARGET on the IF clause + !$omp teams distribute parallel do if(target: .true.) + do i = 1, 10 + end do + !$omp end teams distribute parallel do + + ! ---------------------------------------------------------------------------- + ! TEAMS DISTRIBUTE PARALLEL DO SIMD + ! ---------------------------------------------------------------------------- + !$omp teams distribute parallel do simd if(.true.) + do i = 1, 10 + end do + !$omp end teams distribute parallel do simd + + !$omp teams distribute parallel do simd & + !$omp& if(teams: .true.) if(parallel: .true.) if(simd: .true.) + do i = 1, 10 + end do + !$omp end teams distribute parallel do simd + + !ERROR: Unmatched directive name modifier TARGET on the IF clause + !$omp teams distribute parallel do simd if(target: .true.) + do i = 1, 10 + end do + !$omp end teams distribute parallel do simd + + ! ---------------------------------------------------------------------------- + ! TEAMS DISTRIBUTE SIMD + ! ---------------------------------------------------------------------------- + !$omp teams distribute simd if(.true.) + do i = 1, 10 + end do + !$omp end teams distribute simd + + !$omp teams distribute simd if(teams: .true.) if(simd: .true.) + do i = 1, 10 + end do + !$omp end teams distribute simd + + !ERROR: Unmatched directive name modifier TARGET on the IF clause + !$omp teams distribute simd if(target: .true.) + do i = 1, 10 + end do + !$omp end teams distribute simd +end program main diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td --- a/llvm/include/llvm/Frontend/OpenMP/OMP.td +++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td @@ -635,7 +635,6 @@ } def OMP_Target : Directive<"target"> { let allowedClauses = [ - VersionedClause, VersionedClause, VersionedClause, VersionedClause, @@ -648,6 +647,7 @@ VersionedClause ]; let allowedOnceClauses = [ + VersionedClause, VersionedClause, VersionedClause, VersionedClause, @@ -665,12 +665,13 @@ ]; let allowedOnceClauses = [ VersionedClause, + VersionedClause, VersionedClause, VersionedClause ]; } def OMP_Cancel : Directive<"cancel"> { - let allowedClauses = [ + let allowedOnceClauses = [ VersionedClause ]; } @@ -733,6 +734,7 @@ } def OMP_TargetParallel : Directive<"target parallel"> { let allowedClauses = [ + VersionedClause, VersionedClause, VersionedClause, VersionedClause, @@ -749,7 +751,6 @@ let allowedOnceClauses = [ VersionedClause, VersionedClause, - VersionedClause, VersionedClause, VersionedClause, VersionedClause, @@ -787,6 +788,7 @@ } def OMP_TargetParallelDo : Directive<"target parallel do"> { let allowedClauses = [ + VersionedClause, VersionedClause, VersionedClause, VersionedClause, @@ -803,7 +805,6 @@ VersionedClause ]; let allowedOnceClauses = [ - VersionedClause, VersionedClause, VersionedClause, VersionedClause, @@ -894,6 +895,7 @@ } def OMP_ParallelDoSimd : Directive<"parallel do simd"> { let allowedClauses = [ + VersionedClause, VersionedClause, VersionedClause, VersionedClause, @@ -907,7 +909,6 @@ VersionedClause, ]; let allowedOnceClauses = [ - VersionedClause, VersionedClause, VersionedClause, VersionedClause, @@ -949,7 +950,6 @@ } def OMP_ParallelSections : Directive<"parallel sections"> { let allowedClauses = [ - VersionedClause, VersionedClause, VersionedClause, VersionedClause, @@ -961,6 +961,7 @@ VersionedClause ]; let allowedOnceClauses = [ + VersionedClause, VersionedClause ]; } @@ -994,6 +995,7 @@ VersionedClause ]; let allowedOnceClauses = [ + VersionedClause, VersionedClause, VersionedClause, VersionedClause, @@ -1051,6 +1053,7 @@ } def OMP_TaskLoopSimd : Directive<"taskloop simd"> { let allowedClauses = [ + VersionedClause, VersionedClause, VersionedClause, VersionedClause, @@ -1067,7 +1070,6 @@ VersionedClause ]; let allowedOnceClauses = [ - VersionedClause, VersionedClause, VersionedClause, VersionedClause, @@ -1295,6 +1297,7 @@ } def OMP_TargetSimd : Directive<"target simd"> { let allowedClauses = [ + VersionedClause, VersionedClause, VersionedClause, VersionedClause, @@ -1315,7 +1318,6 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, VersionedClause, VersionedClause, VersionedClause, @@ -1339,9 +1341,13 @@ VersionedClause, VersionedClause ]; + let allowedOnceClauses = [ + VersionedClause + ]; } def OMP_TeamsDistributeSimd : Directive<"teams distribute simd"> { let allowedClauses = [ + VersionedClause, VersionedClause, VersionedClause, VersionedClause, @@ -1356,7 +1362,6 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, VersionedClause, VersionedClause, VersionedClause, @@ -1394,6 +1399,7 @@ def OMP_TeamsDistributeParallelDoSimd : Directive<"teams distribute parallel do simd"> { let allowedClauses = [ + VersionedClause, VersionedClause, VersionedClause, VersionedClause, @@ -1415,7 +1421,6 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, VersionedClause ]; } @@ -1444,6 +1449,7 @@ def OMP_TeamsDistributeParallelDo : Directive<"teams distribute parallel do"> { let allowedClauses = [ + VersionedClause, VersionedClause, VersionedClause, VersionedClause, @@ -1460,7 +1466,6 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, VersionedClause, VersionedClause, VersionedClause, @@ -1626,6 +1631,7 @@ def OMP_TargetTeamsDistributeParallelDoSimd : Directive<"target teams distribute parallel do simd"> { let allowedClauses = [ + VersionedClause, VersionedClause, VersionedClause, VersionedClause, @@ -1644,7 +1650,6 @@ VersionedClause ]; let allowedOnceClauses = [ - VersionedClause, VersionedClause, VersionedClause, VersionedClause, @@ -2033,6 +2038,7 @@ } def OMP_target_teams_loop : Directive<"target teams loop"> { let allowedClauses = [ + VersionedClause, VersionedClause, VersionedClause, VersionedClause, @@ -2051,7 +2057,6 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, VersionedClause, VersionedClause, VersionedClause, @@ -2081,6 +2086,7 @@ } def OMP_target_parallel_loop : Directive<"target parallel loop"> { let allowedClauses = [ + VersionedClause, VersionedClause, VersionedClause, VersionedClause, @@ -2100,7 +2106,6 @@ VersionedClause, VersionedClause, VersionedClause, - VersionedClause, VersionedClause, VersionedClause, VersionedClause,