[flang-commits] [flang] a6ec1e3 - [flang][lowering] Add support for lowering the `dim` intrinsic

Andrzej Warzynski via flang-commits flang-commits at lists.llvm.org
Tue Mar 15 09:27:54 PDT 2022


Author: Andrzej Warzynski
Date: 2022-03-15T16:27:45Z
New Revision: a6ec1e3d798f8eab43fb3a91028c6ab04e115fcb

URL: https://github.com/llvm/llvm-project/commit/a6ec1e3d798f8eab43fb3a91028c6ab04e115fcb
DIFF: https://github.com/llvm/llvm-project/commit/a6ec1e3d798f8eab43fb3a91028c6ab04e115fcb.diff

LOG: [flang][lowering] Add support for lowering the `dim` intrinsic

This patch adds support for lowering of the `dim` intrinsic from Fortran
to the FIR dialect of MLIR.

This is part of the upstreaming effort from the `fir-dev` branch in [1].

[1] https://github.com/flang-compiler/f18-llvm-project

Differential Revision: https://reviews.llvm.org/D121689

Co-authored-by: Jean Perier <jperier at nvidia.com>
Co-authored-by: Eric Schweitz <eschweitz at nvidia.com>
Co-authored-by: Valentin Clement <clementval at gmail.com>
Co-authored-by: V Donaldson <vdonaldson at nvidia.com>

Added: 
    flang/test/Lower/Intrinsics/dim.f90

Modified: 
    flang/lib/Lower/IntrinsicCall.cpp

Removed: 
    


################################################################################
diff  --git a/flang/lib/Lower/IntrinsicCall.cpp b/flang/lib/Lower/IntrinsicCall.cpp
index 9eec8534006d0..e43f3a3a5fb15 100644
--- a/flang/lib/Lower/IntrinsicCall.cpp
+++ b/flang/lib/Lower/IntrinsicCall.cpp
@@ -267,6 +267,7 @@ struct IntrinsicLibrary {
   fir::ExtendedValue genAssociated(mlir::Type,
                                    llvm::ArrayRef<fir::ExtendedValue>);
   fir::ExtendedValue genChar(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
+  mlir::Value genDim(mlir::Type, llvm::ArrayRef<mlir::Value>);
   fir::ExtendedValue genDotProduct(mlir::Type,
                                    llvm::ArrayRef<fir::ExtendedValue>);
   template <Extremum, ExtremumBehavior>
@@ -380,6 +381,7 @@ static constexpr IntrinsicHandler handlers[]{
      {{{"pointer", asInquired}, {"target", asInquired}}},
      /*isElemental=*/false},
     {"char", &I::genChar},
+    {"dim", &I::genDim},
     {"dot_product",
      &I::genDotProduct,
      {{{"vector_a", asBox}, {"vector_b", asBox}}},
@@ -1259,6 +1261,25 @@ IntrinsicLibrary::genChar(mlir::Type type,
   return fir::CharBoxValue{cast, len};
 }
 
+// DIM
+mlir::Value IntrinsicLibrary::genDim(mlir::Type resultType,
+                                     llvm::ArrayRef<mlir::Value> args) {
+  assert(args.size() == 2);
+  if (resultType.isa<mlir::IntegerType>()) {
+    mlir::Value zero = builder.createIntegerConstant(loc, resultType, 0);
+    auto 
diff  = builder.create<mlir::arith::SubIOp>(loc, args[0], args[1]);
+    auto cmp = builder.create<mlir::arith::CmpIOp>(
+        loc, mlir::arith::CmpIPredicate::sgt, 
diff , zero);
+    return builder.create<mlir::arith::SelectOp>(loc, cmp, 
diff , zero);
+  }
+  assert(fir::isa_real(resultType) && "Only expects real and integer in DIM");
+  mlir::Value zero = builder.createRealZeroConstant(loc, resultType);
+  auto 
diff  = builder.create<mlir::arith::SubFOp>(loc, args[0], args[1]);
+  auto cmp = builder.create<mlir::arith::CmpFOp>(
+      loc, mlir::arith::CmpFPredicate::OGT, 
diff , zero);
+  return builder.create<mlir::arith::SelectOp>(loc, cmp, 
diff , zero);
+}
+
 // DOT_PRODUCT
 fir::ExtendedValue
 IntrinsicLibrary::genDotProduct(mlir::Type resultType,

diff  --git a/flang/test/Lower/Intrinsics/dim.f90 b/flang/test/Lower/Intrinsics/dim.f90
new file mode 100644
index 0000000000000..9ceecdfd74ad0
--- /dev/null
+++ b/flang/test/Lower/Intrinsics/dim.f90
@@ -0,0 +1,33 @@
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s
+
+! CHECK-LABEL: func @_QPdim_testr(
+! CHECK-SAME:                     %[[VAL_0:[a-z]+[0-9]]]: !fir.ref<f32>{{.*}}, %[[VAL_1:.*]]: !fir.ref<f32>{{.*}}, %[[VAL_2:.*]]: !fir.ref<f32>{{.*}}) {
+subroutine dim_testr(x, y, z)
+! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_0]] : !fir.ref<f32>
+! CHECK: %[[VAL_4:.*]] = fir.load %[[VAL_1]] : !fir.ref<f32>
+! CHECK: %[[VAL_5:.*]] = arith.constant 0.000000e+00 : f32
+! CHECK: %[[VAL_6:.*]] = arith.subf %[[VAL_3]], %[[VAL_4]] : f32
+! CHECK: %[[VAL_7:.*]] = arith.cmpf ogt, %[[VAL_6]], %[[VAL_5]] : f32
+! CHECK: %[[VAL_8:.*]] = arith.select %[[VAL_7]], %[[VAL_6]], %[[VAL_5]] : f32
+! CHECK: fir.store %[[VAL_8]] to %[[VAL_2]] : !fir.ref<f32>
+! CHECK: return
+  real :: x, y, z
+  z = dim(x, y)
+end subroutine
+
+! CHECK-LABEL: func @_QPdim_testi(
+! CHECK-SAME: %[[VAL_0:[a-z]+[0-9]]]: !fir.ref<i32>{{.*}}, %[[VAL_1:.*]]: !fir.ref<i32>{{.*}}, %[[VAL_2:.*]]: !fir.ref<i32>{{.*}}) {
+subroutine dim_testi(i, j, k)
+! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_0]] : !fir.ref<i32>
+! CHECK: %[[VAL_4:.*]] = fir.load %[[VAL_1]] : !fir.ref<i32>
+! CHECK: %[[VAL_5:.*]] = arith.constant 0 : i32
+! CHECK: %[[VAL_6:.*]] = arith.subi %[[VAL_3]], %[[VAL_4]] : i32
+! CHECK: %[[VAL_7:.*]] = arith.cmpi sgt, %[[VAL_6]], %[[VAL_5]] : i32
+! CHECK: %[[VAL_8:.*]] = arith.select %[[VAL_7]], %[[VAL_6]], %[[VAL_5]] : i32
+! CHECK: fir.store %[[VAL_8]] to %[[VAL_2]] : !fir.ref<i32>
+! CHECK: return
+  integer :: i, j, k
+  k = dim(i, j)
+end subroutine
+


        


More information about the flang-commits mailing list