diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index 8d2d085a749f5..39dbeb5e7cfbe 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -4962,11 +4962,9 @@ struct OpenMPDeclareMapperConstruct { // 2.16 declare-reduction -> DECLARE REDUCTION (reduction-identifier : type-list // : combiner) [initializer-clause] struct OpenMPDeclareReductionConstruct { - TUPLE_CLASS_BOILERPLATE(OpenMPDeclareReductionConstruct); + WRAPPER_CLASS_BOILERPLATE( + OpenMPDeclareReductionConstruct, OmpDirectiveSpecification); CharBlock source; - std::tuple, - std::optional> - t; }; // 2.8.2 declare-simd -> DECLARE SIMD [(proc-name)] [declare-simd-clause[ [,] diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index e12ed06520bf1..30bc02ce851db 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -1716,9 +1716,9 @@ TYPE_PARSER(sourced(construct( // 2.16 Declare Reduction Construct TYPE_PARSER(sourced(construct( - verbatim("DECLARE REDUCTION"_tok) || verbatim("DECLARE_REDUCTION"_tok), - "(" >> indirect(Parser{}) / ")", - maybe(Parser{})))) + predicated(Parser{}, + IsDirective(llvm::omp::Directive::OMPD_declare_reduction)) >= + Parser{}))) // declare-target with list TYPE_PARSER(sourced(construct( diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index 77ed7951496c1..853d228fa7702 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -2507,11 +2507,8 @@ class UnparseVisitor { } void Unparse(const OpenMPDeclareReductionConstruct &x) { BeginOpenMP(); - Word("!$OMP DECLARE REDUCTION "); - Put("("); - Walk(std::get>(x.t)); - Put(")"); - Walk(std::get>(x.t)); + Word("!$OMP "); + Walk(x.v); Put("\n"); EndOpenMP(); } diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index 0cbcbc3a8f50e..e9bd34d449461 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -624,11 +624,6 @@ template struct DirectiveSpellingVisitor { checker_(std::get(x.t).source, Directive::OMPD_assumes); return false; } - bool Pre(const parser::OpenMPDeclareReductionConstruct &x) { - checker_(std::get(x.t).source, - Directive::OMPD_declare_reduction); - return false; - } bool Pre(const parser::OpenMPDeclareSimdConstruct &x) { checker_( std::get(x.t).source, Directive::OMPD_declare_simd); @@ -1626,9 +1621,21 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclareMapperConstruct &) { void OmpStructureChecker::Enter( const parser::OpenMPDeclareReductionConstruct &x) { - const auto &dir{std::get(x.t)}; - PushContextAndClauseSets( - dir.source, llvm::omp::Directive::OMPD_declare_reduction); + const parser::OmpDirectiveName &dirName{x.v.DirName()}; + PushContextAndClauseSets(dirName.source, dirName.v); + + const parser::OmpArgumentList &args{x.v.Arguments()}; + if (args.v.size() != 1) { + context_.Say(args.source, + "DECLARE_REDUCTION directive should have a single argument"_err_en_US); + return; + } + + const parser::OmpArgument &arg{args.v.front()}; + if (!std::holds_alternative(arg.u)) { + context_.Say(arg.source, + "The argument to the DECLARE_REDUCTION directive should be a reduction-specifier"_err_en_US); + } } void OmpStructureChecker::Leave( diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp index f665f9c8bf5c0..699cb562da8cc 100644 --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -1559,12 +1559,7 @@ class OmpVisitor : public virtual DeclarationVisitor { bool Pre(const parser::OpenMPDeclareReductionConstruct &x) { AddOmpSourceRange(x.source); - parser::OmpClauseList empty(std::list{}); - auto &maybeClauses{std::get>(x.t)}; - ProcessReductionSpecifier( - std::get>(x.t).value(), - maybeClauses ? *maybeClauses : empty, declaratives_.back()); - return false; + return true; } bool Pre(const parser::OmpMapClause &); @@ -1697,6 +1692,11 @@ class OmpVisitor : public virtual DeclarationVisitor { // should not reach a point where it calls this function. llvm_unreachable("This function should not be reached by AST traversal"); } + bool Pre(const parser::OmpReductionSpecifier &x) { + // OmpReductionSpecifier is handled explicitly, and the AST traversal + // should not reach a point where it calls this function. + llvm_unreachable("This function should not be reached by AST traversal"); + } bool Pre(const parser::OmpDirectiveSpecification &x); void Post(const parser::OmpDirectiveSpecification &) { messageHandler().set_currStmtSource(std::nullopt); @@ -1724,8 +1724,7 @@ class OmpVisitor : public virtual DeclarationVisitor { void ProcessMapperSpecifier(const parser::OmpMapperSpecifier &spec, const parser::OmpClauseList &clauses); void ProcessReductionSpecifier(const parser::OmpReductionSpecifier &spec, - const parser::OmpClauseList &clauses, - const parser::OpenMPDeclarativeConstruct *wholeConstruct); + const parser::OmpClauseList &clauses); void ResolveCriticalName(const parser::OmpArgument &arg); @@ -1856,8 +1855,7 @@ std::string MangleDefinedOperator(const parser::CharBlock &name) { void OmpVisitor::ProcessReductionSpecifier( const parser::OmpReductionSpecifier &spec, - const parser::OmpClauseList &clauses, - const parser::OpenMPDeclarativeConstruct *construct) { + const parser::OmpClauseList &clauses) { const parser::Name *name{nullptr}; parser::CharBlock mangledName; UserReductionDetails reductionDetailsTemp; @@ -1944,7 +1942,7 @@ void OmpVisitor::ProcessReductionSpecifier( PopScope(); } - reductionDetails->AddDecl(construct); + reductionDetails->AddDecl(declaratives_.back()); if (!symbol) { symbol = &MakeSymbol(mangledName, Attrs{}, std::move(*reductionDetails)); @@ -1997,7 +1995,7 @@ bool OmpVisitor::Pre(const parser::OmpDirectiveSpecification &x) { visitClauses = false; }, [&](const parser::OmpReductionSpecifier &spec) { - ProcessReductionSpecifier(spec, clauses, declaratives_.back()); + ProcessReductionSpecifier(spec, clauses); visitClauses = false; }, [&](const parser::OmpLocator &locator) { diff --git a/flang/test/Parser/OpenMP/declare-reduction-multi.f90 b/flang/test/Parser/OpenMP/declare-reduction-multi.f90 index 693e69d8896be..19266aca9db03 100644 --- a/flang/test/Parser/OpenMP/declare-reduction-multi.f90 +++ b/flang/test/Parser/OpenMP/declare-reduction-multi.f90 @@ -26,111 +26,127 @@ program omp_examples type(tt) :: values(n), sum, prod, big, small !$omp declare reduction(+:tt:omp_out%r = omp_out%r + omp_in%r) initializer(omp_priv%r = 0) -!CHECK: !$OMP DECLARE REDUCTION (+:tt: omp_out%r=omp_out%r+omp_in%r +!CHECK: !$OMP DECLARE REDUCTION(+:tt: omp_out%r=omp_out%r+omp_in%r !CHECK-NEXT: ) INITIALIZER(omp_priv%r=0_4) -!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -!PARSE-TREE: Verbatim -!PARSE-TREE: OmpReductionSpecifier -!PARSE-TREE-NEXT: OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Add -!PARSE-TREE: OmpTypeNameList -> OmpTypeSpecifier -> TypeSpec -> DerivedTypeSpec -!PARSE-TREE-NEXT: Name = 'tt' -!PARSE-TREE: OmpReductionCombiner -> AssignmentStmt = 'omp_out%r=omp_out%r+omp_in%r' -!PARSE-TREE: OmpClauseList -> OmpClause -> Initializer -> OmpInitializerClause -> AssignmentStmt = 'omp_priv%r=0._4 + +!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -> OmpDirectiveSpecification +!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare reduction +!PARSE-TREE: | OmpArgumentList -> OmpArgument -> OmpReductionSpecifier +!PARSE-TREE: | | OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Add +!PARSE-TREE: | | OmpTypeNameList -> OmpTypeSpecifier -> TypeSpec -> DerivedTypeSpec +!PARSE-TREE: | | | Name = 'tt' +!PARSE-TREE: | | OmpReductionCombiner -> AssignmentStmt = 'omp_out%r=omp_out%r+omp_in%r' +!PARSE-TREE: | OmpClauseList -> OmpClause -> Initializer -> OmpInitializerClause -> AssignmentStmt = 'omp_priv%r=0._4' + !$omp declare reduction(*:tt:omp_out%r = omp_out%r * omp_in%r) initializer(omp_priv%r = 1) -!CHECK-NEXT: !$OMP DECLARE REDUCTION (*:tt: omp_out%r=omp_out%r*omp_in%r +!CHECK-NEXT: !$OMP DECLARE REDUCTION(*:tt: omp_out%r=omp_out%r*omp_in%r !CHECK-NEXT: ) INITIALIZER(omp_priv%r=1_4) -!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -!PARSE-TREE: Verbatim -!PARSE-TREE: OmpReductionSpecifier -!PARSE-TREE: OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Multiply -!PARSE-TREE: OmpTypeNameList -> OmpTypeSpecifier -> TypeSpec -> DerivedTypeSpec -!PARSE-TREE-NEXT: Name = 'tt' -!PARSE-TREE: OmpReductionCombiner -> AssignmentStmt = 'omp_out%r=omp_out%r*omp_in%r' -!PARSE-TREE: OmpClauseList -> OmpClause -> Initializer -> OmpInitializerClause -> AssignmentStmt = 'omp_priv%r=1._4' + +!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -> OmpDirectiveSpecification +!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare reduction +!PARSE-TREE: | OmpArgumentList -> OmpArgument -> OmpReductionSpecifier +!PARSE-TREE: | | OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Multiply +!PARSE-TREE: | | OmpTypeNameList -> OmpTypeSpecifier -> TypeSpec -> DerivedTypeSpec +!PARSE-TREE: | | | Name = 'tt' +!PARSE-TREE: | | OmpReductionCombiner -> AssignmentStmt = 'omp_out%r=omp_out%r*omp_in%r' +!PARSE-TREE: | OmpClauseList -> OmpClause -> Initializer -> OmpInitializerClause -> AssignmentStmt = 'omp_priv%r=1._4' + !$omp declare reduction(max:tt:omp_out = mymax(omp_out, omp_in)) initializer(omp_priv%r = 0) -!CHECK-NEXT: !$OMP DECLARE REDUCTION (max:tt: omp_out=mymax(omp_out,omp_in) +!CHECK-NEXT: !$OMP DECLARE REDUCTION(max:tt: omp_out=mymax(omp_out,omp_in) !CHECK-NEXT: ) INITIALIZER(omp_priv%r=0_4) -!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -!PARSE-TREE: Verbatim -!PARSE-TREE: OmpReductionSpecifier -!PARSE-TREE: OmpReductionIdentifier -> ProcedureDesignator -> Name = 'max' -!PARSE-TREE: OmpTypeNameList -> OmpTypeSpecifier -> TypeSpec -> DerivedTypeSpec -!PARSE-TREE: Name = 'tt' -!PARSE-TREE: OmpReductionCombiner -> AssignmentStmt = 'omp_out=mymax(omp_out,omp_in)' -!PARSE-TREE: OmpClauseList -> OmpClause -> Initializer -> OmpInitializerClause -> AssignmentStmt = 'omp_priv%r=0._4' + +!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -> OmpDirectiveSpecification +!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare reduction +!PARSE-TREE: | OmpArgumentList -> OmpArgument -> OmpReductionSpecifier +!PARSE-TREE: | | OmpReductionIdentifier -> ProcedureDesignator -> Name = 'max' +!PARSE-TREE: | | OmpTypeNameList -> OmpTypeSpecifier -> TypeSpec -> DerivedTypeSpec +!PARSE-TREE: | | | Name = 'tt' +!PARSE-TREE: | | OmpReductionCombiner -> AssignmentStmt = 'omp_out=mymax(omp_out,omp_in)' +!PARSE-TREE: | OmpClauseList -> OmpClause -> Initializer -> OmpInitializerClause -> AssignmentStmt = 'omp_priv%r=0._4' + !$omp declare reduction(min:tt:omp_out%r = min(omp_out%r, omp_in%r)) initializer(omp_priv%r = 1) -!CHECK-NEXT: !$OMP DECLARE REDUCTION (min:tt: omp_out%r=min(omp_out%r,omp_in%r) +!CHECK-NEXT: !$OMP DECLARE REDUCTION(min:tt: omp_out%r=min(omp_out%r,omp_in%r) !CHECK-NEXT: ) INITIALIZER(omp_priv%r=1_4) -!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -!PARSE-TREE: Verbatim -!PARSE-TREE: OmpReductionSpecifier -!PARSE-TREE: OmpReductionIdentifier -> ProcedureDesignator -> Name = 'min' -!PARSE-TREE: OmpTypeNameList -> OmpTypeSpecifier -> TypeSpec -> DerivedTypeSpec -!PARSE-TREE: Name = 'tt' -!PARSE-TREE: OmpReductionCombiner -> AssignmentStmt = 'omp_out%r=min(omp_out%r,omp_in%r)' -!PARSE-TREE: OmpClauseList -> OmpClause -> Initializer -> OmpInitializerClause -> AssignmentStmt = 'omp_priv%r=1._4' + +!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -> OmpDirectiveSpecification +!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare reduction +!PARSE-TREE: | OmpArgumentList -> OmpArgument -> OmpReductionSpecifier +!PARSE-TREE: | | OmpReductionIdentifier -> ProcedureDesignator -> Name = 'min' +!PARSE-TREE: | | OmpTypeNameList -> OmpTypeSpecifier -> TypeSpec -> DerivedTypeSpec +!PARSE-TREE: | | | Name = 'tt' +!PARSE-TREE: | | OmpReductionCombiner -> AssignmentStmt = 'omp_out%r=min(omp_out%r,omp_in%r)' +!PARSE-TREE: | OmpClauseList -> OmpClause -> Initializer -> OmpInitializerClause -> AssignmentStmt = 'omp_priv%r=1._4' + call random_number(values%r) sum%r = 0 !$omp parallel do reduction(+:sum) -!CHECK: !$OMP PARALLEL DO REDUCTION(+: sum) +!CHECK: !$OMP PARALLEL DO REDUCTION(+: sum) + !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPLoopConstruct -!PARSE-TREE: OmpBeginLoopDirective -!PARSE-TREE: OmpDirectiveName -> llvm::omp::Directive = parallel do -!PARSE-TREE: OmpClauseList -> OmpClause -> Reduction -> OmpReductionClause -!PARSE-TREE: Modifier -> OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Add -!PARSE-TREE: OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'sum -!PARSE-TREE: Flags = None -!PARSE-TREE: DoConstruct +!PARSE-TREE: | OmpBeginLoopDirective +!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = parallel do +!PARSE-TREE: | | OmpClauseList -> OmpClause -> Reduction -> OmpReductionClause +!PARSE-TREE: | | | Modifier -> OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Add +!PARSE-TREE: | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'sum' +!PARSE-TREE: | | Flags = None +!PARSE-TREE: | DoConstruct + do i = 1, n sum%r = sum%r + values(i)%r end do prod%r = 1 !$omp parallel do reduction(*:prod) -!CHECK: !$OMP PARALLEL DO REDUCTION(*: prod) -!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPLoopConstruct -!PARSE-TREE: OmpBeginLoopDirective -!PARSE-TREE: OmpDirectiveName -> llvm::omp::Directive = parallel do -!PARSE-TREE: OmpClauseList -> OmpClause -> Reduction -> OmpReductionClause -!PARSE-TREE: Modifier -> OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Multiply -!PARSE-TREE: OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'prod' -!PARSE-TREE: Flags = None -!PARSE-TREE: DoConstruct +!CHECK: !$OMP PARALLEL DO REDUCTION(*: prod) + +!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPLoopConstruct +!PARSE-TREE: | OmpBeginLoopDirective +!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = parallel do +!PARSE-TREE: | | OmpClauseList -> OmpClause -> Reduction -> OmpReductionClause +!PARSE-TREE: | | | Modifier -> OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Multiply +!PARSE-TREE: | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'prod' +!PARSE-TREE: | | Flags = None +!PARSE-TREE: | DoConstruct + do i = 1, n prod%r = prod%r * (values(i)%r+0.6) end do big%r = 0 !$omp parallel do reduction(max:big) -!CHECK: $OMP PARALLEL DO REDUCTION(max: big) +!CHECK: $OMP PARALLEL DO REDUCTION(max: big) + !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPLoopConstruct -!PARSE-TREE: OmpBeginLoopDirective -!PARSE-TREE: OmpDirectiveName -> llvm::omp::Directive = parallel do -!PARSE-TREE: OmpClauseList -> OmpClause -> Reduction -> OmpReductionClause -!PARSE-TREE: Modifier -> OmpReductionIdentifier -> ProcedureDesignator -> Name = 'max' -!PARSE-TREE: OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'big' -!PARSE-TREE: Flags = None -!PARSE-TREE: DoConstruct +!PARSE-TREE: | OmpBeginLoopDirective +!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = parallel do +!PARSE-TREE: | | OmpClauseList -> OmpClause -> Reduction -> OmpReductionClause +!PARSE-TREE: | | | Modifier -> OmpReductionIdentifier -> ProcedureDesignator -> Name = 'max' +!PARSE-TREE: | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'big' +!PARSE-TREE: | | Flags = None +!PARSE-TREE: | DoConstruct + do i = 1, n big = mymax(values(i), big) end do small%r = 1 !$omp parallel do reduction(min:small) -!CHECK: !$OMP PARALLEL DO REDUCTION(min: small) -!CHECK-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPLoopConstruct -!CHECK-TREE: OmpBeginLoopDirective -!CHECK-TREE: OmpDirectiveName -> llvm::omp::Directive = parallel do -!CHECK-TREE: OmpClauseList -> OmpClause -> Reduction -> OmpReductionClause -!CHECK-TREE: Modifier -> OmpReductionIdentifier -> ProcedureDesignator -> Name = 'min' -!CHECK-TREE: OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'small' -!PARSE-TREE: Flags = None -!CHECK-TREE: DoConstruct +!CHECK: !$OMP PARALLEL DO REDUCTION(min: small) + +!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPLoopConstruct +!PARSE-TREE: | OmpBeginLoopDirective +!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = parallel do +!PARSE-TREE: | | OmpClauseList -> OmpClause -> Reduction -> OmpReductionClause +!PARSE-TREE: | | | Modifier -> OmpReductionIdentifier -> ProcedureDesignator -> Name = 'min' +!PARSE-TREE: | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'small' +!PARSE-TREE: | | Flags = None +!PARSE-TREE: | DoConstruct + do i = 1, n small%r = min(values(i)%r, small%r) end do - + print *, values%r print *, "sum=", sum%r print *, "prod=", prod%r diff --git a/flang/test/Parser/OpenMP/declare-reduction-operator.f90 b/flang/test/Parser/OpenMP/declare-reduction-operator.f90 index 7bfb78115b10d..c41daa596d2d0 100644 --- a/flang/test/Parser/OpenMP/declare-reduction-operator.f90 +++ b/flang/test/Parser/OpenMP/declare-reduction-operator.f90 @@ -16,27 +16,33 @@ subroutine reduce_1 ( n, tts ) type(tt) :: tts(n) type(tt2) :: tts2(n) -!CHECK: !$OMP DECLARE REDUCTION (+:tt: omp_out=tt(x=omp_out%x-omp_in%x,y=omp_out%y-omp_in%y) +!CHECK: !$OMP DECLARE REDUCTION(+:tt: omp_out=tt(x=omp_out%x-omp_in%x,y=omp_out%y-omp_in%y) !CHECK: ) INITIALIZER(omp_priv=tt(x=0_4,y=0_4)) -!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -!PARSE-TREE: Verbatim -!PARSE-TREE: OmpReductionSpecifier -!PARSE-TREE: OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Add -!PARSE-TREE: OmpReductionCombiner -> AssignmentStmt = 'omp_out=tt(x=omp_out%x-omp_in%x,y=omp_out%y-omp_in%y)' -!PARSE-TREE: OmpInitializerClause -> AssignmentStmt = 'omp_priv=tt(x=0_4,y=0_4)' - + +!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -> OmpDirectiveSpecification +!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare reduction +!PARSE-TREE: | OmpArgumentList -> OmpArgument -> OmpReductionSpecifier +!PARSE-TREE: | | OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Add +!PARSE-TREE: | | OmpTypeNameList -> OmpTypeSpecifier -> TypeSpec -> DerivedTypeSpec +!PARSE-TREE: | | | Name = 'tt' +!PARSE-TREE: | | OmpReductionCombiner -> AssignmentStmt = 'omp_out=tt(x=omp_out%x-omp_in%x,y=omp_out%y-omp_in%y)' +!PARSE-TREE: | OmpClauseList -> OmpClause -> Initializer -> OmpInitializerClause -> AssignmentStmt = 'omp_priv=tt(x=0_4,y=0_4)' + !$omp declare reduction(+ : tt : omp_out = tt(omp_out%x - omp_in%x , omp_out%y - omp_in%y)) initializer(omp_priv = tt(0,0)) -!CHECK: !$OMP DECLARE REDUCTION (+:tt2: omp_out=tt2(x=omp_out%x-omp_in%x,y=omp_out%y-omp_in%y) +!CHECK: !$OMP DECLARE REDUCTION(+:tt2: omp_out=tt2(x=omp_out%x-omp_in%x,y=omp_out%y-omp_in%y) !CHECK: ) INITIALIZER(omp_priv=tt2(x=0._8,y=0._8) -!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -!PARSE-TREE: Verbatim -!PARSE-TREE: OmpReductionSpecifier -!PARSE-TREE: OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Add -!PARSE-TREE: OmpReductionCombiner -> AssignmentStmt = 'omp_out=tt2(x=omp_out%x-omp_in%x,y=omp_out%y-omp_in%y)' -!PARSE-TREE: OmpInitializerClause -> AssignmentStmt = 'omp_priv=tt2(x=0._8,y=0._8)' - + +!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -> OmpDirectiveSpecification +!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare reduction +!PARSE-TREE: | OmpArgumentList -> OmpArgument -> OmpReductionSpecifier +!PARSE-TREE: | | OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Add +!PARSE-TREE: | | OmpTypeNameList -> OmpTypeSpecifier -> TypeSpec -> DerivedTypeSpec +!PARSE-TREE: | | | Name = 'tt2' +!PARSE-TREE: | | OmpReductionCombiner -> AssignmentStmt = 'omp_out=tt2(x=omp_out%x-omp_in%x,y=omp_out%y-omp_in%y)' +!PARSE-TREE: | OmpClauseList -> OmpClause -> Initializer -> OmpInitializerClause -> AssignmentStmt = 'omp_priv=tt2(x=0._8,y=0._8)' + !$omp declare reduction(+ :tt2 : omp_out = tt2(omp_out%x - omp_in%x , omp_out%y - omp_in%y)) initializer(omp_priv = tt2(0,0)) type(tt) :: diffp = tt( 0, 0 ) diff --git a/flang/test/Parser/OpenMP/declare-reduction-unparse-with-symbols.f90 b/flang/test/Parser/OpenMP/declare-reduction-unparse-with-symbols.f90 index fbcd5b62821a3..131a816057d5a 100644 --- a/flang/test/Parser/OpenMP/declare-reduction-unparse-with-symbols.f90 +++ b/flang/test/Parser/OpenMP/declare-reduction-unparse-with-symbols.f90 @@ -8,6 +8,6 @@ subroutine f00 !CHECK: !DEF: /f00 (Subroutine) Subprogram !CHECK: subroutine f00 -!CHECK: !$omp declare reduction (fred:integer,real:omp_out = omp_in+omp_out) +!CHECK: !$omp declare reduction(fred:integer,real:omp_out = omp_in+omp_out) !CHECK: end subroutine diff --git a/flang/test/Parser/OpenMP/declare-reduction-unparse.f90 b/flang/test/Parser/OpenMP/declare-reduction-unparse.f90 index 0ed693e5821d6..7607b3d20b52d 100644 --- a/flang/test/Parser/OpenMP/declare-reduction-unparse.f90 +++ b/flang/test/Parser/OpenMP/declare-reduction-unparse.f90 @@ -18,21 +18,38 @@ subroutine initme(x,n) integer x,n end subroutine initme end interface -!CHECK: !$OMP DECLARE REDUCTION (red_add:INTEGER(KIND=4_4): omp_out=omp_out+omp_in -!CHECK: ) INITIALIZER(initme(omp_priv, 0_4)) !$omp declare reduction(red_add:integer(4):omp_out=omp_out+omp_in) initializer(initme(omp_priv,0)) -!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -!PARSE-TREE: OmpReductionCombiner -> AssignmentStmt = 'omp_out=omp_out+omp_in' -!PARSE-TREE: OmpInitializerClause -> OmpInitializerProc -!PARSE-TREE-NEXT: ProcedureDesignator -> Name = 'initme' +!CHECK: !$OMP DECLARE REDUCTION(red_add:INTEGER(KIND=4_4): omp_out=omp_out+omp_in +!CHECK: ) INITIALIZER(initme(omp_priv, 0_4)) + +!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -> OmpDirectiveSpecification +!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare reduction +!PARSE-TREE: | OmpArgumentList -> OmpArgument -> OmpReductionSpecifier +!PARSE-TREE: | | OmpReductionIdentifier -> ProcedureDesignator -> Name = 'red_add' +!PARSE-TREE: | | OmpTypeNameList -> OmpTypeSpecifier -> DeclarationTypeSpec -> IntrinsicTypeSpec -> IntegerTypeSpec -> KindSelector -> Scalar -> Integer -> Constant -> Expr = '4_4' +!PARSE-TREE: | | | LiteralConstant -> IntLiteralConstant = '4' +!PARSE-TREE: | | OmpReductionCombiner -> AssignmentStmt = 'omp_out=omp_out+omp_in' +!PARSE-TREE: | OmpClauseList -> OmpClause -> Initializer -> OmpInitializerClause -> OmpInitializerProc +!PARSE-TREE: | | ProcedureDesignator -> Name = 'initme' + res=init !$omp simd reduction(red_add:res) !CHECK: !$OMP SIMD REDUCTION(red_add: res) + +!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> AssignmentStmt = 'res=init' +!PARSE-TREE: | Variable = 'res' +!PARSE-TREE: | | Designator -> DataRef -> Name = 'res' +!PARSE-TREE: | Expr = 'init' +!PARSE-TREE: | | Designator -> DataRef -> Name = 'init' !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPLoopConstruct -!PARSE-TREE: OmpBeginLoopDirective -!PARSE-TREE: OmpDirectiveName -> llvm::omp::Directive = simd -!PARSE-TREE: OmpClauseList -> OmpClause -> Reduction -> OmpReductionClause -!PARSE-TREE: Modifier -> OmpReductionIdentifier -> ProcedureDesignator -> Name = 'red_add +!PARSE-TREE: | OmpBeginLoopDirective +!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = simd +!PARSE-TREE: | | OmpClauseList -> OmpClause -> Reduction -> OmpReductionClause +!PARSE-TREE: | | | Modifier -> OmpReductionIdentifier -> ProcedureDesignator -> Name = 'red_add' +!PARSE-TREE: | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'res' +!PARSE-TREE: | | Flags = None +!PARSE-TREE: | DoConstruct + do i=1,n res=res+x(i) enddo @@ -43,7 +60,7 @@ end function func !CHECK-LABEL: program main program main integer :: my_var -!CHECK: !$OMP DECLARE REDUCTION (my_add_red:INTEGER: omp_out=omp_out+omp_in +!CHECK: !$OMP DECLARE REDUCTION(my_add_red:INTEGER: omp_out=omp_out+omp_in !CHECK-NEXT: ) INITIALIZER(omp_priv=0_4) !$omp declare reduction (my_add_red : integer : omp_out = omp_out + omp_in) initializer (omp_priv=0) @@ -54,8 +71,10 @@ program main print *, "sum of thread numbers is ", my_var end program main -!PARSE-TREE: OpenMPDeclareReductionConstruct -!PARSE-TREE: OmpReductionIdentifier -> ProcedureDesignator -> Name = 'my_add_red' -!PARSE-TREE: DeclarationTypeSpec -> IntrinsicTypeSpec -> IntegerTypeSpec -!PARSE-TREE: OmpReductionCombiner -> AssignmentStmt = 'omp_out=omp_out+omp_in' -!PARSE-TREE: OmpInitializerClause -> AssignmentStmt = 'omp_priv=0_4' +!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -> OmpDirectiveSpecification +!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare reduction +!PARSE-TREE: | OmpArgumentList -> OmpArgument -> OmpReductionSpecifier +!PARSE-TREE: | | OmpReductionIdentifier -> ProcedureDesignator -> Name = 'my_add_red' +!PARSE-TREE: | | OmpTypeNameList -> OmpTypeSpecifier -> DeclarationTypeSpec -> IntrinsicTypeSpec -> IntegerTypeSpec -> +!PARSE-TREE: | | OmpReductionCombiner -> AssignmentStmt = 'omp_out=omp_out+omp_in' +!PARSE-TREE: | OmpClauseList -> OmpClause -> Initializer -> OmpInitializerClause -> AssignmentStmt = 'omp_priv=0_4' diff --git a/flang/test/Parser/OpenMP/openmp6-directive-spellings.f90 b/flang/test/Parser/OpenMP/openmp6-directive-spellings.f90 index 47237de2d5aff..c4d9f6ef4618c 100644 --- a/flang/test/Parser/OpenMP/openmp6-directive-spellings.f90 +++ b/flang/test/Parser/OpenMP/openmp6-directive-spellings.f90 @@ -79,13 +79,13 @@ subroutine f02 !UNPARSE: TYPE :: t !UNPARSE: INTEGER :: x !UNPARSE: END TYPE -!UNPARSE: !$OMP DECLARE REDUCTION (+:t: omp_out%x=omp_out%x+omp_in%x +!UNPARSE: !$OMP DECLARE_REDUCTION(+:t: omp_out%x=omp_out%x+omp_in%x !UNPARSE: ) !UNPARSE: END SUBROUTINE -!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -!PARSE-TREE: | Verbatim -!PARSE-TREE: | OmpReductionSpecifier +!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareReductionConstruct -> OmpDirectiveSpecification +!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = declare reduction +!PARSE-TREE: | OmpArgumentList -> OmpArgument -> OmpReductionSpecifier !PARSE-TREE: | | OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Add !PARSE-TREE: | | OmpTypeNameList -> OmpTypeSpecifier -> TypeSpec -> DerivedTypeSpec !PARSE-TREE: | | | Name = 't' @@ -105,6 +105,7 @@ subroutine f02 !PARSE-TREE: | | | | | | | DataRef -> Name = 'omp_in' !PARSE-TREE: | | | | | | | Name = 'x' !PARSE-TREE: | OmpClauseList -> +!PARSE-TREE: | Flags = None subroutine f03 !$omp declare_simd diff --git a/flang/test/Semantics/OpenMP/declare-reduction-modfile.f90 b/flang/test/Semantics/OpenMP/declare-reduction-modfile.f90 index f80eb1097e18a..2fb2cd7c4b89d 100644 --- a/flang/test/Semantics/OpenMP/declare-reduction-modfile.f90 +++ b/flang/test/Semantics/OpenMP/declare-reduction-modfile.f90 @@ -6,13 +6,13 @@ !type::t1 !integer(4)::val !endtype -!!$OMP DECLARE REDUCTION (*:t1:omp_out = omp_out*omp_in) INITIALIZER(omp_priv=t& -!!$OMP&1(1)) +!!$OMP DECLARE REDUCTION(*:t1:omp_out = omp_out*omp_in) INITIALIZER(omp_priv=t1& +!!$OMP&(1)) !!$OMP METADIRECTIVE OTHERWISE(DECLARE REDUCTION(+:INTEGER)) -!!$OMP DECLARE REDUCTION (.fluffy.:t1:omp_out = omp_out.fluffy.omp_in) INITIALI& -!!$OMP&ZER(omp_priv=t1(0)) -!!$OMP DECLARE REDUCTION (.mul.:t1:omp_out = omp_out.mul.omp_in) INITIALIZER(om& -!!$OMP&p_priv=t1(1)) +!!$OMP DECLARE REDUCTION(.fluffy.:t1:omp_out = omp_out.fluffy.omp_in) INITIALIZ& +!!$OMP&ER(omp_priv=t1(0)) +!!$OMP DECLARE REDUCTION(.mul.:t1:omp_out = omp_out.mul.omp_in) INITIALIZER(omp& +!!$OMP&_priv=t1(1)) !interface operator(.mul.) !procedure::mul !end interface