diff --git a/flang/lib/Lower/IntrinsicCall.cpp b/flang/lib/Lower/IntrinsicCall.cpp index b7c02e2c2cacf..d4fbf554c2de6 100644 --- a/flang/lib/Lower/IntrinsicCall.cpp +++ b/flang/lib/Lower/IntrinsicCall.cpp @@ -505,6 +505,7 @@ struct IntrinsicLibrary { void genSystemClock(llvm::ArrayRef); fir::ExtendedValue genTransfer(mlir::Type, llvm::ArrayRef); + fir::ExtendedValue genTrim(mlir::Type, llvm::ArrayRef); fir::ExtendedValue genUbound(mlir::Type, llvm::ArrayRef); fir::ExtendedValue genUnpack(mlir::Type, llvm::ArrayRef); fir::ExtendedValue genVerify(mlir::Type, llvm::ArrayRef); @@ -804,6 +805,7 @@ static constexpr IntrinsicHandler handlers[]{ &I::genTransfer, {{{"source", asAddr}, {"mold", asAddr}, {"size", asValue}}}, /*isElemental=*/false}, + {"trim", &I::genTrim, {{{"string", asAddr}}}, /*isElemental=*/false}, {"ubound", &I::genUbound, {{{"array", asBox}, {"dim", asValue}, {"kind", asValue}}}, @@ -3061,6 +3063,23 @@ IntrinsicLibrary::genUbound(mlir::Type resultType, return mlir::Value(); } +// TRIM +fir::ExtendedValue +IntrinsicLibrary::genTrim(mlir::Type resultType, + llvm::ArrayRef args) { + assert(args.size() == 1); + mlir::Value string = builder.createBox(loc, args[0]); + // 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::genTrim(builder, loc, resultIrBox, string); + // Read result from mutable fir.box and add it to the list of temps to be + // finalized by the StatementContext. + return readAndAddCleanUp(resultMutableBox, resultType, "TRIM"); +} // UNPACK fir::ExtendedValue IntrinsicLibrary::genUnpack(mlir::Type resultType, diff --git a/flang/test/Lower/Intrinsics/trim.f90 b/flang/test/Lower/Intrinsics/trim.f90 new file mode 100644 index 0000000000000..35ea606c34bfb --- /dev/null +++ b/flang/test/Lower/Intrinsics/trim.f90 @@ -0,0 +1,21 @@ +! RUN: bbc -emit-fir %s -o - | FileCheck %s +! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s + +! CHECK-LABEL: func @_QPtrim_test( +! CHECK-SAME: %[[arg0:.*]]: !fir.boxchar<1>{{.*}}) { +subroutine trim_test(c) + character(*) :: c + ! CHECK: %[[tmpBox:.*]] = fir.alloca !fir.box>> + ! CHECK-DAG: %[[c:.*]]:2 = fir.unboxchar %[[arg0]] : (!fir.boxchar<1>) -> (!fir.ref>, index) + ! 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 @{{.*}}Trim(%[[resBox]], %[[cBoxNone]], {{.*}}) : (!fir.ref>, !fir.box, !fir.ref, i32) -> none + ! CHECK-DAG: %[[tmpAddr:.*]] = fir.box_addr + ! CHECK-DAG: fir.box_elesize + ! CHECK: fir.call @{{.*}}bar_trim_test + call bar_trim_test(trim(c)) + ! CHECK: fir.freemem %[[tmpAddr]] : > + return +end subroutine +