[flang-commits] [flang] d3a0df7 - [flang][openacc] Add semantic check for reduction operator and types

Valentin Clement via flang-commits flang-commits at lists.llvm.org
Thu Jul 13 08:55:09 PDT 2023


Author: Valentin Clement
Date: 2023-07-13T08:55:01-07:00
New Revision: d3a0df78bfd332790f23e653d497166de29f7468

URL: https://github.com/llvm/llvm-project/commit/d3a0df78bfd332790f23e653d497166de29f7468
DIFF: https://github.com/llvm/llvm-project/commit/d3a0df78bfd332790f23e653d497166de29f7468.diff

LOG: [flang][openacc] Add semantic check for reduction operator and types

Check the combination of reduction operator and types. This is
currently not checking common block and composite types.

Depends on D155105

Reviewed By: razvanlupusoru

Differential Revision: https://reviews.llvm.org/D155106

Added: 
    flang/test/Semantics/OpenACC/acc-reduction-validity.f90

Modified: 
    flang/lib/Semantics/check-acc-structure.cpp

Removed: 
    


################################################################################
diff  --git a/flang/lib/Semantics/check-acc-structure.cpp b/flang/lib/Semantics/check-acc-structure.cpp
index f5c226b0c32f24..aeb34b8d5cb9eb 100644
--- a/flang/lib/Semantics/check-acc-structure.cpp
+++ b/flang/lib/Semantics/check-acc-structure.cpp
@@ -6,6 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 #include "check-acc-structure.h"
+#include "flang/Common/enum-set.h"
 #include "flang/Parser/parse-tree.h"
 #include "flang/Semantics/tools.h"
 
@@ -20,6 +21,35 @@
     RequiresConstantPositiveParameter(llvm::acc::Clause::Y, c.v); \
   }
 
+using ReductionOpsSet =
+    Fortran::common::EnumSet<Fortran::parser::AccReductionOperator::Operator,
+        Fortran::parser::AccReductionOperator::Operator_enumSize>;
+
+static ReductionOpsSet reductionIntegerSet{
+    Fortran::parser::AccReductionOperator::Operator::Plus,
+    Fortran::parser::AccReductionOperator::Operator::Multiply,
+    Fortran::parser::AccReductionOperator::Operator::Max,
+    Fortran::parser::AccReductionOperator::Operator::Min,
+    Fortran::parser::AccReductionOperator::Operator::Iand,
+    Fortran::parser::AccReductionOperator::Operator::Ior,
+    Fortran::parser::AccReductionOperator::Operator::Ieor};
+
+static ReductionOpsSet reductionRealSet{
+    Fortran::parser::AccReductionOperator::Operator::Plus,
+    Fortran::parser::AccReductionOperator::Operator::Multiply,
+    Fortran::parser::AccReductionOperator::Operator::Max,
+    Fortran::parser::AccReductionOperator::Operator::Min};
+
+static ReductionOpsSet reductionComplexSet{
+    Fortran::parser::AccReductionOperator::Operator::Plus,
+    Fortran::parser::AccReductionOperator::Operator::Multiply};
+
+static ReductionOpsSet reductionLogicalSet{
+    Fortran::parser::AccReductionOperator::Operator::And,
+    Fortran::parser::AccReductionOperator::Operator::Or,
+    Fortran::parser::AccReductionOperator::Operator::Eqv,
+    Fortran::parser::AccReductionOperator::Operator::Neqv};
+
 namespace Fortran::semantics {
 
 static constexpr inline AccClauseSet
@@ -335,7 +365,6 @@ CHECK_SIMPLE_CLAUSE(NumWorkers, ACCC_num_workers)
 CHECK_SIMPLE_CLAUSE(Present, ACCC_present)
 CHECK_SIMPLE_CLAUSE(Private, ACCC_private)
 CHECK_SIMPLE_CLAUSE(Read, ACCC_read)
-CHECK_SIMPLE_CLAUSE(Reduction, ACCC_reduction)
 CHECK_SIMPLE_CLAUSE(Seq, ACCC_seq)
 CHECK_SIMPLE_CLAUSE(Tile, ACCC_tile)
 CHECK_SIMPLE_CLAUSE(UseDevice, ACCC_use_device)
@@ -431,6 +460,57 @@ void AccStructureChecker::Enter(const parser::AccClause::NumGangs &n) {
         "NUM_GANGS clause accepts a maximum of 3 arguments"_err_en_US);
 }
 
+void AccStructureChecker::Enter(const parser::AccClause::Reduction &reduction) {
+  CheckAllowed(llvm::acc::Clause::ACCC_reduction);
+
+  // From OpenACC 3.3
+  // At a minimum, the supported data types include Fortran logical as well as
+  // the numerical data types (e.g. integer, real, double precision, complex).
+  // However, for each reduction operator, the supported data types include only
+  // the types permitted as operands to the corresponding operator in the base
+  // language where (1) for max and min, the corresponding operator is less-than
+  // and (2) for other operators, the operands and the result are the same type.
+  //
+  // The following check that the reduction operator is supported with the given
+  // type.
+  const parser::AccObjectListWithReduction &list{reduction.v};
+  const auto &op{std::get<parser::AccReductionOperator>(list.t)};
+  const auto &objects{std::get<parser::AccObjectList>(list.t)};
+
+  for (const auto &object : objects.v) {
+    std::visit(
+        Fortran::common::visitors{
+            [&](const Fortran::parser::Designator &designator) {
+              if (const auto *name = getDesignatorNameIfDataRef(designator)) {
+                const auto *type{name->symbol->GetType()};
+                if (type->IsNumeric(TypeCategory::Integer) &&
+                    !reductionIntegerSet.test(op.v)) {
+                  context_.Say(GetContext().clauseSource,
+                      "reduction operator not supported for integer type"_err_en_US);
+                } else if (type->IsNumeric(TypeCategory::Real) &&
+                    !reductionRealSet.test(op.v)) {
+                  context_.Say(GetContext().clauseSource,
+                      "reduction operator not supported for real type"_err_en_US);
+                } else if (type->IsNumeric(TypeCategory::Complex) &&
+                    !reductionComplexSet.test(op.v)) {
+                  context_.Say(GetContext().clauseSource,
+                      "reduction operator not supported for complex type"_err_en_US);
+                } else if (type->category() ==
+                        Fortran::semantics::DeclTypeSpec::Category::Logical &&
+                    !reductionLogicalSet.test(op.v)) {
+                  context_.Say(GetContext().clauseSource,
+                      "reduction operator not supported for logical type"_err_en_US);
+                }
+                // TODO: check composite type.
+              }
+            },
+            [&](const Fortran::parser::Name &name) {
+              // TODO: check common block
+            }},
+        object.u);
+  }
+}
+
 void AccStructureChecker::Enter(const parser::AccClause::Self &x) {
   CheckAllowed(llvm::acc::Clause::ACCC_self);
   const std::optional<parser::AccSelfClause> &accSelfClause = x.v;

diff  --git a/flang/test/Semantics/OpenACC/acc-reduction-validity.f90 b/flang/test/Semantics/OpenACC/acc-reduction-validity.f90
new file mode 100644
index 00000000000000..ccd009bffa2e24
--- /dev/null
+++ b/flang/test/Semantics/OpenACC/acc-reduction-validity.f90
@@ -0,0 +1,172 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenacc
+
+! Check OpenACC reduction validity.
+
+program openacc_reduction_validity
+
+  integer :: i
+  real :: r
+  complex :: c
+  logical :: l
+
+  !$acc parallel reduction(+:i)
+  !$acc end parallel
+
+  !$acc parallel reduction(*:i)
+  !$acc end parallel
+
+  !$acc parallel reduction(min:i)
+  !$acc end parallel
+
+  !$acc parallel reduction(max:i)
+  !$acc end parallel
+
+  !$acc parallel reduction(iand:i)
+  !$acc end parallel
+
+  !$acc parallel reduction(ior:i)
+  !$acc end parallel
+
+  !$acc parallel reduction(ieor:i)
+  !$acc end parallel
+
+  !ERROR: reduction operator not supported for integer type
+  !$acc parallel reduction(.and.:i)
+  !$acc end parallel
+
+  !ERROR: reduction operator not supported for integer type
+  !$acc parallel reduction(.or.:i)
+  !$acc end parallel
+
+  !ERROR: reduction operator not supported for integer type
+  !$acc parallel reduction(.eqv.:i)
+  !$acc end parallel
+
+  !ERROR: reduction operator not supported for integer type
+  !$acc parallel reduction(.neqv.:i)
+  !$acc end parallel
+
+  !$acc parallel reduction(+:r)
+  !$acc end parallel
+
+  !$acc parallel reduction(*:r)
+  !$acc end parallel
+
+  !$acc parallel reduction(min:r)
+  !$acc end parallel
+
+  !$acc parallel reduction(max:r)
+  !$acc end parallel
+
+  !ERROR: reduction operator not supported for real type
+  !$acc parallel reduction(iand:r)
+  !$acc end parallel
+
+  !ERROR: reduction operator not supported for real type
+  !$acc parallel reduction(ior:r)
+  !$acc end parallel
+
+  !ERROR: reduction operator not supported for real type
+  !$acc parallel reduction(ieor:r)
+  !$acc end parallel
+
+  !ERROR: reduction operator not supported for real type
+  !$acc parallel reduction(.and.:r)
+  !$acc end parallel
+
+  !ERROR: reduction operator not supported for real type
+  !$acc parallel reduction(.or.:r)
+  !$acc end parallel
+
+  !ERROR: reduction operator not supported for real type
+  !$acc parallel reduction(.eqv.:r)
+  !$acc end parallel
+
+  !ERROR: reduction operator not supported for real type
+  !$acc parallel reduction(.neqv.:r)
+  !$acc end parallel
+
+  !$acc parallel reduction(+:c)
+  !$acc end parallel
+
+  !$acc parallel reduction(*:c)
+  !$acc end parallel
+
+  !ERROR: reduction operator not supported for complex type
+  !$acc parallel reduction(min:c)
+  !$acc end parallel
+
+  !ERROR: reduction operator not supported for complex type
+  !$acc parallel reduction(max:c)
+  !$acc end parallel
+
+  !ERROR: reduction operator not supported for complex type
+  !$acc parallel reduction(iand:c)
+  !$acc end parallel
+
+  !ERROR: reduction operator not supported for complex type
+  !$acc parallel reduction(ior:c)
+  !$acc end parallel
+
+  !ERROR: reduction operator not supported for complex type
+  !$acc parallel reduction(ieor:c)
+  !$acc end parallel
+
+  !ERROR: reduction operator not supported for complex type
+  !$acc parallel reduction(.and.:c)
+  !$acc end parallel
+
+  !ERROR: reduction operator not supported for complex type
+  !$acc parallel reduction(.or.:c)
+  !$acc end parallel
+
+  !ERROR: reduction operator not supported for complex type
+  !$acc parallel reduction(.eqv.:c)
+  !$acc end parallel
+
+  !ERROR: reduction operator not supported for complex type
+  !$acc parallel reduction(.neqv.:c)
+  !$acc end parallel
+
+  !$acc parallel reduction(.and.:l)
+  !$acc end parallel
+
+  !$acc parallel reduction(.or.:l)
+  !$acc end parallel
+
+  !$acc parallel reduction(.eqv.:l)
+  !$acc end parallel
+
+  !$acc parallel reduction(.neqv.:l)
+  !$acc end parallel
+
+  !ERROR: reduction operator not supported for logical type
+  !$acc parallel reduction(+:l)
+  !$acc end parallel
+
+  !ERROR: reduction operator not supported for logical type
+  !$acc parallel reduction(*:l)
+  !$acc end parallel
+
+  !ERROR: reduction operator not supported for logical type
+  !$acc parallel reduction(min:l)
+  !$acc end parallel
+
+  !ERROR: reduction operator not supported for logical type
+  !$acc parallel reduction(max:l)
+  !$acc end parallel
+
+  !ERROR: reduction operator not supported for logical type
+  !$acc parallel reduction(iand:l)
+  !$acc end parallel
+
+  !ERROR: reduction operator not supported for logical type
+  !$acc parallel reduction(ior:l)
+  !$acc end parallel
+
+  !ERROR: reduction operator not supported for logical type
+  !$acc parallel reduction(ieor:l)
+  !$acc end parallel
+
+
+end program


        


More information about the flang-commits mailing list