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 @@ -615,6 +615,12 @@ return llvm::APFloat::getSmallest(floatTy.getFloatSemantics(), /*negative=*/true); } + } else if (op == mlir::acc::ReductionOperator::AccIand) { + if constexpr (std::is_same_v) { + assert(ty.isIntOrIndex() && "expect integer type"); + unsigned bits = ty.getIntOrFloatBitWidth(); + return llvm::APInt::getAllOnes(bits); + } } else { // +, ior, ieor init value -> 0 // * init value -> 1 @@ -642,7 +648,8 @@ if (op != mlir::acc::ReductionOperator::AccAdd && op != mlir::acc::ReductionOperator::AccMul && op != mlir::acc::ReductionOperator::AccMin && - op != mlir::acc::ReductionOperator::AccMax) + op != mlir::acc::ReductionOperator::AccMax && + op != mlir::acc::ReductionOperator::AccIand) TODO(loc, "reduction operator"); if (ty.isIntOrIndex()) @@ -746,6 +753,9 @@ if (op == mlir::acc::ReductionOperator::AccMax) return fir::genMax(builder, loc, {value1, value2}); + if (op == mlir::acc::ReductionOperator::AccIand) + return builder.create(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,16 @@ ! RUN: bbc -fopenacc -emit-fir %s -o - | FileCheck %s +! CHECK-LABEL: acc.reduction.recipe @reduction_iand_i32 : i32 reduction_operator init { +! CHECK: ^bb0(%{{.*}}: i32): +! CHECK: %[[CST:.*]] = arith.constant -1 : i32 +! CHECK: acc.yield %[[CST]] : i32 +! CHECK: } combiner { +! CHECK: ^bb0(%[[ARG0:.*]]: i32, %[[ARG1:.*]]: i32): +! CHECK: %[[COMBINED:.*]] = arith.andi %[[ARG0]], %[[ARG1]] : i32 +! CHECK: acc.yield %[[COMBINED]] : i32 +! CHECK: } + ! CHECK-LABEL: acc.reduction.recipe @reduction_max_ref_100xf32 : !fir.ref> reduction_operator init { ! CHECK: ^bb0(%{{.*}}: !fir.ref>): ! CHECK: %[[CST:.*]] = arith.constant dense<-1.401300e-45> : vector<100xf32> @@ -578,3 +588,12 @@ ! CHECK: %[[RED_ARG1:.*]] = acc.reduction varPtr(%[[ARG1]] : !fir.ref>) bounds(%{{.*}}) -> !fir.ref> {name = "b"} ! CHECK: acc.loop reduction(@reduction_max_ref_100xf32 -> %[[RED_ARG1]] : !fir.ref>) { +subroutine acc_reduction_iand() + integer :: i + !$acc parallel reduction(iand:i) + !$acc end parallel +end subroutine + +! CHECK-LABEL: func.func @_QPacc_reduction_iand() +! CHECK: %[[RED:.*]] = acc.reduction varPtr(%{{.*}} : !fir.ref) -> !fir.ref {name = "i"} +! CHECK: acc.parallel reduction(@reduction_iand_i32 -> %[[RED]] : !fir.ref)