diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp --- a/flang/lib/Lower/OpenACC.cpp +++ b/flang/lib/Lower/OpenACC.cpp @@ -559,10 +559,13 @@ static mlir::Value genReductionInitValue(mlir::OpBuilder &builder, mlir::Location loc, mlir::Type ty, mlir::acc::ReductionOperator op) { - if (op != mlir::acc::ReductionOperator::AccAdd) + if (op != mlir::acc::ReductionOperator::AccAdd && + op != mlir::acc::ReductionOperator::AccMul) TODO(loc, "reduction operator"); - unsigned initValue = 0; + // 0 for +, ior, ieor + // 1 for * + unsigned initValue = op == mlir::acc::ReductionOperator::AccMul ? 1 : 0; if (ty.isIntOrIndex()) return builder.create( @@ -583,6 +586,14 @@ return builder.create(loc, value1, value2); TODO(loc, "reduction add type"); } + + if (op == mlir::acc::ReductionOperator::AccMul) { + if (ty.isIntOrIndex()) + return builder.create(loc, value1, value2); + if (mlir::isa(ty)) + return builder.create(loc, value1, value2); + TODO(loc, "reduction mul type"); + } TODO(loc, "reduction operator"); } diff --git a/flang/test/Lower/OpenACC/acc-reduction.f90 b/flang/test/Lower/OpenACC/acc-reduction.f90 --- a/flang/test/Lower/OpenACC/acc-reduction.f90 +++ b/flang/test/Lower/OpenACC/acc-reduction.f90 @@ -2,6 +2,26 @@ ! RUN: bbc -fopenacc -emit-fir %s -o - | FileCheck %s +! CHECK-LABEL: acc.reduction.recipe @reduction_mul_f32 : f32 reduction_operator init { +! CHECK: ^bb0(%{{.*}}: f32): +! CHECK: %[[INIT:.*]] = arith.constant 1.000000e+00 : f32 +! CHECK: acc.yield %[[INIT]] : f32 +! CHECK: } combiner { +! CHECK: ^bb0(%[[ARG0:.*]]: f32, %[[ARG1:.*]]: f32): +! CHECK: %[[COMBINED:.*]] = arith.mulf %[[ARG0]], %[[ARG1]] {{.*}} : f32 +! CHECK: acc.yield %[[COMBINED]] : f32 +! CHECK: } + +! CHECK-LABEL: acc.reduction.recipe @reduction_mul_i32 : i32 reduction_operator init { +! CHECK: ^bb0(%{{.*}}: i32): +! CHECK: %[[INIT:.*]] = arith.constant 1 : i32 +! CHECK: acc.yield %[[INIT]] : i32 +! CHECK: } combiner { +! CHECK: ^bb0(%[[ARG0:.*]]: i32, %[[ARG1:.*]]: i32): +! CHECK: %[[COMBINED:.*]] = arith.muli %[[ARG0]], %[[ARG1]] : i32 +! CHECK: acc.yield %[[COMBINED]] : i32 +! CHECK: } + ! CHECK-LABEL: acc.reduction.recipe @reduction_add_f32 : f32 reduction_operator init { ! CHECK: ^bb0(%{{.*}}: f32): ! CHECK: %[[INIT:.*]] = arith.constant 0.000000e+00 : f32 @@ -34,7 +54,7 @@ ! CHECK-LABEL: func.func @_QPacc_reduction_add_int( ! CHECK-SAME: %{{.*}}: !fir.ref> {fir.bindc_name = "a"}, %[[B:.*]]: !fir.ref {fir.bindc_name = "b"}) -! CHECK: acc.loop reduction(@reduction_add_i32 -> %[[B]] : !fir.ref) { +! CHECK: acc.loop reduction(@reduction_add_i32 -> %[[B]] : !fir.ref) subroutine acc_reduction_add_float(a, b) real :: a(100), b @@ -49,3 +69,31 @@ ! CHECK-LABEL: func.func @_QPacc_reduction_add_float( ! CHECK-SAME: %{{.*}}: !fir.ref> {fir.bindc_name = "a"}, %[[B:.*]]: !fir.ref {fir.bindc_name = "b"}) ! CHECK: acc.loop reduction(@reduction_add_f32 -> %[[B]] : !fir.ref) + +subroutine acc_reduction_mul_int(a, b) + integer :: a(100) + integer :: i, b + + !$acc loop reduction(*:b) + do i = 1, 100 + b = b * a(i) + end do +end subroutine + +! CHECK-LABEL: func.func @_QPacc_reduction_mul_int( +! CHECK-SAME: %{{.*}}: !fir.ref> {fir.bindc_name = "a"}, %[[B:.*]]: !fir.ref {fir.bindc_name = "b"}) +! CHECK: acc.loop reduction(@reduction_mul_i32 -> %[[B]] : !fir.ref) + +subroutine acc_reduction_mul_float(a, b) + real :: a(100), b + integer :: i + + !$acc loop reduction(*:b) + do i = 1, 100 + b = b * a(i) + end do +end subroutine + +! CHECK-LABEL: func.func @_QPacc_reduction_mul_float( +! CHECK-SAME: %{{.*}}: !fir.ref> {fir.bindc_name = "a"}, %[[B:.*]]: !fir.ref {fir.bindc_name = "b"}) +! CHECK: acc.loop reduction(@reduction_mul_f32 -> %[[B]] : !fir.ref)