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); void genRandomNumber(llvm::ArrayRef); void genRandomSeed(llvm::ArrayRef); + fir::ExtendedValue genRepeat(mlir::Type, llvm::ArrayRef); fir::ExtendedValue genReshape(mlir::Type, llvm::ArrayRef); mlir::Value genScale(mlir::Type, llvm::ArrayRef); fir::ExtendedValue genScan(mlir::Type, llvm::ArrayRef); @@ -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 args) { Fortran::lower::genRandomSeed(builder, loc, -1, mlir::Value{}); } +// REPEAT +fir::ExtendedValue +IntrinsicLibrary::genRepeat(mlir::Type resultType, + llvm::ArrayRef 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{{.*}}) { +subroutine repeat_test(c, n) + character(*) :: c + integer :: n + ! CHECK: %[[tmpBox:.*]] = fir.alloca !fir.box>> + ! CHECK-DAG: %[[c:.*]]:2 = fir.unboxchar %[[arg0]] : (!fir.boxchar<1>) -> (!fir.ref>, index) + ! CHECK-DAG: %[[ni32:.*]] = fir.load %[[arg1]] : !fir.ref + ! CHECK-DAG: %[[n:.*]] = fir.convert %[[ni32]] : (i32) -> i64 + ! CHECK-DAG: %[[cBox:.*]] = fir.embox %[[c]]#0 typeparams %[[c]]#1 : (!fir.ref>, index) -> !fir.box> + ! CHECK-DAG: %[[cBoxNone:.*]] = fir.convert %[[cBox]] : (!fir.box>) -> !fir.box + ! CHECK-DAG: %[[resBox:.*]] = fir.convert %[[tmpBox]] : (!fir.ref>>>) -> !fir.ref> + ! CHECK: fir.call @{{.*}}Repeat(%[[resBox]], %[[cBoxNone]], %[[n]], {{.*}}, {{.*}}) : (!fir.ref>, !fir.box, i64, !fir.ref, 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]] : > + return +end subroutine +