[flang-commits] [flang] [flang] emit declare for function result before call (PR #177615)
via flang-commits
flang-commits at lists.llvm.org
Fri Jan 23 09:00:38 PST 2026
https://github.com/jeanPerier created https://github.com/llvm/llvm-project/pull/177615
This changes 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.
>From 600bfea32f440f0e58c8ab6190a22673e04c5ee9 Mon Sep 17 00:00:00 2001
From: Jean Perier <jperier at nvidia.com>
Date: Fri, 23 Jan 2026 06:43:21 -0800
Subject: [PATCH] [flang] emit declare for function result before call
---
flang/include/flang/Lower/ConvertCall.h | 3 +-
flang/lib/Lower/ConvertCall.cpp | 56 ++++++++++++-------
flang/lib/Lower/ConvertExpr.cpp | 13 ++---
flang/test/Lower/HLFIR/calls-f77.f90 | 2 +-
.../test/Lower/HLFIR/elemental-array-ops.f90 | 2 +-
flang/test/Lower/HLFIR/where.f90 | 4 +-
.../test/Lower/Intrinsics/storage_size-2.f90 | 4 +-
.../omp-declare-reduction-derivedtype.f90 | 2 +-
.../array-elemental-calls-char-dynamic.f90 | 10 ++--
.../test/Lower/array-elemental-calls-char.f90 | 2 +-
10 files changed, 57 insertions(+), 41 deletions(-)
diff --git a/flang/include/flang/Lower/ConvertCall.h b/flang/include/flang/Lower/ConvertCall.h
index f1cd4f938320b..6de0b3cbd11f5 100644
--- a/flang/include/flang/Lower/ConvertCall.h
+++ b/flang/include/flang/Lower/ConvertCall.h
@@ -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,
diff --git a/flang/lib/Lower/ConvertCall.cpp b/flang/lib/Lower/ConvertCall.cpp
index 7bdd84903c1d3..8a0160e9a2fa3 100644
--- a/flang/lib/Lower/ConvertCall.cpp
+++ b/flang/lib/Lower/ConvertCall.cpp
@@ -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,6 +1077,17 @@ extendedValueToHlfirEntity(mlir::Location loc, fir::FirOpBuilder &builder,
builder, loc, storage, /*mustFree=*/builder.createBool(loc, false));
return hlfir::EntityWithAttributes{asExpr.getResult()};
}
+ // TODO: better scoping model in FIR.
+ // The declare for result storage allocated on the callee side must be
+ // 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);
return hlfir::genDeclare(loc, builder, exv, name,
fir::FortranVariableFlagsAttr{});
}
@@ -1909,10 +1924,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 +1964,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 +1997,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
diff --git a/flang/lib/Lower/ConvertExpr.cpp b/flang/lib/Lower/ConvertExpr.cpp
index b2910a0fc58e0..a7e0239d335fd 100644
--- a/flang/lib/Lower/ConvertExpr.cpp
+++ b/flang/lib/Lower/ConvertExpr.cpp
@@ -2907,10 +2907,8 @@ class ScalarExprLowering {
}
}
- 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 @@ class ArrayExprLowering {
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);
};
}
diff --git a/flang/test/Lower/HLFIR/calls-f77.f90 b/flang/test/Lower/HLFIR/calls-f77.f90
index 97d2307beeb06..3e3ac33bdf719 100644
--- a/flang/test/Lower/HLFIR/calls-f77.f90
+++ b/flang/test/Lower/HLFIR/calls-f77.f90
@@ -164,8 +164,8 @@ subroutine return_char(n)
! 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
diff --git a/flang/test/Lower/HLFIR/elemental-array-ops.f90 b/flang/test/Lower/HLFIR/elemental-array-ops.f90
index 3a923b3c70ec5..9007e26b05a64 100644
--- a/flang/test/Lower/HLFIR/elemental-array-ops.f90
+++ b/flang/test/Lower/HLFIR/elemental-array-ops.f90
@@ -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>>
diff --git a/flang/test/Lower/HLFIR/where.f90 b/flang/test/Lower/HLFIR/where.f90
index bd4cc64de9509..80f1c38510f05 100644
--- a/flang/test/Lower/HLFIR/where.f90
+++ b/flang/test/Lower/HLFIR/where.f90
@@ -76,9 +76,9 @@ subroutine where_cleanup()
! 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_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_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: %[[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 @@ subroutine where_cleanup()
! CHECK: }
! CHECK: } do {
! CHECK: hlfir.region_assign {
+! 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_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: %[[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>
diff --git a/flang/test/Lower/Intrinsics/storage_size-2.f90 b/flang/test/Lower/Intrinsics/storage_size-2.f90
index 208070e04e6e6..41ea51961bca4 100644
--- a/flang/test/Lower/Intrinsics/storage_size-2.f90
+++ b/flang/test/Lower/Intrinsics/storage_size-2.f90
@@ -11,8 +11,8 @@ function return_char(l)
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)
diff --git a/flang/test/Lower/OpenMP/omp-declare-reduction-derivedtype.f90 b/flang/test/Lower/OpenMP/omp-declare-reduction-derivedtype.f90
index 36bb131e677a3..f38018d2067cc 100644
--- a/flang/test/Lower/OpenMP/omp-declare-reduction-derivedtype.f90
+++ b/flang/test/Lower/OpenMP/omp-declare-reduction-derivedtype.f90
@@ -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: %[[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 %[[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: %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)
diff --git a/flang/test/Lower/array-elemental-calls-char-dynamic.f90 b/flang/test/Lower/array-elemental-calls-char-dynamic.f90
index 24b798904d82d..34baea2e9f3b2 100644
--- a/flang/test/Lower/array-elemental-calls-char-dynamic.f90
+++ b/flang/test/Lower/array-elemental-calls-char-dynamic.f90
@@ -39,8 +39,8 @@ elemental function bug_145151_1(c_dummy)
! 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 @@ elemental function bug_145151_2(x)
! 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 @@ elemental function f_opt(x, opt)
! 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 @@ elemental function f_poly(p1, p2)
! 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 @@ elemental function f_value(c_dummy)
! 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
diff --git a/flang/test/Lower/array-elemental-calls-char.f90 b/flang/test/Lower/array-elemental-calls-char.f90
index f99bce4cfec81..b1c220991c6fe 100644
--- a/flang/test/Lower/array-elemental-calls-char.f90
+++ b/flang/test/Lower/array-elemental-calls-char.f90
@@ -253,8 +253,8 @@ subroutine foo6(c)
! 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,?>>
More information about the flang-commits
mailing list