[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