From c3645de20738190fb0f4e6d194f8dd45f94aebbf Mon Sep 17 00:00:00 2001 From: Jean Perier Date: Fri, 3 Feb 2023 15:02:26 +0100 Subject: [PATCH] [flang][hlfir] Handle intrinsic subroutines The code did not propagate the result optionality for subroutine. Make the result of genIntrinsicRef optional. Differential Revision: https://reviews.llvm.org/D143251 --- flang/lib/Lower/ConvertCall.cpp | 12 +++++++----- flang/test/Lower/HLFIR/intrinsic-subroutines.f90 | 14 ++++++++++++++ 2 files changed, 21 insertions(+), 5 deletions(-) create mode 100644 flang/test/Lower/HLFIR/intrinsic-subroutines.f90 diff --git a/flang/lib/Lower/ConvertCall.cpp b/flang/lib/Lower/ConvertCall.cpp index 4f1dd00..6ee6122 100644 --- a/flang/lib/Lower/ConvertCall.cpp +++ b/flang/lib/Lower/ConvertCall.cpp @@ -1057,7 +1057,7 @@ genUserCall(PreparedActualArguments &loweredActuals, /// Lower calls to intrinsic procedures with actual arguments that have been /// pre-lowered but have not yet been prepared according to the interface. -static hlfir::EntityWithAttributes genIntrinsicRefCore( +static std::optional genIntrinsicRefCore( PreparedActualArguments &loweredActuals, const Fortran::evaluate::SpecificIntrinsic &intrinsic, const Fortran::lower::IntrinsicArgumentLoweringRules *argLowering, @@ -1112,6 +1112,8 @@ static hlfir::EntityWithAttributes genIntrinsicRefCore( auto [resultExv, mustBeFreed] = Fortran::lower::genIntrinsicCall( callContext.getBuilder(), loc, intrinsic.name, scalarResultType, operands); + if (!fir::getBase(resultExv)) + return std::nullopt; hlfir::EntityWithAttributes resultEntity = extendedValueToHlfirEntity( loc, builder, resultExv, ".tmp.intrinsic_result"); // Move result into memory into an hlfir.expr since they are immutable from @@ -1371,7 +1373,7 @@ genIsPresentIfArgMaybeAbsent(mlir::Location loc, hlfir::Entity actual, } /// Lower an intrinsic procedure reference. -static hlfir::EntityWithAttributes +static std::optional genIntrinsicRef(const Fortran::evaluate::SpecificIntrinsic &intrinsic, CallContext &callContext) { mlir::Location loc = callContext.loc; @@ -1413,12 +1415,12 @@ genIntrinsicRef(const Fortran::evaluate::SpecificIntrinsic &intrinsic, .genElementalCall(loweredActuals, /*isImpure=*/!isFunction, callContext) .value(); } - hlfir::EntityWithAttributes result = + std::optional result = genIntrinsicRefCore(loweredActuals, intrinsic, argLowering, callContext); - if (result.getType().isa()) { + if (result && result->getType().isa()) { fir::FirOpBuilder *bldr = &callContext.getBuilder(); callContext.stmtCtx.attachCleanup( - [=]() { bldr->create(loc, result); }); + [=]() { bldr->create(loc, *result); }); } return result; } diff --git a/flang/test/Lower/HLFIR/intrinsic-subroutines.f90 b/flang/test/Lower/HLFIR/intrinsic-subroutines.f90 new file mode 100644 index 0000000..775c150 --- /dev/null +++ b/flang/test/Lower/HLFIR/intrinsic-subroutines.f90 @@ -0,0 +1,14 @@ +! Test lowering of intrinsic subroutines to HLFIR what matters here +! is not to test each subroutine, but to check how their +! lowering interfaces with the rest of lowering. +! RUN: bbc -emit-fir -hlfir -o - %s | FileCheck %s + +subroutine test_subroutine(x) + real :: x + call cpu_time(x) +end subroutine +! CHECK-LABEL: func.func @_QPtest_subroutine( +! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %{{.*}} +! CHECK: %[[VAL_2:.*]] = fir.call @_FortranACpuTime() fastmath : () -> f64 +! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (f64) -> f32 +! CHECK: fir.store %[[VAL_3]] to %[[VAL_1]]#1 : !fir.ref -- 2.7.4