[Flang] Lower the spacing, rrspacing intrinsics
authorKiran Chandramohan <kiran.chandramohan@arm.com>
Thu, 17 Mar 2022 13:47:28 +0000 (13:47 +0000)
committerKiran Chandramohan <kiran.chandramohan@arm.com>
Fri, 18 Mar 2022 09:18:42 +0000 (09:18 +0000)
These intrinsics returns the distance to the nearest real number and
their reciprocal. They are lowered to flang runtime calls.

This is part of the upstreaming effort from the fir-dev branch in [1].
[1] https://github.com/flang-compiler/f18-llvm-project

Reviewed By: clementval

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

Co-authored-by: Mark Leair <leairmark@gmail.com>
Co-authored-by: Eric Schweitz <eschweitz@nvidia.com>
Co-authored-by: Jean Perier <jperier@nvidia.com>
flang/lib/Lower/IntrinsicCall.cpp
flang/test/Lower/Intrinsics/rrspacing.f90 [new file with mode: 0644]
flang/test/Lower/Intrinsics/spacing.f90 [new file with mode: 0644]

index 67c50eb..104fb7e 100644 (file)
@@ -509,12 +509,16 @@ struct IntrinsicLibrary {
   void genRandomSeed(llvm::ArrayRef<fir::ExtendedValue>);
   fir::ExtendedValue genRepeat(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
   fir::ExtendedValue genReshape(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
+  mlir::Value genRRSpacing(mlir::Type resultType,
+                           llvm::ArrayRef<mlir::Value> args);
   mlir::Value genScale(mlir::Type, llvm::ArrayRef<mlir::Value>);
   fir::ExtendedValue genScan(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
   mlir::Value genSetExponent(mlir::Type resultType,
                              llvm::ArrayRef<mlir::Value> args);
   mlir::Value genSign(mlir::Type, llvm::ArrayRef<mlir::Value>);
   fir::ExtendedValue genSize(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
+  mlir::Value genSpacing(mlir::Type resultType,
+                         llvm::ArrayRef<mlir::Value> args);
   fir::ExtendedValue genSum(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
   fir::ExtendedValue genSpread(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
   void genSystemClock(llvm::ArrayRef<fir::ExtendedValue>);
@@ -820,6 +824,7 @@ static constexpr IntrinsicHandler handlers[]{
        {"pad", asBox, handleDynamicOptional},
        {"order", asBox, handleDynamicOptional}}},
      /*isElemental=*/false},
+    {"rrspacing", &I::genRRSpacing},
     {"scale",
      &I::genScale,
      {{{"x", asValue}, {"i", asValue}}},
@@ -839,6 +844,7 @@ static constexpr IntrinsicHandler handlers[]{
        {"dim", asAddr, handleDynamicOptional},
        {"kind", asValue}}},
      /*isElemental=*/false},
+    {"spacing", &I::genSpacing},
     {"spread",
      &I::genSpread,
      {{{"source", asAddr}, {"dim", asValue}, {"ncopies", asValue}}},
@@ -3015,6 +3021,16 @@ IntrinsicLibrary::genReshape(mlir::Type resultType,
                            "unexpected result for RESHAPE");
 }
 
+// RRSPACING
+mlir::Value IntrinsicLibrary::genRRSpacing(mlir::Type resultType,
+                                           llvm::ArrayRef<mlir::Value> args) {
+  assert(args.size() == 1);
+
+  return builder.createConvert(
+      loc, resultType,
+      fir::runtime::genRRSpacing(builder, loc, fir::getBase(args[0])));
+}
+
 // SCALE
 mlir::Value IntrinsicLibrary::genScale(mlir::Type resultType,
                                        llvm::ArrayRef<mlir::Value> args) {
@@ -3130,6 +3146,16 @@ mlir::Value IntrinsicLibrary::genSign(mlir::Type resultType,
   return genRuntimeCall("sign", resultType, args);
 }
 
+// SPACING
+mlir::Value IntrinsicLibrary::genSpacing(mlir::Type resultType,
+                                         llvm::ArrayRef<mlir::Value> args) {
+  assert(args.size() == 1);
+
+  return builder.createConvert(
+      loc, resultType,
+      fir::runtime::genSpacing(builder, loc, fir::getBase(args[0])));
+}
+
 // SIZE
 fir::ExtendedValue
 IntrinsicLibrary::genSize(mlir::Type resultType,
diff --git a/flang/test/Lower/Intrinsics/rrspacing.f90 b/flang/test/Lower/Intrinsics/rrspacing.f90
new file mode 100644 (file)
index 0000000..96f6093
--- /dev/null
@@ -0,0 +1,11 @@
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s
+
+! CHECK-LABEL: func @_QPrrspacing_test2(
+! CHECK-SAME: %[[x:[^:]+]]: !fir.ref<f128>{{.*}}) -> f128
+real*16 function rrspacing_test2(x)
+  real*16 :: x
+  rrspacing_test2 = rrspacing(x)
+! CHECK: %[[a1:.*]] = fir.load %[[x]] : !fir.ref<f128>
+! CHECK: %{{.*}} = fir.call @_FortranARRSpacing16(%[[a1]]) : (f128) -> f128
+end function
diff --git a/flang/test/Lower/Intrinsics/spacing.f90 b/flang/test/Lower/Intrinsics/spacing.f90
new file mode 100644 (file)
index 0000000..b6db96d
--- /dev/null
@@ -0,0 +1,20 @@
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s
+
+! CHECK-LABEL: func @_QPspacing_test(
+! CHECK-SAME: %[[x:[^:]+]]: !fir.ref<f32>{{.*}}) -> f32
+real*4 function spacing_test(x)
+  real*4 :: x
+  spacing_test = spacing(x)
+! CHECK: %[[a1:.*]] = fir.load %[[x]] : !fir.ref<f32>
+! CHECK: %{{.*}} = fir.call @_FortranASpacing4(%[[a1]]) : (f32) -> f32
+end function
+
+! CHECK-LABEL: func @_QPspacing_test2(
+! CHECK-SAME: %[[x:[^:]+]]: !fir.ref<f80>{{.*}}) -> f80
+real*10 function spacing_test2(x)
+  real*10 :: x
+  spacing_test2 = spacing(x)
+! CHECK: %[[a1:.*]] = fir.load %[[x]] : !fir.ref<f80>
+! CHECK: %{{.*}} = fir.call @_FortranASpacing10(%[[a1]]) : (f80) -> f80
+end function