diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp index 3cd970e8b4b59..ac4858551ce04 100644 --- a/flang/lib/Lower/OpenACC.cpp +++ b/flang/lib/Lower/OpenACC.cpp @@ -687,16 +687,19 @@ static R getReductionInitValue(mlir::acc::ReductionOperator op, mlir::Type ty) { static mlir::Value genReductionInitValue(fir::FirOpBuilder &builder, mlir::Location loc, mlir::Type ty, mlir::acc::ReductionOperator op) { - if (op == mlir::acc::ReductionOperator::AccLor && - op == mlir::acc::ReductionOperator::AccEqv && + if (op == mlir::acc::ReductionOperator::AccEqv && op == mlir::acc::ReductionOperator::AccNeqv) TODO(loc, "reduction operator"); - if (op == mlir::acc::ReductionOperator::AccLand) { + if (op == mlir::acc::ReductionOperator::AccLand || + op == mlir::acc::ReductionOperator::AccLor) { assert(mlir::isa(ty) && "expect fir.logical type"); - return builder.createBool(loc, true); + bool value = true; // .true. for .and. and .eqv. + if (op == mlir::acc::ReductionOperator::AccLor || + op == mlir::acc::ReductionOperator::AccNeqv) + value = false; // .false. for .or. and .neqv. + return builder.createBool(loc, value); } - if (ty.isIntOrIndex()) return builder.create( loc, ty, @@ -740,6 +743,17 @@ static mlir::Value genReductionInitValue(fir::FirOpBuilder &builder, TODO(loc, "reduction type"); } +template +static mlir::Value genLogicalCombiner(fir::FirOpBuilder &builder, + mlir::Location loc, mlir::Value value1, + mlir::Value value2) { + mlir::Type i1 = builder.getI1Type(); + mlir::Value v1 = builder.create(loc, i1, value1); + mlir::Value v2 = builder.create(loc, i1, value2); + mlir::Value add = builder.create(loc, v1, v2); + return builder.create(loc, value1.getType(), add); +} + static mlir::Value genCombiner(fir::FirOpBuilder &builder, mlir::Location loc, mlir::acc::ReductionOperator op, mlir::Type ty, mlir::Value value1, mlir::Value value2) { @@ -810,13 +824,12 @@ static mlir::Value genCombiner(fir::FirOpBuilder &builder, mlir::Location loc, if (op == mlir::acc::ReductionOperator::AccXor) return builder.create(loc, value1, value2); - if (op == mlir::acc::ReductionOperator::AccLand) { - mlir::Type i1 = builder.getI1Type(); - mlir::Value v1 = builder.create(loc, i1, value1); - mlir::Value v2 = builder.create(loc, i1, value2); - mlir::Value add = builder.create(loc, v1, v2); - return builder.create(loc, value1.getType(), add); - } + if (op == mlir::acc::ReductionOperator::AccLand) + return genLogicalCombiner(builder, loc, value1, + value2); + + if (op == mlir::acc::ReductionOperator::AccLor) + return genLogicalCombiner(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 index 07229f8e6b3fa..9fda6711dd0d7 100644 --- a/flang/test/Lower/OpenACC/acc-reduction.f90 +++ b/flang/test/Lower/OpenACC/acc-reduction.f90 @@ -2,6 +2,19 @@ ! RUN: bbc -fopenacc -emit-fir %s -o - | FileCheck %s +! CHECK-LABEL: acc.reduction.recipe @reduction_lor_l32 : !fir.logical<4> reduction_operator init { +! CHECK: ^bb0(%{{.*}}: !fir.logical<4>): +! CHECK: %[[CST:.*]] = arith.constant false +! CHECK: acc.yield %[[CST]] : i1 +! CHECK: } combiner { +! CHECK: ^bb0(%[[ARG0:.*]]: !fir.logical<4>, %[[ARG1:.*]]: !fir.logical<4>): +! CHECK: %[[V1:.*]] = fir.convert %[[ARG0]] : (!fir.logical<4>) -> i1 +! CHECK: %[[V2:.*]] = fir.convert %[[ARG1]] : (!fir.logical<4>) -> i1 +! CHECK: %[[AND:.*]] = arith.ori %[[V1]], %[[V2]] : i1 +! CHECK: %[[CONV:.*]] = fir.convert %[[AND]] : (i1) -> !fir.logical<4> +! CHECK: acc.yield %[[CONV]] : !fir.logical<4> +! CHECK: } + ! CHECK-LABEL: acc.reduction.recipe @reduction_land_l32 : !fir.logical<4> reduction_operator init { ! CHECK: ^bb0(%{{.*}}: !fir.logical<4>): ! CHECK: %[[CST:.*]] = arith.constant true @@ -660,3 +673,13 @@ subroutine acc_reduction_and() ! CHECK-LABEL: func.func @_QPacc_reduction_and() ! CHECK: %[[RED:.*]] = acc.reduction varPtr(%0 : !fir.ref>) -> !fir.ref> {name = "l"} ! CHECK: acc.parallel reduction(@reduction_land_l32 -> %[[RED]] : !fir.ref>) + +subroutine acc_reduction_or() + logical :: l + !$acc parallel reduction(.or.:l) + !$acc end parallel +end subroutine + +! CHECK-LABEL: func.func @_QPacc_reduction_or() +! CHECK: %[[RED:.*]] = acc.reduction varPtr(%{{.*}} : !fir.ref>) -> !fir.ref> {name = "l"} +! CHECK: acc.parallel reduction(@reduction_lor_l32 -> %[[RED]] : !fir.ref>)