[flang-commits] [flang] 291913d - [Flang] Lower the repeat intrinsic

Kiran Chandramohan via flang-commits flang-commits at lists.llvm.org
Thu Mar 17 06:38:31 PDT 2022


Author: Kiran Chandramohan
Date: 2022-03-17T13:38:16Z
New Revision: 291913db53722f216222bbb1b685965215ffaf36

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

LOG: [Flang] Lower the repeat intrinsic

The repeat intrinsic creates ncopies of a string. The lowering is to
a runtime call to a function in the flang library. The runtime allocates
the buffer to store the result string. This buffer is freed by code
added in the lowering.

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/D121880

Co-authored-by: Valentin Clement <clementval at gmail.com>
Co-authored-by: Jean Perier <jperier at nvidia.com>

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

Modified: 
    flang/lib/Lower/IntrinsicCall.cpp

Removed: 
    


################################################################################
diff  --git a/flang/lib/Lower/IntrinsicCall.cpp b/flang/lib/Lower/IntrinsicCall.cpp
index 512c24d685eb5..e04984433ed47 100644
--- a/flang/lib/Lower/IntrinsicCall.cpp
+++ b/flang/lib/Lower/IntrinsicCall.cpp
@@ -499,6 +499,7 @@ struct IntrinsicLibrary {
   void genRandomInit(llvm::ArrayRef<fir::ExtendedValue>);
   void genRandomNumber(llvm::ArrayRef<fir::ExtendedValue>);
   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 genScale(mlir::Type, llvm::ArrayRef<mlir::Value>);
   fir::ExtendedValue genScan(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
@@ -787,6 +788,10 @@ static constexpr IntrinsicHandler handlers[]{
      &I::genRandomSeed,
      {{{"size", asBox}, {"put", asBox}, {"get", asBox}}},
      /*isElemental=*/false},
+    {"repeat",
+     &I::genRepeat,
+     {{{"string", asAddr}, {"ncopies", asValue}}},
+     /*isElemental=*/false},
     {"reshape",
      &I::genReshape,
      {{{"source", asBox},
@@ -2840,6 +2845,25 @@ void IntrinsicLibrary::genRandomSeed(llvm::ArrayRef<fir::ExtendedValue> args) {
   Fortran::lower::genRandomSeed(builder, loc, -1, mlir::Value{});
 }
 
+// REPEAT
+fir::ExtendedValue
+IntrinsicLibrary::genRepeat(mlir::Type resultType,
+                            llvm::ArrayRef<fir::ExtendedValue> args) {
+  assert(args.size() == 2);
+  mlir::Value string = builder.createBox(loc, args[0]);
+  mlir::Value ncopies = fir::getBase(args[1]);
+  // Create mutable fir.box to be passed to the runtime for the result.
+  fir::MutableBoxValue resultMutableBox =
+      fir::factory::createTempMutableBox(builder, loc, resultType);
+  mlir::Value resultIrBox =
+      fir::factory::getMutableIRBox(builder, loc, resultMutableBox);
+  // Call runtime. The runtime is allocating the result.
+  fir::runtime::genRepeat(builder, loc, resultIrBox, string, ncopies);
+  // Read result from mutable fir.box and add it to the list of temps to be
+  // finalized by the StatementContext.
+  return readAndAddCleanUp(resultMutableBox, resultType, "REPEAT");
+}
+
 // RESHAPE
 fir::ExtendedValue
 IntrinsicLibrary::genReshape(mlir::Type resultType,

diff  --git a/flang/test/Lower/Intrinsics/repeat.f90 b/flang/test/Lower/Intrinsics/repeat.f90
new file mode 100644
index 0000000000000..f6e8452634abf
--- /dev/null
+++ b/flang/test/Lower/Intrinsics/repeat.f90
@@ -0,0 +1,24 @@
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s
+
+! CHECK-LABEL: func @_QPrepeat_test(
+! CHECK-SAME: %[[arg0:.*]]: !fir.boxchar<1>{{.*}}, %[[arg1:.*]]: !fir.ref<i32>{{.*}}) {
+subroutine repeat_test(c, n)
+  character(*) :: c
+  integer :: n
+  ! CHECK: %[[tmpBox:.*]] = fir.alloca !fir.box<!fir.heap<!fir.char<1,?>>>
+  ! CHECK-DAG: %[[c:.*]]:2 = fir.unboxchar %[[arg0]] : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
+  ! CHECK-DAG: %[[ni32:.*]] = fir.load %[[arg1]] : !fir.ref<i32>
+  ! CHECK-DAG: %[[n:.*]] = fir.convert %[[ni32]] : (i32) -> i64
+  ! CHECK-DAG: %[[cBox:.*]] = fir.embox %[[c]]#0 typeparams %[[c]]#1 : (!fir.ref<!fir.char<1,?>>, index) -> !fir.box<!fir.char<1,?>>
+  ! CHECK-DAG: %[[cBoxNone:.*]] = fir.convert %[[cBox]] : (!fir.box<!fir.char<1,?>>) -> !fir.box<none>
+  ! CHECK-DAG: %[[resBox:.*]] = fir.convert %[[tmpBox]] : (!fir.ref<!fir.box<!fir.heap<!fir.char<1,?>>>>) -> !fir.ref<!fir.box<none>>
+  ! CHECK: fir.call @{{.*}}Repeat(%[[resBox]], %[[cBoxNone]], %[[n]], {{.*}}, {{.*}}) : (!fir.ref<!fir.box<none>>, !fir.box<none>, i64, !fir.ref<i8>, i32) -> none
+  ! CHECK-DAG: %[[tmpAddr:.*]] = fir.box_addr
+  ! CHECK-DAG: fir.box_elesize
+  ! CHECK: fir.call @{{.*}}bar_repeat_test
+  call bar_repeat_test(repeat(c,n))
+  ! CHECK: fir.freemem %[[tmpAddr]] : <!fir.char<1,?>>
+  return
+end subroutine
+


        


More information about the flang-commits mailing list