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 @@ -532,7 +532,8 @@ mlir::acc::ReductionOperator op) { if (op != mlir::acc::ReductionOperator::AccAdd && op != mlir::acc::ReductionOperator::AccMul && - op != mlir::acc::ReductionOperator::AccMin) + op != mlir::acc::ReductionOperator::AccMin && + op != mlir::acc::ReductionOperator::AccMax) TODO(loc, "reduction operator"); // min -> largest @@ -551,6 +552,20 @@ builder.getFloatAttr( ty, llvm::APFloat::getLargest(sem, /*negative=*/false))); } + // max -> least + } else if (op == mlir::acc::ReductionOperator::AccMax) { + if (ty.isIntOrIndex()) + return builder.create( + loc, ty, + builder.getIntegerAttr( + ty, llvm::APInt::getSignedMinValue(ty.getIntOrFloatBitWidth()) + .getSExtValue())); + if (auto floatTy = mlir::dyn_cast_or_null(ty)) + return builder.create( + loc, ty, + builder.getFloatAttr( + ty, llvm::APFloat::getSmallest(floatTy.getFloatSemantics(), + /*negative=*/true))); } else { // 0 for +, ior, ieor // 1 for * @@ -562,6 +577,7 @@ return builder.create( loc, ty, builder.getFloatAttr(ty, initValue)); } + TODO(loc, "reduction type"); } @@ -587,6 +603,9 @@ if (op == mlir::acc::ReductionOperator::AccMin) return fir::genMin(builder, loc, {value1, value2}); + if (op == mlir::acc::ReductionOperator::AccMax) + return fir::genMax(builder, loc, {value1, value2}); + 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,28 @@ ! RUN: bbc -fopenacc -emit-fir %s -o - | FileCheck %s +! CHECK-LABEL: acc.reduction.recipe @reduction_max_f32 : f32 reduction_operator init { +! CHECK: ^bb0(%{{.*}}: f32): +! CHECK: %[[INIT:.*]] = arith.constant -1.401300e-45 : f32 +! CHECK: acc.yield %[[INIT]] : f32 +! CHECK: } combiner { +! CHECK: ^bb0(%[[ARG0:.*]]: f32, %[[ARG1:.*]]: f32): +! CHECK: %[[CMP:.*]] = arith.cmpf ogt, %[[ARG0]], %[[ARG1]] : f32 +! CHECK: %[[SELECT:.*]] = arith.select %[[CMP]], %[[ARG0]], %[[ARG1]] : f32 +! CHECK: acc.yield %[[SELECT]] : f32 +! CHECK: } + +! CHECK-LABEL: acc.reduction.recipe @reduction_max_i32 : i32 reduction_operator init { +! CHECK: ^bb0(%arg0: i32): +! CHECK: %[[INIT:.*]] = arith.constant -2147483648 : i32 +! CHECK: acc.yield %[[INIT]] : i32 +! CHECK: } combiner { +! CHECK: ^bb0(%[[ARG0:.*]]: i32, %[[ARG1:.*]]: i32): +! CHECK: %[[CMP:.*]] = arith.cmpi sgt, %[[ARG0]], %[[ARG1]] : i32 +! CHECK: %[[SELECT:.*]] = arith.select %[[CMP]], %[[ARG0]], %[[ARG1]] : i32 +! CHECK: acc.yield %[[SELECT]] : i32 +! CHECK: } + ! CHECK-LABEL: acc.reduction.recipe @reduction_min_f32 : f32 reduction_operator init { ! CHECK: ^bb0(%{{.*}}: f32): ! CHECK: %[[INIT:.*]] = arith.constant 3.40282347E+38 : f32 @@ -148,3 +170,31 @@ ! CHECK-LABEL: func.func @_QPacc_reduction_min_float( ! CHECK-SAME: %{{.*}}: !fir.ref> {fir.bindc_name = "a"}, %[[B:.*]]: !fir.ref {fir.bindc_name = "b"}) ! CHECK: acc.loop reduction(@reduction_min_f32 -> %[[B]] : !fir.ref) + +subroutine acc_reduction_max_int(a, b) + integer :: a(100) + integer :: i, b + + !$acc loop reduction(max:b) + do i = 1, 100 + b = max(b, a(i)) + end do +end subroutine + +! CHECK-LABEL: func.func @_QPacc_reduction_max_int( +! CHECK-SAME: %{{.*}}: !fir.ref> {fir.bindc_name = "a"}, %[[B:.*]]: !fir.ref {fir.bindc_name = "b"}) +! CHECK: acc.loop reduction(@reduction_max_i32 -> %[[B]] : !fir.ref) + +subroutine acc_reduction_max_float(a, b) + real :: a(100), b + integer :: i + + !$acc loop reduction(max:b) + do i = 1, 100 + b = max(b, a(i)) + end do +end subroutine + +! CHECK-LABEL: func.func @_QPacc_reduction_max_float( +! CHECK-SAME: %{{.*}}: !fir.ref> {fir.bindc_name = "a"}, %[[B:.*]]: !fir.ref {fir.bindc_name = "b"}) +! CHECK: acc.loop reduction(@reduction_max_f32 -> %[[B]] : !fir.ref)