diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index 43c6128d46647..abea2b16f8dbc 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -3884,31 +3884,29 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable, const auto &specifier = DEREF(parser::omp::GetFirstArgument( construct.v)); - if (std::get(specifier.t).v.size() > 1) - TODO(converter.getCurrentLocation(), - "multiple types in declare reduction is not yet supported"); - - mlir::Type reductionType = getReductionType(converter, specifier); + const auto &typeNameList = std::get(specifier.t); List clauses = makeClauses(construct.v.Clauses(), semaCtx); const clause::Combiner &combiner = appendCombiner(construct, clauses, semaCtx); - - ReductionProcessor::GenCombinerCBTy genCombinerCB = - processReductionCombiner(converter, symTable, semaCtx, combiner); - - ReductionProcessor::GenInitValueCBTy genInitValueCB; - ClauseProcessor cp(converter, semaCtx, clauses); - cp.processInitializer(symTable, genInitValueCB); - const auto &identifier = std::get(specifier.t); const auto &designator = std::get(identifier.u); const auto &reductionName = std::get(designator.u); - bool isByRef = ReductionProcessor::doReductionByRef(reductionType); - ReductionProcessor::createDeclareReductionHelper< - mlir::omp::DeclareReductionOp>( - converter, reductionName.ToString(), reductionType, - converter.getCurrentLocation(), isByRef, genCombinerCB, genInitValueCB); + + for (const auto &typeSpec : typeNameList.v) { + (void)typeSpec; // Currently unused + mlir::Type reductionType = getReductionType(converter, specifier); + ReductionProcessor::GenCombinerCBTy genCombinerCB = + processReductionCombiner(converter, symTable, semaCtx, combiner); + ReductionProcessor::GenInitValueCBTy genInitValueCB; + ClauseProcessor cp(converter, semaCtx, clauses); + cp.processInitializer(symTable, genInitValueCB); + bool isByRef = ReductionProcessor::doReductionByRef(reductionType); + ReductionProcessor::createDeclareReductionHelper< + mlir::omp::DeclareReductionOp>( + converter, reductionName.ToString(), reductionType, + converter.getCurrentLocation(), isByRef, genCombinerCB, genInitValueCB); + } } static void diff --git a/flang/test/Lower/OpenMP/Todo/multiple-types-declare_reduction.f90 b/flang/test/Lower/OpenMP/Todo/multiple-types-declare_reduction.f90 new file mode 100644 index 0000000000000..e4931018b07ec --- /dev/null +++ b/flang/test/Lower/OpenMP/Todo/multiple-types-declare_reduction.f90 @@ -0,0 +1,51 @@ +! Test OpenMP declare reduction with integer and real types. +! This test verifies correct lowering of user-defined reductions +! to HLFIR and their use in OpenMP parallel loops. + +! RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s + +program main + implicit none + integer :: i, isum + real :: rsum + + !$omp declare reduction(myred: integer, real : & + !$omp omp_out = omp_out + omp_in) initializer(omp_priv = 0) + + isum = 0 + rsum = 0.0 + + !$omp parallel do reduction(myred:isum) + do i = 1, 3 + isum = isum + i + end do + + !$omp parallel do reduction(myred:rsum) + do i = 1, 3 + rsum = rsum + real(i) + end do + + print *, isum, rsum +end program main + +! Verify declare reduction is created for integer +! CHECK-LABEL: omp.declare_reduction @myred : i32 +! CHECK: init { +! CHECK: arith.constant 0 : i32 +! CHECK: omp.yield + +! Verify integer combiner uses addi +! CHECK: combiner { +! CHECK: arith.addi +! CHECK: omp.yield + +! Verify reduction is used in first parallel loop (integer) +! CHECK: omp.parallel +! CHECK: omp.wsloop +! CHECK-SAME: reduction(@myred + +! Verify reduction is used in second parallel loop (real) +! CHECK: omp.parallel +! CHECK: omp.wsloop +! CHECK-SAME: reduction(@myred +! CHECK: arith.addf