[flang] emit declare for function result before call (#177615)
This change moves the declare of result storage alloca before the call so that alias analysis can revert to linking fir.declare to the fisrt dominating dummy_scope instead of the dominating one. This is only relevant when MLIR inlining is enabled and is the first step to fix issues recent TBAA changes that placed target data in its own tree exposed an issue with the result storage of a TARGET result. After inlining, the usages of the result storage inside the callee and after the call ended-up being placed in different nodes (target and non target) of the same TBAA tree (for the dominating function). The fact that both nodes are placed in the same tree stems from https://github.com/llvm/llvm-project/pull/146006 that fixed another TBAA issue related to MLIR inlining and function result where the function result was placed into the wrong TBAA tree, which with nested inlining could end-up being the tree of a callee where the result storage was a dummy, causing the TBAA to wrongfully tell that any access to the result storage inside the nested callee did not alias with any access after the call. By moving the declare before the call that will be inlined, this patch will allow reverting #146006 and fixing both issues: the TBAA emit for usages of the result storage after the call will always be placed in a different TBAA tree than any usages of the result storage inside the callee.
This commit is contained in:
parent
4848313824
commit
45102be5e5
@ -21,6 +21,7 @@
|
||||
#include "flang/Lower/CallInterface.h"
|
||||
#include "flang/Optimizer/Builder/HLFIRTools.h"
|
||||
#include <optional>
|
||||
#include <tuple>
|
||||
|
||||
namespace Fortran::lower {
|
||||
|
||||
@ -37,7 +38,7 @@ using LoweredResult =
|
||||
/// It is only used for HLFIR.
|
||||
/// The returned boolean indicates if finalization has been emitted in
|
||||
/// \p stmtCtx for the result.
|
||||
std::pair<LoweredResult, bool> genCallOpAndResult(
|
||||
std::tuple<LoweredResult, bool, mlir::Operation *> genCallOpAndResult(
|
||||
mlir::Location loc, Fortran::lower::AbstractConverter &converter,
|
||||
Fortran::lower::SymMap &symMap, Fortran::lower::StatementContext &stmtCtx,
|
||||
Fortran::lower::CallerInterface &caller, mlir::FunctionType callSiteType,
|
||||
|
||||
@ -342,7 +342,7 @@ getTypeWithIgnoreTkrC(mlir::FunctionType funcType,
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::pair<Fortran::lower::LoweredResult, bool>
|
||||
std::tuple<Fortran::lower::LoweredResult, bool, mlir::Operation *>
|
||||
Fortran::lower::genCallOpAndResult(
|
||||
mlir::Location loc, Fortran::lower::AbstractConverter &converter,
|
||||
Fortran::lower::SymMap &symMap, Fortran::lower::StatementContext &stmtCtx,
|
||||
@ -351,6 +351,7 @@ Fortran::lower::genCallOpAndResult(
|
||||
fir::FirOpBuilder &builder = converter.getFirOpBuilder();
|
||||
using PassBy = Fortran::lower::CallerInterface::PassEntityBy;
|
||||
bool mustPopSymMap = false;
|
||||
mlir::Operation *callOp = nullptr;
|
||||
|
||||
llvm::SmallVector<mlir::Value> resultLengths;
|
||||
if (isElemental)
|
||||
@ -713,10 +714,10 @@ Fortran::lower::genCallOpAndResult(
|
||||
}
|
||||
}
|
||||
|
||||
cuf::KernelLaunchOp::create(builder, loc, funcType.getResults(),
|
||||
funcSymbolAttr, grid_x, grid_y, grid_z, block_x,
|
||||
block_y, block_z, bytes, stream, operands,
|
||||
/*arg_attrs=*/nullptr, /*res_attrs=*/nullptr);
|
||||
callOp = cuf::KernelLaunchOp::create(
|
||||
builder, loc, funcType.getResults(), funcSymbolAttr, grid_x, grid_y,
|
||||
grid_z, block_x, block_y, block_z, bytes, stream, operands,
|
||||
/*arg_attrs=*/nullptr, /*res_attrs=*/nullptr);
|
||||
callNumResults = 0;
|
||||
} else if (caller.requireDispatchCall()) {
|
||||
// Procedure call requiring a dynamic dispatch. Call is created with
|
||||
@ -748,6 +749,7 @@ Fortran::lower::genCallOpAndResult(
|
||||
passActual, operands, builder.getI32IntegerAttr(*passArg),
|
||||
/*arg_attrs=*/nullptr,
|
||||
/*res_attrs=*/nullptr, procAttrs);
|
||||
callOp = dispatch;
|
||||
} else {
|
||||
// NOPASS
|
||||
const Fortran::evaluate::Component *component =
|
||||
@ -764,6 +766,7 @@ Fortran::lower::genCallOpAndResult(
|
||||
builder, loc, funcType.getResults(), builder.getStringAttr(procName),
|
||||
passObject, operands, nullptr, /*arg_attrs=*/nullptr,
|
||||
/*res_attrs=*/nullptr, procAttrs);
|
||||
callOp = dispatch;
|
||||
}
|
||||
callNumResults = dispatch.getNumResults();
|
||||
if (callNumResults != 0)
|
||||
@ -785,6 +788,7 @@ Fortran::lower::genCallOpAndResult(
|
||||
builder, loc, funcType.getResults(), funcSymbolAttr, operands,
|
||||
/*arg_attrs=*/nullptr, /*res_attrs=*/nullptr, procAttrs, inlineAttr,
|
||||
/*accessGroups=*/mlir::ArrayAttr{});
|
||||
callOp = call;
|
||||
|
||||
callNumResults = call.getNumResults();
|
||||
if (callNumResults != 0)
|
||||
@ -821,7 +825,7 @@ Fortran::lower::genCallOpAndResult(
|
||||
/*finalize=*/mustFinalizeResult);
|
||||
});
|
||||
return {LoweredResult{hlfir::EntityWithAttributes{expr}},
|
||||
mustFinalizeResult};
|
||||
mustFinalizeResult, callOp};
|
||||
}
|
||||
|
||||
if (allocatedResult) {
|
||||
@ -880,13 +884,13 @@ Fortran::lower::genCallOpAndResult(
|
||||
}
|
||||
}
|
||||
}
|
||||
return {LoweredResult{*allocatedResult}, resultIsFinalized};
|
||||
return {LoweredResult{*allocatedResult}, resultIsFinalized, callOp};
|
||||
}
|
||||
|
||||
// subroutine call
|
||||
if (!resultType)
|
||||
return {LoweredResult{fir::ExtendedValue{mlir::Value{}}},
|
||||
/*resultIsFinalized=*/false};
|
||||
/*resultIsFinalized=*/false, callOp};
|
||||
|
||||
// For now, Fortran return values are implemented with a single MLIR
|
||||
// function return value.
|
||||
@ -902,11 +906,11 @@ Fortran::lower::genCallOpAndResult(
|
||||
loc, builder.getCharacterLengthType(), charTy.getLen());
|
||||
return {
|
||||
LoweredResult{fir::ExtendedValue{fir::CharBoxValue{callResult, len}}},
|
||||
/*resultIsFinalized=*/false};
|
||||
/*resultIsFinalized=*/false, callOp};
|
||||
}
|
||||
|
||||
return {LoweredResult{fir::ExtendedValue{callResult}},
|
||||
/*resultIsFinalized=*/false};
|
||||
/*resultIsFinalized=*/false, callOp};
|
||||
}
|
||||
|
||||
static hlfir::EntityWithAttributes genStmtFunctionRef(
|
||||
@ -1050,8 +1054,8 @@ using ExvAndCleanup =
|
||||
// Helper to transform a fir::ExtendedValue to an hlfir::EntityWithAttributes.
|
||||
static hlfir::EntityWithAttributes
|
||||
extendedValueToHlfirEntity(mlir::Location loc, fir::FirOpBuilder &builder,
|
||||
const fir::ExtendedValue &exv,
|
||||
llvm::StringRef name) {
|
||||
const fir::ExtendedValue &exv, llvm::StringRef name,
|
||||
mlir::Operation *insertBefore = nullptr) {
|
||||
mlir::Value firBase = fir::getBase(exv);
|
||||
mlir::Type firBaseTy = firBase.getType();
|
||||
if (fir::isa_trivial(firBaseTy))
|
||||
@ -1073,8 +1077,26 @@ extendedValueToHlfirEntity(mlir::Location loc, fir::FirOpBuilder &builder,
|
||||
builder, loc, storage, /*mustFree=*/builder.createBool(loc, false));
|
||||
return hlfir::EntityWithAttributes{asExpr.getResult()};
|
||||
}
|
||||
return hlfir::genDeclare(loc, builder, exv, name,
|
||||
fir::FortranVariableFlagsAttr{});
|
||||
// TODO: better scoping model in FIR.
|
||||
// The declare for result storage allocated on the callee side must
|
||||
// currently be emitted before the call so that MLIR level inlining does not
|
||||
// break aliasing by introducing a fir.dummy_scope between the alloca and
|
||||
// fir.declare that leads the alias analysis to think that the result
|
||||
// allocation is a local inside the callee scope that cannot alias with the
|
||||
// usage of that temporary inside the callee because they are made through a
|
||||
// declare with the TARGET attribute.
|
||||
mlir::OpBuilder::InsertionGuard guard(builder);
|
||||
if (insertBefore)
|
||||
builder.setInsertionPoint(insertBefore);
|
||||
hlfir::EntityWithAttributes declare = hlfir::genDeclare(
|
||||
loc, builder, exv, name, fir::FortranVariableFlagsAttr{});
|
||||
// Replace the fir.save_result "to" by the declare results instead of
|
||||
// directly using the alloca.
|
||||
if (insertBefore && insertBefore->getNumResults() == 1)
|
||||
for (auto resUser : insertBefore->getResult(0).getUsers())
|
||||
if (auto save_result = llvm::dyn_cast<fir::SaveResultOp>(resUser))
|
||||
save_result.getMemrefMutable().assign(declare.getFirBase());
|
||||
return declare;
|
||||
}
|
||||
namespace {
|
||||
/// Structure to hold the clean-up related to a dummy argument preparation
|
||||
@ -1909,10 +1931,11 @@ genUserCall(Fortran::lower::PreparedActualArguments &loweredActuals,
|
||||
// Prepare lowered arguments according to the interface
|
||||
// and map the lowered values to the dummy
|
||||
// arguments.
|
||||
auto [loweredResult, resultIsFinalized] = Fortran::lower::genCallOpAndResult(
|
||||
loc, callContext.converter, callContext.symMap, callContext.stmtCtx,
|
||||
caller, callSiteType, callContext.resultType,
|
||||
callContext.isElementalProcWithArrayArgs());
|
||||
auto [loweredResult, resultIsFinalized, callOp] =
|
||||
Fortran::lower::genCallOpAndResult(
|
||||
loc, callContext.converter, callContext.symMap, callContext.stmtCtx,
|
||||
caller, callSiteType, callContext.resultType,
|
||||
callContext.isElementalProcWithArrayArgs());
|
||||
|
||||
// Clean-up associations and copy-in.
|
||||
// The association clean-ups are postponed to the end of the statement
|
||||
@ -1948,8 +1971,8 @@ genUserCall(Fortran::lower::PreparedActualArguments &loweredActuals,
|
||||
return extendedValueToHlfirEntity(loc, builder, result, tempResultName);
|
||||
|
||||
if (!resultIsFinalized) {
|
||||
hlfir::Entity resultEntity =
|
||||
extendedValueToHlfirEntity(loc, builder, result, tempResultName);
|
||||
hlfir::Entity resultEntity = extendedValueToHlfirEntity(
|
||||
loc, builder, result, tempResultName, /*insertBefore=*/callOp);
|
||||
resultEntity = loadTrivialScalar(loc, builder, resultEntity);
|
||||
if (resultEntity.isVariable()) {
|
||||
// If the result has no finalization, it can be moved into an expression.
|
||||
@ -1981,7 +2004,9 @@ genUserCall(Fortran::lower::PreparedActualArguments &loweredActuals,
|
||||
/*mayBePolymorphic=*/true,
|
||||
/*preserveLowerBounds=*/false)
|
||||
: result;
|
||||
return extendedValueToHlfirEntity(loc, builder, loadedResult, tempResultName);
|
||||
return extendedValueToHlfirEntity(
|
||||
loc, builder, loadedResult, tempResultName,
|
||||
/*insertBefore=*/!allocatable ? callOp : nullptr);
|
||||
}
|
||||
|
||||
/// Create an optional dummy argument value from an entity that may be
|
||||
|
||||
@ -2907,10 +2907,8 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
auto loweredResult =
|
||||
Fortran::lower::genCallOpAndResult(loc, converter, symMap, stmtCtx,
|
||||
caller, callSiteType, resultType)
|
||||
.first;
|
||||
auto loweredResult = std::get<0>(Fortran::lower::genCallOpAndResult(
|
||||
loc, converter, symMap, stmtCtx, caller, callSiteType, resultType));
|
||||
auto &result = std::get<ExtValue>(loweredResult);
|
||||
|
||||
// Sync pointers and allocatables that may have been modified during the
|
||||
@ -4946,10 +4944,9 @@ private:
|
||||
caller.placeInput(argIface, arg);
|
||||
}
|
||||
Fortran::lower::LoweredResult res =
|
||||
Fortran::lower::genCallOpAndResult(loc, converter, symMap,
|
||||
getElementCtx(), caller,
|
||||
callSiteType, retTy)
|
||||
.first;
|
||||
std::get<0>(Fortran::lower::genCallOpAndResult(
|
||||
loc, converter, symMap, getElementCtx(), caller, callSiteType,
|
||||
retTy));
|
||||
return std::get<ExtValue>(res);
|
||||
};
|
||||
}
|
||||
|
||||
@ -164,8 +164,8 @@ end subroutine
|
||||
! CHECK: %[[VAL_10:.*]] = arith.cmpi sgt, %[[VAL_8]], %[[VAL_9]] : index
|
||||
! CHECK: %[[VAL_11:.*]] = arith.select %[[VAL_10]], %[[VAL_8]], %[[VAL_9]] : index
|
||||
! CHECK: %[[VAL_13:.*]] = fir.alloca !fir.char<1,?>(%[[VAL_11]] : index) {bindc_name = ".result"}
|
||||
! CHECK: %[[VAL_14:.*]] = fir.call @_QPc2foo(%[[VAL_13]], %[[VAL_11]]) fastmath<contract> : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
|
||||
! CHECK: %[[VAL_15:.*]]:2 = hlfir.declare %[[VAL_13]] typeparams %[[VAL_11]] {uniq_name = ".tmp.func_result"} : (!fir.ref<!fir.char<1,?>>, index) -> (!fir.boxchar<1>, !fir.ref<!fir.char<1,?>>)
|
||||
! CHECK: %[[VAL_14:.*]] = fir.call @_QPc2foo(%[[VAL_13]], %[[VAL_11]]) fastmath<contract> : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
|
||||
|
||||
! -----------------------------------------------------------------------------
|
||||
! Test calls with alternate returns
|
||||
|
||||
@ -177,8 +177,8 @@ end subroutine char_return
|
||||
! CHECK: ^bb0(%[[VAL_18:.*]]: index):
|
||||
! CHECK: %[[VAL_19:.*]] = hlfir.designate %[[VAL_12]]#0 (%[[VAL_18]]) typeparams %[[VAL_11]] : (!fir.box<!fir.array<?x!fir.char<1,3>>>, index, index) -> !fir.ref<!fir.char<1,3>>
|
||||
! CHECK: %[[VAL_20:.*]] = fir.emboxchar %[[VAL_19]], %[[VAL_11]] : (!fir.ref<!fir.char<1,3>>, index) -> !fir.boxchar<1>
|
||||
! CHECK: %[[VAL_27:.*]] = fir.call @_QPcallee(%[[VAL_2]], %[[VAL_16]], %[[VAL_20]]) proc_attrs<elemental, pure> fastmath<contract> : (!fir.ref<!fir.char<1,3>>, index, !fir.boxchar<1>) -> !fir.boxchar<1>
|
||||
! CHECK: %[[VAL_28:.*]]:2 = hlfir.declare %[[VAL_2]] typeparams %[[VAL_16]] {uniq_name = ".tmp.func_result"} : (!fir.ref<!fir.char<1,3>>, index) -> (!fir.ref<!fir.char<1,3>>, !fir.ref<!fir.char<1,3>>)
|
||||
! CHECK: %[[VAL_27:.*]] = fir.call @_QPcallee(%[[VAL_2]], %[[VAL_16]], %[[VAL_20]]) proc_attrs<elemental, pure> fastmath<contract> : (!fir.ref<!fir.char<1,3>>, index, !fir.boxchar<1>) -> !fir.boxchar<1>
|
||||
! CHECK: %[[MustFree:.*]] = arith.constant false
|
||||
! CHECK: %[[ResultTemp:.*]] = hlfir.as_expr %[[VAL_28]]#0 move %[[MustFree]] : (!fir.ref<!fir.char<1,3>>, i1) -> !hlfir.expr<!fir.char<1,3>>
|
||||
! CHECK: hlfir.yield_element %[[ResultTemp]] : !hlfir.expr<!fir.char<1,3>>
|
||||
|
||||
@ -76,9 +76,9 @@ end subroutine
|
||||
! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?x!fir.logical<4>>>> {bindc_name = ".result"}
|
||||
! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare {{.*}}Ex
|
||||
! CHECK: hlfir.where {
|
||||
! CHECK: %[[VAL_6:.*]] = fir.call @_QPreturn_temporary_mask() fastmath<contract> : () -> !fir.box<!fir.heap<!fir.array<?x!fir.logical<4>>>>
|
||||
! CHECK: fir.save_result %[[VAL_6]] to %[[VAL_1]] : !fir.box<!fir.heap<!fir.array<?x!fir.logical<4>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.logical<4>>>>>
|
||||
! CHECK: %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_1]] {uniq_name = ".tmp.func_result"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.logical<4>>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.logical<4>>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.logical<4>>>>>)
|
||||
! CHECK: %[[VAL_6:.*]] = fir.call @_QPreturn_temporary_mask() fastmath<contract> : () -> !fir.box<!fir.heap<!fir.array<?x!fir.logical<4>>>>
|
||||
! CHECK: fir.save_result %[[VAL_6]] to %[[VAL_7]]#0 : !fir.box<!fir.heap<!fir.array<?x!fir.logical<4>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.logical<4>>>>>
|
||||
! CHECK: %[[deref:.*]] = fir.load %[[VAL_7]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.logical<4>>>>>
|
||||
! CHECK: %[[MustFree:.*]] = arith.constant false
|
||||
! CHECK: %[[ResTemp:.*]] = hlfir.as_expr %[[deref]] move %[[MustFree]] : (!fir.box<!fir.heap<!fir.array<?x!fir.logical<4>>>>, i1) -> !hlfir.expr<?x!fir.logical<4>>
|
||||
@ -87,9 +87,9 @@ end subroutine
|
||||
! CHECK: }
|
||||
! CHECK: } do {
|
||||
! CHECK: hlfir.region_assign {
|
||||
! CHECK: %[[VAL_14:.*]] = fir.call @_QPreturn_temporary_array() fastmath<contract> : () -> !fir.box<!fir.heap<!fir.array<?xf32>>>
|
||||
! CHECK: fir.save_result %[[VAL_14]] to %[[VAL_0]] : !fir.box<!fir.heap<!fir.array<?xf32>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
|
||||
! CHECK: %[[VAL_15:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = ".tmp.func_result"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>)
|
||||
! CHECK: %[[VAL_14:.*]] = fir.call @_QPreturn_temporary_array() fastmath<contract> : () -> !fir.box<!fir.heap<!fir.array<?xf32>>>
|
||||
! CHECK: fir.save_result %[[VAL_14]] to %[[VAL_15]]#0 : !fir.box<!fir.heap<!fir.array<?xf32>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
|
||||
! CHECK: %[[deref:.*]] = fir.load %[[VAL_15]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
|
||||
! CHECK: %[[MustFree:.*]] = arith.constant false
|
||||
! CHECK: %[[ResTemp:.*]] = hlfir.as_expr %[[deref]] move %[[MustFree]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>, i1) -> !hlfir.expr<?xf32>
|
||||
|
||||
@ -11,8 +11,8 @@ subroutine test_storage_size(n)
|
||||
end interface
|
||||
integer n
|
||||
print*, storage_size(return_char(n))
|
||||
! CHECK: %[[val_16:.*]] = fir.call @_QPreturn_char(%[[res_addr:[^,]*]], %[[res_len:[^,]*]], {{.*}})
|
||||
! CHECK: %[[res:.*]]:2 = hlfir.declare %[[res_addr]] typeparams %[[res_len]]
|
||||
! CHECK: %[[res:.*]]:2 = hlfir.declare %[[res_addr:[^,]*]] typeparams %[[res_len:[^ ]*]]
|
||||
! CHECK: %[[val_16:.*]] = fir.call @_QPreturn_char(%[[res_addr]], %[[res_len]], {{.*}})
|
||||
! CHECK: %[[false:.*]] = arith.constant false
|
||||
! CHECK: %[[expr:.*]] = hlfir.as_expr %[[res]]#0 move %[[false]] : (!fir.boxchar<1>, i1) -> !hlfir.expr<!fir.char<1,?>>
|
||||
! CHECK: %[[assoc:.*]]:3 = hlfir.associate %[[expr]] typeparams %[[res_len]] {adapt.valuebyref} : (!hlfir.expr<!fir.char<1,?>>, index) -> (!fir.boxchar<1>, !fir.ref<!fir.char<1,?>>, i1)
|
||||
|
||||
@ -61,9 +61,9 @@ end module maxtype_mod
|
||||
!CHECK: %[[OMP_IN_DECL:.*]]:2 = hlfir.declare %[[OMP_IN]] {uniq_name = "omp_in"} : (!fir.ref<[[MAXTYPE]]>) -> (!fir.ref<[[MAXTYPE]]>, !fir.ref<[[MAXTYPE]]>)
|
||||
!CHECK: fir.store %[[LHS_ARG]] to %[[OMP_OUT]] : !fir.ref<[[MAXTYPE]]>
|
||||
!CHECK: %[[OMP_OUT_DECL:.*]]:2 = hlfir.declare %[[OMP_OUT]] {uniq_name = "omp_out"} : (!fir.ref<[[MAXTYPE]]>) -> (!fir.ref<[[MAXTYPE]]>, !fir.ref<[[MAXTYPE]]>)
|
||||
!CHECK: %[[COMBINE_RESULT:.*]] = fir.call @_QMmaxtype_modPmycombine(%[[OMP_OUT_DECL]]#0, %[[OMP_IN_DECL]]#0) fastmath<contract> : (!fir.ref<[[MAXTYPE]]>, !fir.ref<[[MAXTYPE]]>) -> [[MAXTYPE]]
|
||||
!CHECK: fir.save_result %[[COMBINE_RESULT]] to %[[RESULT]] : [[MAXTYPE]], !fir.ref<[[MAXTYPE]]>
|
||||
!CHECK: %[[TMPRESULT:.*]]:2 = hlfir.declare %[[RESULT]] {uniq_name = ".tmp.func_result"} : (!fir.ref<[[MAXTYPE]]>) -> (!fir.ref<[[MAXTYPE]]>, !fir.ref<[[MAXTYPE]]>)
|
||||
!CHECK: %[[COMBINE_RESULT:.*]] = fir.call @_QMmaxtype_modPmycombine(%[[OMP_OUT_DECL]]#0, %[[OMP_IN_DECL]]#0) fastmath<contract> : (!fir.ref<[[MAXTYPE]]>, !fir.ref<[[MAXTYPE]]>) -> [[MAXTYPE]]
|
||||
!CHECK: fir.save_result %[[COMBINE_RESULT]] to %[[TMPRESULT]]#0 : [[MAXTYPE]], !fir.ref<[[MAXTYPE]]>
|
||||
!CHECK: %false = arith.constant false
|
||||
!CHECK: %[[EXPRRESULT:.*]] = hlfir.as_expr %[[TMPRESULT]]#0 move %false : (!fir.ref<[[MAXTYPE]]>, i1) -> !hlfir.expr<[[MAXTYPE]]>
|
||||
!CHECK: %[[ASSOCIATE:.*]]:3 = hlfir.associate %[[EXPRRESULT]] {adapt.valuebyref} : (!hlfir.expr<[[MAXTYPE]]>) -> (!fir.ref<[[MAXTYPE]]>, !fir.ref<[[MAXTYPE]]>, i1)
|
||||
|
||||
@ -39,8 +39,8 @@ end subroutine
|
||||
! CHECK: %[[VAL_18:.*]] = fir.load %[[VAL_17]] : !fir.ref<i64>
|
||||
! CHECK: %[[VAL_19:.*]] = hlfir.designate %[[VAL_1]]#0 (%[[VAL_18]]) typeparams %[[VAL_3]] : (!fir.box<!fir.array<?x!fir.char<1,?>>>, i64, index) -> !fir.boxchar<1>
|
||||
! CHECK: %[[VAL_20:.*]] = fir.alloca !fir.char<1,?>(%[[VAL_14]] : index) {bindc_name = ".result"}
|
||||
! CHECK: %[[VAL_21:.*]] = fir.call @_QPbug_145151_1(%[[VAL_20]], %[[VAL_14]], %[[VAL_19]]) proc_attrs<elemental, pure> fastmath<contract> : (!fir.ref<!fir.char<1,?>>, index, !fir.boxchar<1>) -> !fir.boxchar<1>
|
||||
! CHECK: %[[VAL_22:.*]]:2 = hlfir.declare %[[VAL_20]] typeparams %[[VAL_14]] {uniq_name = ".tmp.func_result"} : (!fir.ref<!fir.char<1,?>>, index) -> (!fir.boxchar<1>, !fir.ref<!fir.char<1,?>>)
|
||||
! CHECK: %[[VAL_21:.*]] = fir.call @_QPbug_145151_1(%[[VAL_20]], %[[VAL_14]], %[[VAL_19]]) proc_attrs<elemental, pure> fastmath<contract> : (!fir.ref<!fir.char<1,?>>, index, !fir.boxchar<1>) -> !fir.boxchar<1>
|
||||
! CHECK: %[[VAL_23:.*]] = arith.constant false
|
||||
! CHECK: %[[VAL_24:.*]] = hlfir.as_expr %[[VAL_22]]#0 move %[[VAL_23]] : (!fir.boxchar<1>, i1) -> !hlfir.expr<!fir.char<1,?>>
|
||||
! CHECK: hlfir.yield_element %[[VAL_24]] : !hlfir.expr<!fir.char<1,?>>
|
||||
@ -97,8 +97,8 @@ end subroutine
|
||||
! CHECK: %[[VAL_15:.*]] = hlfir.designate %[[VAL_2]]#0 (%[[VAL_14]]) : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
|
||||
! CHECK: %[[VAL_16:.*]] = fir.load %[[VAL_15]] : !fir.ref<f32>
|
||||
! CHECK: %[[VAL_17:.*]] = fir.alloca !fir.char<1,?>(%[[VAL_12]] : index) {bindc_name = ".result"}
|
||||
! CHECK: %[[VAL_18:.*]] = fir.call @_QPbug_145151_2(%[[VAL_17]], %[[VAL_12]], %[[VAL_16]]) proc_attrs<elemental, pure> fastmath<contract> : (!fir.ref<!fir.char<1,?>>, index, f32) -> !fir.boxchar<1>
|
||||
! CHECK: %[[VAL_19:.*]]:2 = hlfir.declare %[[VAL_17]] typeparams %[[VAL_12]] {uniq_name = ".tmp.func_result"} : (!fir.ref<!fir.char<1,?>>, index) -> (!fir.boxchar<1>, !fir.ref<!fir.char<1,?>>)
|
||||
! CHECK: %[[VAL_18:.*]] = fir.call @_QPbug_145151_2(%[[VAL_17]], %[[VAL_12]], %[[VAL_16]]) proc_attrs<elemental, pure> fastmath<contract> : (!fir.ref<!fir.char<1,?>>, index, f32) -> !fir.boxchar<1>
|
||||
! CHECK: %[[VAL_20:.*]] = arith.constant false
|
||||
! CHECK: %[[VAL_21:.*]] = hlfir.as_expr %[[VAL_19]]#0 move %[[VAL_20]] : (!fir.boxchar<1>, i1) -> !hlfir.expr<!fir.char<1,?>>
|
||||
! CHECK: hlfir.yield_element %[[VAL_21]] : !hlfir.expr<!fir.char<1,?>>
|
||||
@ -165,8 +165,8 @@ end subroutine
|
||||
! CHECK: fir.result %[[VAL_27]] : !fir.ref<f32>
|
||||
! CHECK: }
|
||||
! CHECK: %[[VAL_28:.*]] = fir.alloca !fir.char<1,?>(%[[VAL_21]] : index) {bindc_name = ".result"}
|
||||
! CHECK: %[[VAL_29:.*]] = fir.call @_QPf_opt(%[[VAL_28]], %[[VAL_21]], %[[VAL_24]], %[[VAL_25]]) proc_attrs<elemental, pure> fastmath<contract> : (!fir.ref<!fir.char<1,?>>, index, !fir.ref<f32>, !fir.ref<f32>) -> !fir.boxchar<1>
|
||||
! CHECK: %[[VAL_30:.*]]:2 = hlfir.declare %[[VAL_28]] typeparams %[[VAL_21]] {uniq_name = ".tmp.func_result"} : (!fir.ref<!fir.char<1,?>>, index) -> (!fir.boxchar<1>, !fir.ref<!fir.char<1,?>>)
|
||||
! CHECK: %[[VAL_29:.*]] = fir.call @_QPf_opt(%[[VAL_28]], %[[VAL_21]], %[[VAL_24]], %[[VAL_25]]) proc_attrs<elemental, pure> fastmath<contract> : (!fir.ref<!fir.char<1,?>>, index, !fir.ref<f32>, !fir.ref<f32>) -> !fir.boxchar<1>
|
||||
! CHECK: %[[VAL_31:.*]] = arith.constant false
|
||||
! CHECK: %[[VAL_32:.*]] = hlfir.as_expr %[[VAL_30]]#0 move %[[VAL_31]] : (!fir.boxchar<1>, i1) -> !hlfir.expr<!fir.char<1,?>>
|
||||
! CHECK: hlfir.yield_element %[[VAL_32]] : !hlfir.expr<!fir.char<1,?>>
|
||||
@ -231,8 +231,8 @@ end subroutine
|
||||
! CHECK: %[[VAL_32:.*]] = hlfir.designate %[[VAL_1]]#0 (%[[VAL_31]]) : (!fir.class<!fir.array<?x!fir.type<_QFtest_polymorphicTt>>>, index) -> !fir.class<!fir.type<_QFtest_polymorphicTt>>
|
||||
! CHECK: %[[VAL_33:.*]] = hlfir.designate %[[VAL_2]]#0 (%[[VAL_31]]) : (!fir.class<!fir.array<?x!fir.type<_QFtest_polymorphicTt>>>, index) -> !fir.class<!fir.type<_QFtest_polymorphicTt>>
|
||||
! CHECK: %[[VAL_34:.*]] = fir.alloca !fir.char<1,?>(%[[VAL_29]] : index) {bindc_name = ".result"}
|
||||
! CHECK: %[[VAL_35:.*]] = fir.call @_QPf_poly(%[[VAL_34]], %[[VAL_29]], %[[VAL_32]], %[[VAL_33]]) proc_attrs<elemental, pure> fastmath<contract> : (!fir.ref<!fir.char<1,?>>, index, !fir.class<!fir.type<_QFtest_polymorphicTt>>, !fir.class<!fir.type<_QFtest_polymorphicTt>>) -> !fir.boxchar<1>
|
||||
! CHECK: %[[VAL_36:.*]]:2 = hlfir.declare %[[VAL_34]] typeparams %[[VAL_29]] {uniq_name = ".tmp.func_result"} : (!fir.ref<!fir.char<1,?>>, index) -> (!fir.boxchar<1>, !fir.ref<!fir.char<1,?>>)
|
||||
! CHECK: %[[VAL_35:.*]] = fir.call @_QPf_poly(%[[VAL_34]], %[[VAL_29]], %[[VAL_32]], %[[VAL_33]]) proc_attrs<elemental, pure> fastmath<contract> : (!fir.ref<!fir.char<1,?>>, index, !fir.class<!fir.type<_QFtest_polymorphicTt>>, !fir.class<!fir.type<_QFtest_polymorphicTt>>) -> !fir.boxchar<1>
|
||||
! CHECK: %[[VAL_37:.*]] = arith.constant false
|
||||
! CHECK: %[[VAL_38:.*]] = hlfir.as_expr %[[VAL_36]]#0 move %[[VAL_37]] : (!fir.boxchar<1>, i1) -> !hlfir.expr<!fir.char<1,?>>
|
||||
! CHECK: hlfir.yield_element %[[VAL_38]] : !hlfir.expr<!fir.char<1,?>>
|
||||
@ -278,8 +278,8 @@ end subroutine
|
||||
! CHECK: %[[VAL_18:.*]] = hlfir.as_expr %[[VAL_17]] : (!fir.boxchar<1>) -> !hlfir.expr<!fir.char<1,?>>
|
||||
! CHECK: %[[VAL_19:.*]]:3 = hlfir.associate %[[VAL_18]] typeparams %[[VAL_16]] {adapt.valuebyref} : (!hlfir.expr<!fir.char<1,?>>, index) -> (!fir.boxchar<1>, !fir.ref<!fir.char<1,?>>, i1)
|
||||
! CHECK: %[[VAL_20:.*]] = fir.alloca !fir.char<1,?>(%[[VAL_13]] : index) {bindc_name = ".result"}
|
||||
! CHECK: %[[VAL_21:.*]] = fir.call @_QPf_value(%[[VAL_20]], %[[VAL_13]], %[[VAL_19]]#0) proc_attrs<elemental, pure> fastmath<contract> : (!fir.ref<!fir.char<1,?>>, index, !fir.boxchar<1>) -> !fir.boxchar<1>
|
||||
! CHECK: %[[VAL_22:.*]]:2 = hlfir.declare %[[VAL_20]] typeparams %[[VAL_13]] {uniq_name = ".tmp.func_result"} : (!fir.ref<!fir.char<1,?>>, index) -> (!fir.boxchar<1>, !fir.ref<!fir.char<1,?>>)
|
||||
! CHECK: %[[VAL_21:.*]] = fir.call @_QPf_value(%[[VAL_20]], %[[VAL_13]], %[[VAL_19]]#0) proc_attrs<elemental, pure> fastmath<contract> : (!fir.ref<!fir.char<1,?>>, index, !fir.boxchar<1>) -> !fir.boxchar<1>
|
||||
! CHECK: %[[VAL_23:.*]] = arith.constant false
|
||||
! CHECK: %[[VAL_24:.*]] = hlfir.as_expr %[[VAL_22]]#0 move %[[VAL_23]] : (!fir.boxchar<1>, i1) -> !hlfir.expr<!fir.char<1,?>>
|
||||
! CHECK: hlfir.end_associate %[[VAL_19]]#1, %[[VAL_19]]#2 : !fir.ref<!fir.char<1,?>>, i1
|
||||
|
||||
@ -253,8 +253,8 @@ end subroutine
|
||||
! CHECK: ^bb0(%[[VAL_17:.*]]: index):
|
||||
! CHECK: %[[VAL_18:.*]] = hlfir.designate %[[VAL_6]]#0 (%[[VAL_17]]) typeparams %[[VAL_2]]#1 : (!fir.box<!fir.array<10x!fir.char<1,?>>>, index, index) -> !fir.boxchar<1>
|
||||
! CHECK: %[[VAL_28:.*]] = fir.alloca !fir.char<1,?>(%[[VAL_15]] : index) {bindc_name = ".result"}
|
||||
! CHECK: %[[VAL_29:.*]] = fir.call @_QMchar_elemPelem_return_char(%[[VAL_28]], %[[VAL_15]], %[[VAL_18]]) proc_attrs<elemental, pure> fastmath<contract> : (!fir.ref<!fir.char<1,?>>, index, !fir.boxchar<1>) -> !fir.boxchar<1>
|
||||
! CHECK: %[[VAL_30:.*]]:2 = hlfir.declare %[[VAL_28]] typeparams %[[VAL_15]] {uniq_name = ".tmp.func_result"} : (!fir.ref<!fir.char<1,?>>, index) -> (!fir.boxchar<1>, !fir.ref<!fir.char<1,?>>)
|
||||
! CHECK: %[[VAL_29:.*]] = fir.call @_QMchar_elemPelem_return_char(%[[VAL_28]], %[[VAL_15]], %[[VAL_18]]) proc_attrs<elemental, pure> fastmath<contract> : (!fir.ref<!fir.char<1,?>>, index, !fir.boxchar<1>) -> !fir.boxchar<1>
|
||||
! CHECK: %[[VAL_31:.*]] = arith.constant false
|
||||
! CHECK: %[[VAL_32:.*]] = hlfir.as_expr %[[VAL_30]]#0 move %[[VAL_31]] : (!fir.boxchar<1>, i1) -> !hlfir.expr<!fir.char<1,?>>
|
||||
! CHECK: hlfir.yield_element %[[VAL_32]] : !hlfir.expr<!fir.char<1,?>>
|
||||
|
||||
@ -17,22 +17,25 @@ subroutine test_temp_io_options(status)
|
||||
! CHECK: %[[VAL_2:.*]] = fir.alloca !fir.box<!fir.heap<!fir.char<1,?>>>
|
||||
! CHECK: %[[VAL_3:.*]] = fir.alloca !fir.box<!fir.heap<!fir.char<1,?>>>
|
||||
! CHECK: fir.call @_FortranAioBeginOpenUnit
|
||||
! CHECK: %[[DECLARE3:.*]] = fir.declare %[[VAL_3]]
|
||||
! CHECK: %[[VAL_15:.*]] = fir.call @_QPgen_temp_character() {{.*}}: () -> !fir.box<!fir.heap<!fir.char<1,?>>>
|
||||
! CHECK: fir.save_result %[[VAL_15]] to %[[VAL_3]] : !fir.box<!fir.heap<!fir.char<1,?>>>, !fir.ref<!fir.box<!fir.heap<!fir.char<1,?>>>>
|
||||
! CHECK: fir.save_result %[[VAL_15]] to %[[DECLARE3]] : !fir.box<!fir.heap<!fir.char<1,?>>>, !fir.ref<!fir.box<!fir.heap<!fir.char<1,?>>>>
|
||||
! CHECK: %[[VAL_21:.*]] = fir.call @_FortranAioSetEncoding
|
||||
! CHECK: %[[VAL_22:.*]] = fir.load %[[VAL_3]] : !fir.ref<!fir.box<!fir.heap<!fir.char<1,?>>>>
|
||||
! CHECK: %[[VAL_23:.*]] = fir.box_addr %[[VAL_22]] : (!fir.box<!fir.heap<!fir.char<1,?>>>) -> !fir.heap<!fir.char<1,?>>
|
||||
! CHECK: fir.freemem %[[VAL_23]] : !fir.heap<!fir.char<1,?>>
|
||||
! CHECK: fir.if %[[VAL_21]] {
|
||||
! CHECK: %[[DECLARE2:.*]] = fir.declare %[[VAL_2]]
|
||||
! CHECK: %[[VAL_27:.*]] = fir.call @_QPgen_temp_character() {{.*}}: () -> !fir.box<!fir.heap<!fir.char<1,?>>>
|
||||
! CHECK: fir.save_result %[[VAL_27]] to %[[VAL_2]] : !fir.box<!fir.heap<!fir.char<1,?>>>, !fir.ref<!fir.box<!fir.heap<!fir.char<1,?>>>>
|
||||
! CHECK: fir.save_result %[[VAL_27]] to %[[DECLARE2]] : !fir.box<!fir.heap<!fir.char<1,?>>>, !fir.ref<!fir.box<!fir.heap<!fir.char<1,?>>>>
|
||||
! CHECK: %[[VAL_33:.*]] = fir.call @_FortranAioSetFile
|
||||
! CHECK: %[[VAL_34:.*]] = fir.load %[[VAL_2]] : !fir.ref<!fir.box<!fir.heap<!fir.char<1,?>>>>
|
||||
! CHECK: %[[VAL_35:.*]] = fir.box_addr %[[VAL_34]] : (!fir.box<!fir.heap<!fir.char<1,?>>>) -> !fir.heap<!fir.char<1,?>>
|
||||
! CHECK: fir.freemem %[[VAL_35]] : !fir.heap<!fir.char<1,?>>
|
||||
! CHECK: fir.if %[[VAL_33]] {
|
||||
! CHECK: %[[DECLARE1:.*]] = fir.declare %[[VAL_1]]
|
||||
! CHECK: %[[VAL_39:.*]] = fir.call @_QPgen_temp_character() {{.*}}: () -> !fir.box<!fir.heap<!fir.char<1,?>>>
|
||||
! CHECK: fir.save_result %[[VAL_39]] to %[[VAL_1]] : !fir.box<!fir.heap<!fir.char<1,?>>>, !fir.ref<!fir.box<!fir.heap<!fir.char<1,?>>>>
|
||||
! CHECK: fir.save_result %[[VAL_39]] to %[[DECLARE1]] : !fir.box<!fir.heap<!fir.char<1,?>>>, !fir.ref<!fir.box<!fir.heap<!fir.char<1,?>>>>
|
||||
! CHECK: fir.call @_FortranAioSetPad
|
||||
! CHECK: %[[VAL_46:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.heap<!fir.char<1,?>>>>
|
||||
! CHECK: %[[VAL_47:.*]] = fir.box_addr %[[VAL_46]] : (!fir.box<!fir.heap<!fir.char<1,?>>>) -> !fir.heap<!fir.char<1,?>>
|
||||
|
||||
@ -56,8 +56,9 @@ end program main
|
||||
! DEVICE: omp.distribute {
|
||||
! COMMON: omp.wsloop {
|
||||
! COMMON: omp.loop_nest {{.*}} {
|
||||
! COMMON: %[[DECLARE:.*]]:2 = hlfir.declare %[[LOCAL_TEMP]]
|
||||
! COMMON: %[[TEMP_VAL:.*]] = fir.call @_QMstruct_modPconstruct_from_components
|
||||
! COMMON: fir.save_result %[[TEMP_VAL]] to %[[LOCAL_TEMP]]
|
||||
! COMMON: fir.save_result %[[TEMP_VAL]] to %[[DECLARE]]#0
|
||||
! COMMON: %[[EMBOXED_LOCAL:.*]] = fir.embox %[[LOCAL_TEMP]]
|
||||
! COMMON: %[[CONVERTED_LOCAL:.*]] = fir.convert %[[EMBOXED_LOCAL]]
|
||||
! COMMON: fir.call @_FortranADestroy(%[[CONVERTED_LOCAL]])
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user