Skip to content

Commit

Permalink
[flang][hlfir] Handle intrinsic subroutines
Browse files Browse the repository at this point in the history
The code did not propagate the result optionality for subroutine.
Make the result of genIntrinsicRef optional.

Differential Revision: https://reviews.llvm.org/D143251
  • Loading branch information
jeanPerier committed Feb 3, 2023
1 parent 8998fa6 commit c3645de
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 5 deletions.
12 changes: 7 additions & 5 deletions flang/lib/Lower/ConvertCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<hlfir::EntityWithAttributes> genIntrinsicRefCore(
PreparedActualArguments &loweredActuals,
const Fortran::evaluate::SpecificIntrinsic &intrinsic,
const Fortran::lower::IntrinsicArgumentLoweringRules *argLowering,
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -1371,7 +1373,7 @@ genIsPresentIfArgMaybeAbsent(mlir::Location loc, hlfir::Entity actual,
}

/// Lower an intrinsic procedure reference.
static hlfir::EntityWithAttributes
static std::optional<hlfir::EntityWithAttributes>
genIntrinsicRef(const Fortran::evaluate::SpecificIntrinsic &intrinsic,
CallContext &callContext) {
mlir::Location loc = callContext.loc;
Expand Down Expand Up @@ -1413,12 +1415,12 @@ genIntrinsicRef(const Fortran::evaluate::SpecificIntrinsic &intrinsic,
.genElementalCall(loweredActuals, /*isImpure=*/!isFunction, callContext)
.value();
}
hlfir::EntityWithAttributes result =
std::optional<hlfir::EntityWithAttributes> result =
genIntrinsicRefCore(loweredActuals, intrinsic, argLowering, callContext);
if (result.getType().isa<hlfir::ExprType>()) {
if (result && result->getType().isa<hlfir::ExprType>()) {
fir::FirOpBuilder *bldr = &callContext.getBuilder();
callContext.stmtCtx.attachCleanup(
[=]() { bldr->create<hlfir::DestroyOp>(loc, result); });
[=]() { bldr->create<hlfir::DestroyOp>(loc, *result); });
}
return result;
}
Expand Down
14 changes: 14 additions & 0 deletions flang/test/Lower/HLFIR/intrinsic-subroutines.f90
Original file line number Diff line number Diff line change
@@ -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<contract> : () -> f64
! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (f64) -> f32
! CHECK: fir.store %[[VAL_3]] to %[[VAL_1]]#1 : !fir.ref<f32>

0 comments on commit c3645de

Please sign in to comment.