[flang-commits] [flang] c1ca4d6 - [flang][openacc] Add lowering for min operator
Valentin Clement via flang-commits
flang-commits at lists.llvm.org
Wed Jun 14 08:18:24 PDT 2023
Author: Valentin Clement
Date: 2023-06-14T08:18:03-07:00
New Revision: c1ca4d6fe7886cb43633345f4ff967d4b1e5dd7f
URL: https://github.com/llvm/llvm-project/commit/c1ca4d6fe7886cb43633345f4ff967d4b1e5dd7f
DIFF: https://github.com/llvm/llvm-project/commit/c1ca4d6fe7886cb43633345f4ff967d4b1e5dd7f.diff
LOG: [flang][openacc] Add lowering for min operator
Add lowering support for the min operator
in reduction clause.
Depends on D151565
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D151671
Added:
Modified:
flang/include/flang/Lower/OpenACC.h
flang/lib/Lower/OpenACC.cpp
flang/test/Lower/OpenACC/acc-reduction.f90
Removed:
################################################################################
diff --git a/flang/include/flang/Lower/OpenACC.h b/flang/include/flang/Lower/OpenACC.h
index 5119e10a99832..f9b4c1f2c62ae 100644
--- a/flang/include/flang/Lower/OpenACC.h
+++ b/flang/include/flang/Lower/OpenACC.h
@@ -25,6 +25,10 @@ class Type;
class OpBuilder;
} // namespace mlir
+namespace fir {
+class FirOpBuilder;
+}
+
namespace Fortran {
namespace parser {
struct OpenACCConstruct;
@@ -59,7 +63,7 @@ mlir::acc::PrivateRecipeOp createOrGetPrivateRecipe(mlir::OpBuilder &,
/// Get a acc.reduction.recipe op for the given type or create it if it does not
/// exist yet.
mlir::acc::ReductionRecipeOp
-createOrGetReductionRecipe(mlir::OpBuilder &, llvm::StringRef, mlir::Location,
+createOrGetReductionRecipe(fir::FirOpBuilder &, llvm::StringRef, mlir::Location,
mlir::Type, mlir::acc::ReductionOperator);
/// Get a acc.firstprivate.recipe op for the given type or create it if it does
diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp
index aad6dca8575f8..6b6b0b7ec98c6 100644
--- a/flang/lib/Lower/OpenACC.cpp
+++ b/flang/lib/Lower/OpenACC.cpp
@@ -18,6 +18,7 @@
#include "flang/Lower/Support/Utils.h"
#include "flang/Optimizer/Builder/BoxValue.h"
#include "flang/Optimizer/Builder/FIRBuilder.h"
+#include "flang/Optimizer/Builder/IntrinsicCall.h"
#include "flang/Optimizer/Builder/Todo.h"
#include "flang/Parser/parse-tree.h"
#include "flang/Semantics/expression.h"
@@ -526,27 +527,45 @@ getReductionOperator(const Fortran::parser::AccReductionOperator &op) {
llvm_unreachable("unexpected reduction operator");
}
-static mlir::Value genReductionInitValue(mlir::OpBuilder &builder,
+static mlir::Value genReductionInitValue(fir::FirOpBuilder &builder,
mlir::Location loc, mlir::Type ty,
mlir::acc::ReductionOperator op) {
if (op != mlir::acc::ReductionOperator::AccAdd &&
- op != mlir::acc::ReductionOperator::AccMul)
+ op != mlir::acc::ReductionOperator::AccMul &&
+ op != mlir::acc::ReductionOperator::AccMin)
TODO(loc, "reduction operator");
- // 0 for +, ior, ieor
- // 1 for *
- unsigned initValue = op == mlir::acc::ReductionOperator::AccMul ? 1 : 0;
-
- if (ty.isIntOrIndex())
- return builder.create<mlir::arith::ConstantOp>(
- loc, ty, builder.getIntegerAttr(ty, initValue));
- if (mlir::isa<mlir::FloatType>(ty))
- return builder.create<mlir::arith::ConstantOp>(
- loc, ty, builder.getFloatAttr(ty, initValue));
+ // min -> largest
+ if (op == mlir::acc::ReductionOperator::AccMin) {
+ if (ty.isIntOrIndex()) {
+ unsigned bits = ty.getIntOrFloatBitWidth();
+ return builder.create<mlir::arith::ConstantOp>(
+ loc, ty,
+ builder.getIntegerAttr(
+ ty, llvm::APInt::getSignedMaxValue(bits).getSExtValue()));
+ }
+ if (auto floatTy = mlir::dyn_cast_or_null<mlir::FloatType>(ty)) {
+ const llvm::fltSemantics &sem = floatTy.getFloatSemantics();
+ return builder.create<mlir::arith::ConstantOp>(
+ loc, ty,
+ builder.getFloatAttr(
+ ty, llvm::APFloat::getLargest(sem, /*negative=*/false)));
+ }
+ } else {
+ // 0 for +, ior, ieor
+ // 1 for *
+ int64_t initValue = op == mlir::acc::ReductionOperator::AccMul ? 1 : 0;
+ if (ty.isIntOrIndex())
+ return builder.create<mlir::arith::ConstantOp>(
+ loc, ty, builder.getIntegerAttr(ty, initValue));
+ if (mlir::isa<mlir::FloatType>(ty))
+ return builder.create<mlir::arith::ConstantOp>(
+ loc, ty, builder.getFloatAttr(ty, initValue));
+ }
TODO(loc, "reduction type");
}
-static mlir::Value genCombiner(mlir::OpBuilder &builder, mlir::Location loc,
+static mlir::Value genCombiner(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::acc::ReductionOperator op, mlir::Type ty,
mlir::Value value1, mlir::Value value2) {
if (op == mlir::acc::ReductionOperator::AccAdd) {
@@ -564,11 +583,15 @@ static mlir::Value genCombiner(mlir::OpBuilder &builder, mlir::Location loc,
return builder.create<mlir::arith::MulFOp>(loc, value1, value2);
TODO(loc, "reduction mul type");
}
+
+ if (op == mlir::acc::ReductionOperator::AccMin)
+ return fir::genMin(builder, loc, {value1, value2});
+
TODO(loc, "reduction operator");
}
mlir::acc::ReductionRecipeOp Fortran::lower::createOrGetReductionRecipe(
- mlir::OpBuilder &builder, llvm::StringRef recipeName, mlir::Location loc,
+ fir::FirOpBuilder &builder, llvm::StringRef recipeName, mlir::Location loc,
mlir::Type ty, mlir::acc::ReductionOperator op) {
mlir::ModuleOp mod =
builder.getBlock()->getParent()->getParentOfType<mlir::ModuleOp>();
diff --git a/flang/test/Lower/OpenACC/acc-reduction.f90 b/flang/test/Lower/OpenACC/acc-reduction.f90
index 9dd40a71d99a5..1499cb3feea31 100644
--- 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_min_f32 : f32 reduction_operator <min> init {
+! CHECK: ^bb0(%{{.*}}: f32):
+! CHECK: %[[INIT:.*]] = arith.constant 3.40282347E+38 : f32
+! CHECK: acc.yield %[[INIT]] : f32
+! CHECK: } combiner {
+! CHECK: ^bb0(%[[ARG0:.*]]: f32, %[[ARG1:.*]]: f32):
+! CHECK: %[[CMP:.*]] = arith.cmpf olt, %[[ARG0]], %[[ARG1]] : f32
+! CHECK: %[[SELECT:.*]] = arith.select %[[CMP]], %[[ARG0]], %[[ARG1]] : f32
+! CHECK: acc.yield %[[SELECT]] : f32
+! CHECK: }
+
+! CHECK-LABEL: acc.reduction.recipe @reduction_min_i32 : i32 reduction_operator <min> init {
+! CHECK: ^bb0(%arg0: i32):
+! CHECK: %[[INIT:.*]] = arith.constant 2147483647 : i32
+! CHECK: acc.yield %[[INIT]] : i32
+! CHECK: } combiner {
+! CHECK: ^bb0(%[[ARG0:.*]]: i32, %[[ARG1:.*]]: i32):
+! CHECK: %[[CMP:.*]] = arith.cmpi slt, %[[ARG0]], %[[ARG1]] : i32
+! CHECK: %[[SELECT:.*]] = arith.select %[[CMP]], %[[ARG0]], %[[ARG1]] : i32
+! CHECK: acc.yield %[[SELECT]] : i32
+! CHECK: }
+
! CHECK-LABEL: acc.reduction.recipe @reduction_mul_f32 : f32 reduction_operator <mul> init {
! CHECK: ^bb0(%{{.*}}: f32):
! CHECK: %[[INIT:.*]] = arith.constant 1.000000e+00 : f32
@@ -97,3 +119,32 @@ subroutine acc_reduction_mul_float(a, b)
! CHECK-LABEL: func.func @_QPacc_reduction_mul_float(
! CHECK-SAME: %{{.*}}: !fir.ref<!fir.array<100xf32>> {fir.bindc_name = "a"}, %[[B:.*]]: !fir.ref<f32> {fir.bindc_name = "b"})
! CHECK: acc.loop reduction(@reduction_mul_f32 -> %[[B]] : !fir.ref<f32>)
+
+
+subroutine acc_reduction_min_int(a, b)
+ integer :: a(100)
+ integer :: i, b
+
+ !$acc loop reduction(min:b)
+ do i = 1, 100
+ b = min(b, a(i))
+ end do
+end subroutine
+
+! CHECK-LABEL: func.func @_QPacc_reduction_min_int(
+! CHECK-SAME: %{{.*}}: !fir.ref<!fir.array<100xi32>> {fir.bindc_name = "a"}, %[[B:.*]]: !fir.ref<i32> {fir.bindc_name = "b"})
+! CHECK: acc.loop reduction(@reduction_min_i32 -> %[[B]] : !fir.ref<i32>)
+
+subroutine acc_reduction_min_float(a, b)
+ real :: a(100), b
+ integer :: i
+
+ !$acc loop reduction(min:b)
+ do i = 1, 100
+ b = min(b, a(i))
+ end do
+end subroutine
+
+! CHECK-LABEL: func.func @_QPacc_reduction_min_float(
+! CHECK-SAME: %{{.*}}: !fir.ref<!fir.array<100xf32>> {fir.bindc_name = "a"}, %[[B:.*]]: !fir.ref<f32> {fir.bindc_name = "b"})
+! CHECK: acc.loop reduction(@reduction_min_f32 -> %[[B]] : !fir.ref<f32>)
More information about the flang-commits
mailing list