[Mlir-commits] [flang] [mlir] [flang][openacc] support array section privatization in lowering (PR #175184)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Fri Jan 9 07:19:57 PST 2026
https://github.com/jeanPerier created https://github.com/llvm/llvm-project/pull/175184
Add support array section in private, firstprivate, and reduction.
Key changes:
- Change the related data operation result type to return the same type as the array base (same type as the acc variable input in the operation), while it was the type of the section before. This allows remapping the base the to result value (to use the data operation result as the base when generating addressing inside the compute region).
- The generatePrivateInit implementation of FIROpenACCTypeInterfaces is modified to allocate storage only for the section, and to return the mock base address (that is the address of the allocation minus the offset/lower bound of the privatized section).
- The code generating the copy and combiner region is moved from OpenACC.cpp to FIROpenACCTypeInterfaces.cpp via the addition of new generateCopy and generateCombiner interface in the MappableTypeInterface. This allows sharing all the addressing helper with generatePrivateInit, and will allow late generation of all recipes with Fortran.
- Update generatePrivateDestroy to deallocate the beginning of the section if any.
In the process, the generatePrivateInit implementation is greatly modified so that it is more uniform to make it easier to deal with the section. This also allowed removing runtime calls when initializing the private for array reduction.
Note that all of generatePrivateInit/generateCopy/generateCombiner/generatePrivateDestroy will generate hlfir operations (hlfir.designate) to deal with the sections, making it harder to use these helpers in late stages when HLFIR has already been lowered. I will circle back when there is more need for this late generation.
>From 450dda2925dd68003de439fbb147760e4dac7ce0 Mon Sep 17 00:00:00 2001
From: Jean Perier <jperier at nvidia.com>
Date: Tue, 6 Jan 2026 07:22:18 -0800
Subject: [PATCH] [flang][openacc] support array section privatization in
lowering
---
flang/include/flang/Lower/OpenACC.h | 16 +-
.../flang/Optimizer/Builder/FIRBuilder.h | 2 +-
.../Support/FIROpenACCTypeInterfaces.h | 17 +-
flang/lib/Lower/OpenACC.cpp | 513 ++++--------
flang/lib/Optimizer/Builder/FIRBuilder.cpp | 33 +-
flang/lib/Optimizer/Builder/HLFIRTools.cpp | 13 +-
.../Support/FIROpenACCTypeInterfaces.cpp | 637 +++++++++++----
.../OpenACC/Support/FIROpenACCUtils.cpp | 12 +-
.../OpenACC/recipe-populate-firstprivate.mlir | 26 +-
.../Fir/OpenACC/recipe-populate-private.mlir | 47 +-
...firstprivate-derived-pointer-component.f90 | 12 +-
.../acc-firstprivate-derived-user-assign.f90 | 6 +-
.../OpenACC/acc-firstprivate-derived.f90 | 6 +-
flang/test/Lower/OpenACC/acc-parallel.f90 | 9 +-
flang/test/Lower/OpenACC/acc-private.f90 | 597 ++++++++------
flang/test/Lower/OpenACC/acc-reduction.f90 | 748 ++++++++++--------
flang/test/Lower/OpenACC/acc-serial-loop.f90 | 8 +-
flang/test/Lower/OpenACC/acc-serial.f90 | 9 +-
.../OpenACC/acc-implicit-firstprivate.fir | 27 +-
.../Dialect/OpenACC/OpenACCTypeInterfaces.td | 40 +-
mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp | 2 +-
21 files changed, 1579 insertions(+), 1201 deletions(-)
diff --git a/flang/include/flang/Lower/OpenACC.h b/flang/include/flang/Lower/OpenACC.h
index 69f1f5be753e6..c2a950f36c5a7 100644
--- a/flang/include/flang/Lower/OpenACC.h
+++ b/flang/include/flang/Lower/OpenACC.h
@@ -88,23 +88,23 @@ void genOpenACCRoutineConstruct(
/// Get a acc.private.recipe op for the given type or create it if it does not
/// exist yet.
-mlir::acc::PrivateRecipeOp createOrGetPrivateRecipe(fir::FirOpBuilder &,
- llvm::StringRef,
- mlir::Location, mlir::Type);
+mlir::acc::PrivateRecipeOp
+createOrGetPrivateRecipe(fir::FirOpBuilder &, llvm::StringRef, mlir::Location,
+ mlir::Type,
+ llvm::SmallVector<mlir::Value> &dataOperationBounds);
/// Get a acc.reduction.recipe op for the given type or create it if it does not
/// exist yet.
mlir::acc::ReductionRecipeOp
createOrGetReductionRecipe(fir::FirOpBuilder &, llvm::StringRef, mlir::Location,
mlir::Type, mlir::acc::ReductionOperator,
- llvm::SmallVector<mlir::Value> &);
+ llvm::SmallVector<mlir::Value> &dataOperationBounds);
/// Get a acc.firstprivate.recipe op for the given type or create it if it does
/// not exist yet.
-mlir::acc::FirstprivateRecipeOp
-createOrGetFirstprivateRecipe(fir::FirOpBuilder &, llvm::StringRef,
- mlir::Location, mlir::Type,
- llvm::SmallVector<mlir::Value> &);
+mlir::acc::FirstprivateRecipeOp createOrGetFirstprivateRecipe(
+ fir::FirOpBuilder &, llvm::StringRef, mlir::Location, mlir::Type,
+ llvm::SmallVector<mlir::Value> &dataOperationBounds);
void attachDeclarePostAllocAction(AbstractConverter &, fir::FirOpBuilder &,
const Fortran::semantics::Symbol &);
diff --git a/flang/include/flang/Optimizer/Builder/FIRBuilder.h b/flang/include/flang/Optimizer/Builder/FIRBuilder.h
index 48a72d73c03bd..c6531ac3d0559 100644
--- a/flang/include/flang/Optimizer/Builder/FIRBuilder.h
+++ b/flang/include/flang/Optimizer/Builder/FIRBuilder.h
@@ -576,7 +576,7 @@ class FirOpBuilder : public mlir::OpBuilder, public mlir::OpBuilder::Listener {
/// Fortran 2018 9.5.3.3.2 section for more details.
mlir::Value genExtentFromTriplet(mlir::Location loc, mlir::Value lb,
mlir::Value ub, mlir::Value step,
- mlir::Type type);
+ mlir::Type type, bool fold = false);
/// Create an AbsentOp of \p argTy type and handle special cases, such as
/// Character Procedure Tuple arguments.
diff --git a/flang/include/flang/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.h b/flang/include/flang/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.h
index 0f133623475f8..9db67afeda5e9 100644
--- a/flang/include/flang/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.h
+++ b/flang/include/flang/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.h
@@ -86,7 +86,22 @@ struct OpenACCMappableModel
bool &needsDestroy) const;
bool generatePrivateDestroy(mlir::Type type, mlir::OpBuilder &builder,
- mlir::Location loc, mlir::Value privatized) const;
+ mlir::Location loc, mlir::Value privatized,
+ mlir::ValueRange bounds) const;
+
+ bool generateCopy(mlir::Type type, mlir::OpBuilder &mlirBuilder,
+ mlir::Location loc,
+ mlir::TypedValue<mlir::acc::MappableType> source,
+ mlir::TypedValue<mlir::acc::MappableType> dest,
+ mlir::ValueRange bounds) const;
+
+ bool generateCombiner(mlir::Type type, mlir::OpBuilder &mlirBuilder,
+ mlir::Location loc,
+ mlir::TypedValue<mlir::acc::MappableType> dest,
+ mlir::TypedValue<mlir::acc::MappableType> source,
+ mlir::ValueRange bounds,
+ mlir::acc::ReductionOperator op,
+ mlir::Attribute fastmathFlags) const;
};
} // namespace fir::acc
diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp
index 52fee7baf9de1..0bd2024a3b29b 100644
--- a/flang/lib/Lower/OpenACC.cpp
+++ b/flang/lib/Lower/OpenACC.cpp
@@ -27,14 +27,17 @@
#include "flang/Optimizer/Builder/HLFIRTools.h"
#include "flang/Optimizer/Builder/IntrinsicCall.h"
#include "flang/Optimizer/Builder/Todo.h"
+#include "flang/Optimizer/Dialect/FIROpsSupport.h"
#include "flang/Optimizer/Dialect/FIRType.h"
#include "flang/Optimizer/OpenACC/Support/FIROpenACCUtils.h"
+#include "flang/Optimizer/Support/Utils.h"
#include "flang/Parser/parse-tree-visitor.h"
#include "flang/Parser/parse-tree.h"
#include "flang/Parser/tools.h"
#include "flang/Semantics/expression.h"
#include "flang/Semantics/scope.h"
#include "flang/Semantics/tools.h"
+#include "mlir/Dialect/Arith/IR/Arith.h"
#include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.h"
#include "mlir/Dialect/OpenACC/OpenACCUtils.h"
#include "mlir/IR/IRMapping.h"
@@ -643,54 +646,19 @@ void genAtomicCapture(Fortran::lower::AbstractConverter &converter,
firOpBuilder.setInsertionPointAfter(atomicCaptureOp);
}
-/// Rebuild the array type from the acc.bounds operation with constant
-/// lowerbound/upperbound or extent.
-static mlir::Type getTypeFromBounds(llvm::SmallVector<mlir::Value> &bounds,
- mlir::Type ty) {
- auto seqTy =
- mlir::dyn_cast_or_null<fir::SequenceType>(fir::unwrapRefType(ty));
- if (!bounds.empty() && seqTy) {
- llvm::SmallVector<int64_t> shape;
- for (auto b : bounds) {
- auto boundsOp =
- mlir::dyn_cast<mlir::acc::DataBoundsOp>(b.getDefiningOp());
- if (boundsOp.getLowerbound() &&
- fir::getIntIfConstant(boundsOp.getLowerbound()) &&
- boundsOp.getUpperbound() &&
- fir::getIntIfConstant(boundsOp.getUpperbound())) {
- int64_t ext = *fir::getIntIfConstant(boundsOp.getUpperbound()) -
- *fir::getIntIfConstant(boundsOp.getLowerbound()) + 1;
- shape.push_back(ext);
- } else if (boundsOp.getExtent() &&
- fir::getIntIfConstant(boundsOp.getExtent())) {
- shape.push_back(*fir::getIntIfConstant(boundsOp.getExtent()));
- } else {
- return ty; // TODO: handle dynamic shaped array slice.
- }
- }
- if (shape.empty() || shape.size() != bounds.size())
- return ty;
- auto newSeqTy = fir::SequenceType::get(shape, seqTy.getEleTy());
- if (mlir::isa<fir::ReferenceType, fir::PointerType>(ty))
- return fir::ReferenceType::get(newSeqTy);
- return newSeqTy;
- }
- return ty;
-}
-
static mlir::SymbolRefAttr
createOrGetRecipe(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::acc::RecipeKind kind, mlir::Value addr,
llvm::SmallVector<mlir::Value> &bounds) {
- mlir::Type ty = getTypeFromBounds(bounds, addr.getType());
+ mlir::Type ty = addr.getType();
// Compute the canonical recipe name for the given kind, type, address and
// bounds so that recipes are shared wherever possible.
std::string recipeName = fir::acc::getRecipeName(kind, ty, addr, bounds);
switch (kind) {
case mlir::acc::RecipeKind::private_recipe: {
- auto recipe =
- Fortran::lower::createOrGetPrivateRecipe(builder, recipeName, loc, ty);
+ auto recipe = Fortran::lower::createOrGetPrivateRecipe(builder, recipeName,
+ loc, ty, bounds);
return mlir::SymbolRefAttr::get(builder.getContext(), recipe.getSymName());
}
case mlir::acc::RecipeKind::firstprivate_recipe: {
@@ -788,6 +756,9 @@ genDataOperandOperations(const Fortran::parser::AccObjectList &objectList,
dataRef->u);
}
+ bool isPrivate = std::is_same_v<Op, mlir::acc::PrivateOp> ||
+ std::is_same_v<Op, mlir::acc::FirstprivateOp>;
+
fir::factory::AddrAndBoundsInfo info =
Fortran::lower::gatherDataOperandAddrAndBounds<
mlir::acc::DataBoundsOp, mlir::acc::DataBoundsType>(
@@ -804,8 +775,6 @@ genDataOperandOperations(const Fortran::parser::AccObjectList &objectList,
// For privatization, absent OPTIONAL are illegal as per OpenACC 3.3
// section 2.17.1 and the descriptor must be used to drive the creation of
// the temporary and the copy.
- bool isPrivate = std::is_same_v<Op, mlir::acc::PrivateOp> ||
- std::is_same_v<Op, mlir::acc::FirstprivateOp>;
mlir::Value baseAddr = (!isPrivate &&
(fir::unwrapRefType(info.addr.getType()) !=
fir::unwrapRefType(info.rawInput.getType())) &&
@@ -813,17 +782,9 @@ genDataOperandOperations(const Fortran::parser::AccObjectList &objectList,
? info.rawInput
: info.addr;
- // TODO: update privatization of array section to return the base
- // address and update the recipe generation to "offset back" the returned
- // address. Then it will be possible to remap them like in other cases.
- bool isPrivateArraySection = isPrivate && !bounds.empty();
- mlir::Type resTy = isPrivateArraySection
- ? getTypeFromBounds(bounds, baseAddr.getType())
- : baseAddr.getType();
-
Op op = createDataEntryOp<Op>(
builder, operandLocation, baseAddr, asFortran, bounds, structured,
- implicit, dataClause, resTy, async, asyncDeviceTypes,
+ implicit, dataClause, baseAddr.getType(), async, asyncDeviceTypes,
asyncOnlyDeviceTypes, unwrapBoxAddr, info.isPresent);
dataOperands.push_back(op.getAccVar());
@@ -841,7 +802,7 @@ genDataOperandOperations(const Fortran::parser::AccObjectList &objectList,
// Track the symbol and its corresponding mlir::Value if requested so that
// accesses inside regions can be remapped.
- if (dataMap && !isPrivateArraySection && !isNoCreateWithBounds) {
+ if (dataMap && !isNoCreateWithBounds) {
if (componentRef)
dataMap->emplaceComponent(op.getAccVar(), std::move(*componentRef),
baseAddr);
@@ -1081,16 +1042,6 @@ genDataExitOperations(fir::FirOpBuilder &builder,
}
}
-fir::ShapeOp genShapeOp(mlir::OpBuilder &builder, fir::SequenceType seqTy,
- mlir::Location loc) {
- llvm::SmallVector<mlir::Value> extents;
- mlir::Type idxTy = builder.getIndexType();
- for (auto extent : seqTy.getShape())
- extents.push_back(mlir::arith::ConstantOp::create(
- builder, loc, idxTy, builder.getIntegerAttr(idxTy, extent)));
- return fir::ShapeOp::create(builder, loc, extents);
-}
-
/// Get the initial value for reduction operator.
template <typename R>
static R getReductionInitValue(mlir::acc::ReductionOperator op, mlir::Type ty) {
@@ -1204,10 +1155,71 @@ static mlir::Value getReductionInitValue(fir::FirOpBuilder &builder,
llvm::report_fatal_error("Unsupported OpenACC reduction type");
}
+static llvm::SmallVector<mlir::Value>
+getRecipeBounds(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::ValueRange dataBoundOps,
+ mlir::ValueRange blockBoundArgs) {
+ if (dataBoundOps.empty())
+ return {};
+ mlir::Type idxTy = builder.getIndexType();
+ mlir::Value one = builder.createIntegerConstant(loc, idxTy, 1);
+ llvm::SmallVector<mlir::Value> bounds;
+ if (!blockBoundArgs.empty()) {
+ for (unsigned i = 0; i + 2 < blockBoundArgs.size(); i += 3) {
+ bounds.push_back(blockBoundArgs[i]);
+ bounds.push_back(blockBoundArgs[i + 1]);
+ // acc data bound strides is the inner size in bytes or elements, but
+ // sections are always 1-based, so there is no need to try to compute
+ // that back from the acc bounds.
+ bounds.push_back(one);
+ }
+ return bounds;
+ }
+ for (auto bound : dataBoundOps) {
+ auto dataBound = llvm::dyn_cast_if_present<mlir::acc::DataBoundsOp>(
+ bound.getDefiningOp());
+ assert(dataBound && "expect acc bounds to be produced by DataBoundsOp");
+ assert(
+ dataBound.getLowerbound() && dataBound.getUpperbound() &&
+ "expect acc bounds for Fortran to always have lower and upper bounds");
+ std::optional<std::int64_t> lb =
+ fir::getIntIfConstant(dataBound.getLowerbound());
+ std::optional<std::int64_t> ub =
+ fir::getIntIfConstant(dataBound.getUpperbound());
+ assert(lb.has_value() && ub.has_value() &&
+ "must get constant bounds when there are no bound block arguments");
+ bounds.push_back(builder.createIntegerConstant(loc, idxTy, *lb));
+ bounds.push_back(builder.createIntegerConstant(loc, idxTy, *ub));
+ bounds.push_back(one);
+ }
+ return bounds;
+}
+
+static void addRecipeBoundsArgs(llvm::SmallVector<mlir::Value> &bounds,
+ bool allConstantBound,
+ llvm::SmallVector<mlir::Type> &argsTy,
+ llvm::SmallVector<mlir::Location> &argsLoc) {
+ if (!allConstantBound) {
+ for (mlir::Value bound : llvm::reverse(bounds)) {
+ auto dataBound =
+ mlir::dyn_cast<mlir::acc::DataBoundsOp>(bound.getDefiningOp());
+ argsTy.push_back(dataBound.getLowerbound().getType());
+ argsLoc.push_back(dataBound.getLowerbound().getLoc());
+ argsTy.push_back(dataBound.getUpperbound().getType());
+ argsLoc.push_back(dataBound.getUpperbound().getLoc());
+ argsTy.push_back(dataBound.getStartIdx().getType());
+ argsLoc.push_back(dataBound.getStartIdx().getLoc());
+ }
+ }
+}
+
+using MappableValue = mlir::TypedValue<mlir::acc::MappableType>;
+
template <typename RecipeOp>
static RecipeOp genRecipeOp(
fir::FirOpBuilder &builder, mlir::ModuleOp mod, llvm::StringRef recipeName,
mlir::Location loc, mlir::Type ty,
+ llvm::SmallVector<mlir::Value> &dataOperationBounds, bool allConstantBound,
mlir::acc::ReductionOperator op = mlir::acc::ReductionOperator::AccNone) {
mlir::OpBuilder modBuilder(mod.getBodyRegion());
RecipeOp recipe;
@@ -1218,20 +1230,13 @@ static RecipeOp genRecipeOp(
recipe = RecipeOp::create(modBuilder, loc, recipeName, ty);
}
+ assert(hlfir::isFortranVariableType(ty) && "expect Fortran variable type");
+
llvm::SmallVector<mlir::Type> argsTy{ty};
llvm::SmallVector<mlir::Location> argsLoc{loc};
- if (auto refTy = mlir::dyn_cast_or_null<fir::ReferenceType>(ty)) {
- if (auto seqTy =
- mlir::dyn_cast_or_null<fir::SequenceType>(refTy.getEleTy())) {
- if (seqTy.hasDynamicExtents()) {
- mlir::Type idxTy = builder.getIndexType();
- for (unsigned i = 0; i < seqTy.getDimension(); ++i) {
- argsTy.push_back(idxTy);
- argsLoc.push_back(loc);
- }
- }
- }
- }
+ if (!dataOperationBounds.empty())
+ addRecipeBoundsArgs(dataOperationBounds, allConstantBound, argsTy, argsLoc);
+
auto initBlock = builder.createBlock(
&recipe.getInitRegion(), recipe.getInitRegion().end(), argsTy, argsLoc);
builder.setInsertionPointToEnd(&recipe.getInitRegion().back());
@@ -1253,15 +1258,13 @@ static RecipeOp genRecipeOp(
assert(mappableTy &&
"Expected that all variable types are considered mappable");
bool needsDestroy = false;
- auto retVal = mappableTy.generatePrivateInit(
- builder, loc,
- mlir::cast<mlir::TypedValue<mlir::acc::MappableType>>(
- initBlock->getArgument(0)),
- initName,
- initBlock->getArguments().take_back(initBlock->getArguments().size() - 1),
- initValue, needsDestroy);
- mlir::acc::YieldOp::create(builder, loc,
- retVal ? retVal : initBlock->getArgument(0));
+ llvm::SmallVector<mlir::Value> initBounds =
+ getRecipeBounds(builder, loc, dataOperationBounds,
+ initBlock->getArguments().drop_front(1));
+ mlir::Value retVal = mappableTy.generatePrivateInit(
+ builder, loc, mlir::cast<MappableValue>(initBlock->getArgument(0)),
+ initName, initBounds, initValue, needsDestroy);
+ mlir::acc::YieldOp::create(builder, loc, retVal);
// Create destroy region and generate destruction if requested.
if (needsDestroy) {
llvm::SmallVector<mlir::Type> destroyArgsTy;
@@ -1277,189 +1280,59 @@ static RecipeOp genRecipeOp(
destroyArgsLoc.insert(destroyArgsLoc.end(), argsTy.size() - 1, loc);
}
- builder.createBlock(&recipe.getDestroyRegion(),
- recipe.getDestroyRegion().end(), destroyArgsTy,
- destroyArgsLoc);
- builder.setInsertionPointToEnd(&recipe.getDestroyRegion().back());
- // Call interface on the privatized/reduction value (2nd argument).
- (void)mappableTy.generatePrivateDestroy(
- builder, loc, recipe.getDestroyRegion().front().getArgument(1));
+ mlir::Block *destroyBlock = builder.createBlock(
+ &recipe.getDestroyRegion(), recipe.getDestroyRegion().end(),
+ destroyArgsTy, destroyArgsLoc);
+ builder.setInsertionPointToEnd(destroyBlock);
+
+ llvm::SmallVector<mlir::Value> destroyBounds =
+ getRecipeBounds(builder, loc, dataOperationBounds,
+ destroyBlock->getArguments().drop_front(2));
+ [[maybe_unused]] bool success = mappableTy.generatePrivateDestroy(
+ builder, loc, destroyBlock->getArgument(1), destroyBounds);
+ assert(success && "failed to generate destroy region");
mlir::acc::TerminatorOp::create(builder, loc);
}
return recipe;
}
-mlir::acc::PrivateRecipeOp
-Fortran::lower::createOrGetPrivateRecipe(fir::FirOpBuilder &builder,
- llvm::StringRef recipeName,
- mlir::Location loc, mlir::Type ty) {
+mlir::acc::PrivateRecipeOp Fortran::lower::createOrGetPrivateRecipe(
+ fir::FirOpBuilder &builder, llvm::StringRef recipeName, mlir::Location loc,
+ mlir::Type ty, llvm::SmallVector<mlir::Value> &bounds) {
mlir::ModuleOp mod =
builder.getBlock()->getParent()->getParentOfType<mlir::ModuleOp>();
if (auto recipe = mod.lookupSymbol<mlir::acc::PrivateRecipeOp>(recipeName))
return recipe;
auto ip = builder.saveInsertionPoint();
- auto recipe = genRecipeOp<mlir::acc::PrivateRecipeOp>(builder, mod,
- recipeName, loc, ty);
+ bool allConstantBound = fir::acc::areAllBoundsConstant(bounds);
+ auto recipe = genRecipeOp<mlir::acc::PrivateRecipeOp>(
+ builder, mod, recipeName, loc, ty, bounds, allConstantBound);
builder.restoreInsertionPoint(ip);
return recipe;
}
-/// Check if the DataBoundsOp is a constant bound (lb and ub are constants or
-/// extent is a constant).
-bool isConstantBound(mlir::acc::DataBoundsOp &op) {
- if (op.getLowerbound() && fir::getIntIfConstant(op.getLowerbound()) &&
- op.getUpperbound() && fir::getIntIfConstant(op.getUpperbound()))
- return true;
- if (op.getExtent() && fir::getIntIfConstant(op.getExtent()))
- return true;
- return false;
-}
-
-static llvm::SmallVector<mlir::Value>
-genConstantBounds(fir::FirOpBuilder &builder, mlir::Location loc,
- mlir::acc::DataBoundsOp &dataBound) {
- mlir::Type idxTy = builder.getIndexType();
- mlir::Value lb, ub, step;
- if (dataBound.getLowerbound() &&
- fir::getIntIfConstant(dataBound.getLowerbound()) &&
- dataBound.getUpperbound() &&
- fir::getIntIfConstant(dataBound.getUpperbound())) {
- lb = builder.createIntegerConstant(
- loc, idxTy, *fir::getIntIfConstant(dataBound.getLowerbound()));
- ub = builder.createIntegerConstant(
- loc, idxTy, *fir::getIntIfConstant(dataBound.getUpperbound()));
- step = builder.createIntegerConstant(loc, idxTy, 1);
- } else if (dataBound.getExtent()) {
- lb = builder.createIntegerConstant(loc, idxTy, 0);
- ub = builder.createIntegerConstant(
- loc, idxTy, *fir::getIntIfConstant(dataBound.getExtent()) - 1);
- step = builder.createIntegerConstant(loc, idxTy, 1);
- } else {
- llvm::report_fatal_error("Expect constant lb/ub or extent");
- }
- return {lb, ub, step};
-}
-
-static hlfir::Entity genDesignateWithTriplets(
- fir::FirOpBuilder &builder, mlir::Location loc, hlfir::Entity &entity,
- hlfir::DesignateOp::Subscripts &triplets, mlir::Value shape) {
- llvm::SmallVector<mlir::Value> lenParams;
- hlfir::genLengthParameters(loc, builder, entity, lenParams);
- auto designate = hlfir::DesignateOp::create(
- builder, loc, entity.getBase().getType(), entity, /*component=*/"",
- /*componentShape=*/mlir::Value{}, triplets,
- /*substring=*/mlir::ValueRange{}, /*complexPartAttr=*/std::nullopt, shape,
- lenParams);
- return hlfir::Entity{designate.getResult()};
-}
-
-// Designate uses triplets based on object lower bounds while acc.bounds are
-// zero based. This helper shift the bounds to create the designate triplets.
-static hlfir::DesignateOp::Subscripts
-genTripletsFromAccBounds(fir::FirOpBuilder &builder, mlir::Location loc,
- const llvm::SmallVector<mlir::Value> &accBounds,
- hlfir::Entity entity) {
- assert(entity.getRank() * 3 == static_cast<int>(accBounds.size()) &&
- "must get lb,ub,step for each dimension");
- hlfir::DesignateOp::Subscripts triplets;
- for (unsigned i = 0; i < accBounds.size(); i += 3) {
- mlir::Value lb = hlfir::genLBound(loc, builder, entity, i / 3);
- lb = builder.createConvert(loc, accBounds[i].getType(), lb);
- assert(accBounds[i].getType() == accBounds[i + 1].getType() &&
- "mix of integer types in triplets");
- mlir::Value sliceLB =
- builder.createOrFold<mlir::arith::AddIOp>(loc, accBounds[i], lb);
- mlir::Value sliceUB =
- builder.createOrFold<mlir::arith::AddIOp>(loc, accBounds[i + 1], lb);
- triplets.emplace_back(
- hlfir::DesignateOp::Triplet{sliceLB, sliceUB, accBounds[i + 2]});
- }
- return triplets;
-}
-
-static std::pair<hlfir::Entity, hlfir::Entity>
-genArraySectionsInRecipe(fir::FirOpBuilder &builder, mlir::Location loc,
- llvm::SmallVector<mlir::Value> &dataOperationBounds,
- mlir::ValueRange recipeArguments,
- bool allConstantBound, hlfir::Entity lhs,
- hlfir::Entity rhs) {
- lhs = hlfir::derefPointersAndAllocatables(loc, builder, lhs);
- rhs = hlfir::derefPointersAndAllocatables(loc, builder, rhs);
- // Get the list of lb,ub,step values for the sections that can be used inside
- // the recipe region.
- llvm::SmallVector<mlir::Value> bounds;
- if (allConstantBound) {
- // For constant bounds, the bounds are not region arguments. Materialize
- // constants looking at the IR for the bounds on the data operation.
- for (auto bound : dataOperationBounds) {
- auto dataBound =
- mlir::cast<mlir::acc::DataBoundsOp>(bound.getDefiningOp());
- bounds.append(genConstantBounds(builder, loc, dataBound));
- }
- } else {
- // If one bound is not constant, all of the bounds are region arguments.
- for (auto arg : recipeArguments.drop_front(2))
- bounds.push_back(arg);
- }
- // Compute the fir.shape of the array section and the triplets to create
- // hlfir.designate.
- assert(lhs.getRank() * 3 == static_cast<int>(bounds.size()) &&
- "must get lb,ub,step for each dimension");
- llvm::SmallVector<mlir::Value> extents;
- mlir::Type idxTy = builder.getIndexType();
- for (unsigned i = 0; i < bounds.size(); i += 3)
- extents.push_back(builder.genExtentFromTriplet(
- loc, bounds[i], bounds[i + 1], bounds[i + 2], idxTy));
- mlir::Value shape = fir::ShapeOp::create(builder, loc, extents);
- hlfir::DesignateOp::Subscripts rhsTriplets =
- genTripletsFromAccBounds(builder, loc, bounds, rhs);
- hlfir::DesignateOp::Subscripts lhsTriplets;
- // Share the bounds when both rhs/lhs are known to be 1-based to avoid noise
- // in the IR for the most common cases.
- if (!lhs.mayHaveNonDefaultLowerBounds() &&
- !rhs.mayHaveNonDefaultLowerBounds())
- lhsTriplets = rhsTriplets;
- else
- lhsTriplets = genTripletsFromAccBounds(builder, loc, bounds, lhs);
- hlfir::Entity leftSection =
- genDesignateWithTriplets(builder, loc, lhs, lhsTriplets, shape);
- hlfir::Entity rightSection =
- genDesignateWithTriplets(builder, loc, rhs, rhsTriplets, shape);
- return {leftSection, rightSection};
-}
-
// Generate the combiner or copy region block and block arguments and return the
// source and destination entities.
-static std::pair<hlfir::Entity, hlfir::Entity>
+static std::pair<MappableValue, MappableValue>
genRecipeCombinerOrCopyRegion(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Type ty, mlir::Region ®ion,
llvm::SmallVector<mlir::Value> &bounds,
bool allConstantBound) {
llvm::SmallVector<mlir::Type> argsTy{ty, ty};
llvm::SmallVector<mlir::Location> argsLoc{loc, loc};
- if (!allConstantBound) {
- for (mlir::Value bound : llvm::reverse(bounds)) {
- auto dataBound =
- mlir::dyn_cast<mlir::acc::DataBoundsOp>(bound.getDefiningOp());
- argsTy.push_back(dataBound.getLowerbound().getType());
- argsLoc.push_back(dataBound.getLowerbound().getLoc());
- argsTy.push_back(dataBound.getUpperbound().getType());
- argsLoc.push_back(dataBound.getUpperbound().getLoc());
- argsTy.push_back(dataBound.getStartIdx().getType());
- argsLoc.push_back(dataBound.getStartIdx().getLoc());
- }
- }
+ addRecipeBoundsArgs(bounds, allConstantBound, argsTy, argsLoc);
mlir::Block *block =
builder.createBlock(®ion, region.end(), argsTy, argsLoc);
builder.setInsertionPointToEnd(®ion.back());
- return {hlfir::Entity{block->getArgument(0)},
- hlfir::Entity{block->getArgument(1)}};
+ auto firstArg = mlir::cast<MappableValue>(block->getArgument(0));
+ auto secondArg = mlir::cast<MappableValue>(block->getArgument(1));
+ return {firstArg, secondArg};
}
mlir::acc::FirstprivateRecipeOp Fortran::lower::createOrGetFirstprivateRecipe(
fir::FirOpBuilder &builder, llvm::StringRef recipeName, mlir::Location loc,
- mlir::Type ty, llvm::SmallVector<mlir::Value> &bounds) {
+ mlir::Type ty, llvm::SmallVector<mlir::Value> &dataBoundOps) {
mlir::ModuleOp mod =
builder.getBlock()->getParent()->getParentOfType<mlir::ModuleOp>();
if (auto recipe =
@@ -1467,38 +1340,21 @@ mlir::acc::FirstprivateRecipeOp Fortran::lower::createOrGetFirstprivateRecipe(
return recipe;
mlir::OpBuilder::InsertionGuard guard(builder);
+ bool allConstantBound = fir::acc::areAllBoundsConstant(dataBoundOps);
auto recipe = genRecipeOp<mlir::acc::FirstprivateRecipeOp>(
- builder, mod, recipeName, loc, ty);
- bool allConstantBound = fir::acc::areAllBoundsConstant(bounds);
+ builder, mod, recipeName, loc, ty, dataBoundOps, allConstantBound);
auto [source, destination] = genRecipeCombinerOrCopyRegion(
- builder, loc, ty, recipe.getCopyRegion(), bounds, allConstantBound);
-
- fir::FirOpBuilder firBuilder{builder, recipe.getOperation()};
-
- source = hlfir::derefPointersAndAllocatables(loc, builder, source);
- destination = hlfir::derefPointersAndAllocatables(loc, builder, destination);
+ builder, loc, ty, recipe.getCopyRegion(), dataBoundOps, allConstantBound);
+ llvm::SmallVector<mlir::Value> copyBounds =
+ getRecipeBounds(builder, loc, dataBoundOps,
+ recipe.getCopyRegion().getArguments().drop_front(2));
- if (!bounds.empty())
- std::tie(source, destination) = genArraySectionsInRecipe(
- firBuilder, loc, bounds, recipe.getCopyRegion().getArguments(),
- allConstantBound, source, destination);
- // The source and the destination of the firstprivate copy cannot alias,
- // the destination is already properly allocated, so a simple assignment
- // can be generated right away to avoid ending-up with runtime calls
- // for arrays of numerical, logical and, character types.
- //
- // The temporary_lhs flag allows indicating that user defined assignments
- // should not be called while copying components, and that the LHS and RHS
- // are known to not alias since the LHS is a created object.
- //
- // TODO: detect cases where user defined assignment is needed and add a TODO.
- // using temporary_lhs allows more aggressive optimizations of simple derived
- // types. Existing compilers supporting OpenACC do not call user defined
- // assignments, some use case is needed to decide what to do.
- source = hlfir::loadTrivialScalar(loc, builder, source);
- hlfir::AssignOp::create(builder, loc, source, destination, /*realloc=*/false,
- /*keep_lhs_length_if_realloc=*/false,
- /*temporary_lhs=*/true);
+ auto mappableTy = mlir::dyn_cast<mlir::acc::MappableType>(ty);
+ assert(mappableTy &&
+ "Expected that all variable types are considered mappable");
+ [[maybe_unused]] bool success =
+ mappableTy.generateCopy(builder, loc, source, destination, copyBounds);
+ assert(success && "failed to generate copy");
mlir::acc::TerminatorOp::create(builder, loc);
return recipe;
}
@@ -1534,124 +1390,37 @@ getReductionOperator(const Fortran::parser::ReductionOperator &op) {
llvm_unreachable("unexpected reduction operator");
}
-template <typename Op>
-static mlir::Value genLogicalCombiner(fir::FirOpBuilder &builder,
- mlir::Location loc, mlir::Value value1,
- mlir::Value value2) {
- mlir::Type i1 = builder.getI1Type();
- mlir::Value v1 = fir::ConvertOp::create(builder, loc, i1, value1);
- mlir::Value v2 = fir::ConvertOp::create(builder, loc, i1, value2);
- mlir::Value combined = Op::create(builder, loc, v1, v2);
- return fir::ConvertOp::create(builder, loc, value1.getType(), combined);
-}
-
-static mlir::Value genComparisonCombiner(fir::FirOpBuilder &builder,
- mlir::Location loc,
- mlir::arith::CmpIPredicate pred,
- mlir::Value value1,
- mlir::Value value2) {
- mlir::Type i1 = builder.getI1Type();
- mlir::Value v1 = fir::ConvertOp::create(builder, loc, i1, value1);
- mlir::Value v2 = fir::ConvertOp::create(builder, loc, i1, value2);
- mlir::Value add = mlir::arith::CmpIOp::create(builder, loc, pred, v1, v2);
- return fir::ConvertOp::create(builder, loc, value1.getType(), add);
-}
-
-static mlir::Value genScalarCombiner(fir::FirOpBuilder &builder,
- mlir::Location loc,
- mlir::acc::ReductionOperator op,
- mlir::Type ty, mlir::Value value1,
- mlir::Value value2) {
- value1 = builder.loadIfRef(loc, value1);
- value2 = builder.loadIfRef(loc, value2);
- if (op == mlir::acc::ReductionOperator::AccAdd) {
- if (ty.isIntOrIndex())
- return mlir::arith::AddIOp::create(builder, loc, value1, value2);
- if (mlir::isa<mlir::FloatType>(ty))
- return mlir::arith::AddFOp::create(builder, loc, value1, value2);
- if (auto cmplxTy = mlir::dyn_cast_or_null<mlir::ComplexType>(ty))
- return fir::AddcOp::create(builder, loc, value1, value2);
- TODO(loc, "reduction add type");
- }
-
- if (op == mlir::acc::ReductionOperator::AccMul) {
- if (ty.isIntOrIndex())
- return mlir::arith::MulIOp::create(builder, loc, value1, value2);
- if (mlir::isa<mlir::FloatType>(ty))
- return mlir::arith::MulFOp::create(builder, loc, value1, value2);
- if (mlir::isa<mlir::ComplexType>(ty))
- return fir::MulcOp::create(builder, loc, value1, value2);
- TODO(loc, "reduction mul type");
- }
-
- if (op == mlir::acc::ReductionOperator::AccMin)
- return fir::genMin(builder, loc, {value1, value2});
-
- if (op == mlir::acc::ReductionOperator::AccMax)
- return fir::genMax(builder, loc, {value1, value2});
-
- if (op == mlir::acc::ReductionOperator::AccIand)
- return mlir::arith::AndIOp::create(builder, loc, value1, value2);
-
- if (op == mlir::acc::ReductionOperator::AccIor)
- return mlir::arith::OrIOp::create(builder, loc, value1, value2);
-
- if (op == mlir::acc::ReductionOperator::AccXor)
- return mlir::arith::XOrIOp::create(builder, loc, value1, value2);
-
- if (op == mlir::acc::ReductionOperator::AccLand)
- return genLogicalCombiner<mlir::arith::AndIOp>(builder, loc, value1,
- value2);
-
- if (op == mlir::acc::ReductionOperator::AccLor)
- return genLogicalCombiner<mlir::arith::OrIOp>(builder, loc, value1, value2);
-
- if (op == mlir::acc::ReductionOperator::AccEqv)
- return genComparisonCombiner(builder, loc, mlir::arith::CmpIPredicate::eq,
- value1, value2);
-
- if (op == mlir::acc::ReductionOperator::AccNeqv)
- return genComparisonCombiner(builder, loc, mlir::arith::CmpIPredicate::ne,
- value1, value2);
-
- TODO(loc, "reduction operator");
-}
-
mlir::acc::ReductionRecipeOp Fortran::lower::createOrGetReductionRecipe(
fir::FirOpBuilder &builder, llvm::StringRef recipeName, mlir::Location loc,
mlir::Type ty, mlir::acc::ReductionOperator op,
- llvm::SmallVector<mlir::Value> &bounds) {
+ llvm::SmallVector<mlir::Value> &dataBoundOps) {
mlir::ModuleOp mod =
builder.getBlock()->getParent()->getParentOfType<mlir::ModuleOp>();
if (auto recipe = mod.lookupSymbol<mlir::acc::ReductionRecipeOp>(recipeName))
return recipe;
mlir::OpBuilder::InsertionGuard guard(builder);
+ bool allConstantBound = fir::acc::areAllBoundsConstant(dataBoundOps);
auto recipe = genRecipeOp<mlir::acc::ReductionRecipeOp>(
- builder, mod, recipeName, loc, ty, op);
- bool allConstantBound = fir::acc::areAllBoundsConstant(bounds);
+ builder, mod, recipeName, loc, ty, dataBoundOps, allConstantBound, op);
- auto [dest, src] = genRecipeCombinerOrCopyRegion(
- builder, loc, ty, recipe.getCombinerRegion(), bounds, allConstantBound);
- // Generate loops that combine and assign the inputs into dest (or array
- // section of the inputs when there are bounds).
- hlfir::Entity srcSection = src;
- hlfir::Entity destSection = dest;
- if (!bounds.empty())
- std::tie(srcSection, destSection) = genArraySectionsInRecipe(
- builder, loc, bounds, recipe.getCombinerRegion().getArguments(),
- allConstantBound, srcSection, destSection);
-
- mlir::Type elementType = fir::getFortranElementType(ty);
- auto genKernel = [&](mlir::Location l, fir::FirOpBuilder &b,
- hlfir::Entity srcElementValue,
- hlfir::Entity destElementValue) -> hlfir::Entity {
- return hlfir::Entity{genScalarCombiner(builder, loc, op, elementType,
- srcElementValue, destElementValue)};
- };
- hlfir::genNoAliasAssignment(loc, builder, srcSection, destSection,
- /*emitWorkshareLoop=*/false,
- /*temporaryLHS=*/false, genKernel);
+ auto [dest, source] = genRecipeCombinerOrCopyRegion(
+ builder, loc, ty, recipe.getCombinerRegion(), dataBoundOps,
+ allConstantBound);
+ llvm::SmallVector<mlir::Value> combinerBounds =
+ getRecipeBounds(builder, loc, dataBoundOps,
+ recipe.getCombinerRegion().getArguments().drop_front(2));
+
+ auto mappableTy = mlir::dyn_cast<mlir::acc::MappableType>(ty);
+ assert(mappableTy &&
+ "Expected that all variable types are considered mappable");
+ mlir::Attribute fastMathAttr;
+ if (builder.getFastMathFlags() != mlir::arith::FastMathFlags::none)
+ fastMathAttr = mlir::arith::FastMathFlagsAttr::get(
+ builder.getContext(), builder.getFastMathFlags());
+ [[maybe_unused]] bool success = mappableTy.generateCombiner(
+ builder, loc, dest, source, combinerBounds, op, fastMathAttr);
+ assert(success && "failed to generate combiner");
mlir::acc::YieldOp::create(builder, loc, dest);
return recipe;
}
@@ -1726,10 +1495,6 @@ genReductions(const Fortran::parser::AccObjectListWithReduction &objectList,
mlir::acc::DataClause::acc_reduction, info.addr.getType(), async,
asyncDeviceTypes, asyncOnlyDeviceTypes, /*unwrapBoxAddr=*/true);
mlir::Type ty = op.getAccVar().getType();
- if (!fir::acc::areAllBoundsConstant(bounds) ||
- fir::isAssumedShape(info.addr.getType()) ||
- fir::isAllocatableOrPointerArray(info.addr.getType()))
- ty = info.addr.getType();
std::string recipeName = fir::acc::getRecipeName(
mlir::acc::RecipeKind::reduction_recipe, ty, info.addr, bounds, mlirOp);
diff --git a/flang/lib/Optimizer/Builder/FIRBuilder.cpp b/flang/lib/Optimizer/Builder/FIRBuilder.cpp
index c704ac79ae5f7..fcceb3a5b32c7 100644
--- a/flang/lib/Optimizer/Builder/FIRBuilder.cpp
+++ b/flang/lib/Optimizer/Builder/FIRBuilder.cpp
@@ -859,21 +859,32 @@ mlir::Value fir::FirOpBuilder::genIsNullAddr(mlir::Location loc,
mlir::arith::CmpIPredicate::eq);
}
-mlir::Value fir::FirOpBuilder::genExtentFromTriplet(mlir::Location loc,
- mlir::Value lb,
- mlir::Value ub,
- mlir::Value step,
- mlir::Type type) {
+template <typename OpTy, typename... Args>
+static mlir::Value createAndMaybeFold(bool fold, fir::FirOpBuilder &builder,
+ mlir::Location loc, Args &&...args) {
+ if (fold)
+ return builder.createOrFold<OpTy>(loc, std::forward<Args>(args)...);
+ return OpTy::create(builder, loc, std::forward<Args>(args)...);
+}
+
+mlir::Value
+fir::FirOpBuilder::genExtentFromTriplet(mlir::Location loc, mlir::Value lb,
+ mlir::Value ub, mlir::Value step,
+ mlir::Type type, bool fold) {
auto zero = createIntegerConstant(loc, type, 0);
lb = createConvert(loc, type, lb);
ub = createConvert(loc, type, ub);
step = createConvert(loc, type, step);
- auto diff = mlir::arith::SubIOp::create(*this, loc, ub, lb);
- auto add = mlir::arith::AddIOp::create(*this, loc, diff, step);
- auto div = mlir::arith::DivSIOp::create(*this, loc, add, step);
- auto cmp = mlir::arith::CmpIOp::create(
- *this, loc, mlir::arith::CmpIPredicate::sgt, div, zero);
- return mlir::arith::SelectOp::create(*this, loc, cmp, div, zero);
+
+ auto diff = createAndMaybeFold<mlir::arith::SubIOp>(fold, *this, loc, ub, lb);
+ auto add =
+ createAndMaybeFold<mlir::arith::AddIOp>(fold, *this, loc, diff, step);
+ auto div =
+ createAndMaybeFold<mlir::arith::DivSIOp>(fold, *this, loc, add, step);
+ auto cmp = createAndMaybeFold<mlir::arith::CmpIOp>(
+ fold, *this, loc, mlir::arith::CmpIPredicate::sgt, div, zero);
+ return createAndMaybeFold<mlir::arith::SelectOp>(fold, *this, loc, cmp, div,
+ zero);
}
mlir::Value fir::FirOpBuilder::genAbsentOp(mlir::Location loc,
diff --git a/flang/lib/Optimizer/Builder/HLFIRTools.cpp b/flang/lib/Optimizer/Builder/HLFIRTools.cpp
index a345dcb86e3d6..894b920c38fea 100644
--- a/flang/lib/Optimizer/Builder/HLFIRTools.cpp
+++ b/flang/lib/Optimizer/Builder/HLFIRTools.cpp
@@ -1417,13 +1417,14 @@ void hlfir::genNoAliasArrayAssignment(
rhs = hlfir::derefPointersAndAllocatables(loc, builder, rhs);
lhs = hlfir::derefPointersAndAllocatables(loc, builder, lhs);
mlir::Value lhsShape = hlfir::genShape(loc, builder, lhs);
- llvm::SmallVector<mlir::Value> lhsExtents =
- hlfir::getIndexExtents(loc, builder, lhsShape);
- mlir::Value rhsShape = hlfir::genShape(loc, builder, rhs);
- llvm::SmallVector<mlir::Value> rhsExtents =
- hlfir::getIndexExtents(loc, builder, rhsShape);
llvm::SmallVector<mlir::Value> extents =
- fir::factory::deduceOptimalExtents(lhsExtents, rhsExtents);
+ hlfir::getIndexExtents(loc, builder, lhsShape);
+ if (rhs.isArray()) {
+ mlir::Value rhsShape = hlfir::genShape(loc, builder, rhs);
+ llvm::SmallVector<mlir::Value> rhsExtents =
+ hlfir::getIndexExtents(loc, builder, rhsShape);
+ extents = fir::factory::deduceOptimalExtents(extents, rhsExtents);
+ }
hlfir::LoopNest loopNest =
hlfir::genLoopNest(loc, builder, extents,
/*isUnordered=*/true, emitWorkshareLoop);
diff --git a/flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp b/flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp
index 9fcc7d3681c39..fb0ecac81f951 100644
--- a/flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp
+++ b/flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp
@@ -15,6 +15,7 @@
#include "flang/Optimizer/Builder/DirectivesCommon.h"
#include "flang/Optimizer/Builder/FIRBuilder.h"
#include "flang/Optimizer/Builder/HLFIRTools.h"
+#include "flang/Optimizer/Builder/IntrinsicCall.h"
#include "flang/Optimizer/Dialect/FIRCG/CGOps.h"
#include "flang/Optimizer/Dialect/FIROps.h"
#include "flang/Optimizer/Dialect/FIROpsSupport.h"
@@ -565,30 +566,141 @@ OpenACCPointerLikeModel<fir::LLVMPointerType>::getPointeeTypeCategory(
return categorizePointee(pointer, varPtr, varType);
}
-static fir::ShapeOp genShapeOp(mlir::OpBuilder &builder,
- fir::SequenceType seqTy, mlir::Location loc) {
+static hlfir::Entity
+genDesignateWithTriplets(fir::FirOpBuilder &builder, mlir::Location loc,
+ hlfir::Entity &entity,
+ hlfir::DesignateOp::Subscripts &triplets,
+ mlir::Value shape, mlir::ValueRange extents) {
+ llvm::SmallVector<mlir::Value> lenParams;
+ hlfir::genLengthParameters(loc, builder, entity, lenParams);
+
+ // Compute result type of array section.
+ fir::SequenceType::Shape resultTypeShape;
+ bool shapeIsConstant = true;
+ for (mlir::Value extent : extents) {
+ if (std::optional<std::int64_t> cst_extent =
+ fir::getIntIfConstant(extent)) {
+ resultTypeShape.push_back(*cst_extent);
+ } else {
+ resultTypeShape.push_back(fir::SequenceType::getUnknownExtent());
+ shapeIsConstant = false;
+ }
+ }
+ assert(!resultTypeShape.empty() &&
+ "expect private sections to always represented as arrays");
+ mlir::Type eleTy = entity.getFortranElementType();
+ auto seqTy = fir::SequenceType::get(resultTypeShape, eleTy);
+ bool isVolatile = fir::isa_volatile_type(entity.getType());
+ bool resultNeedsBox =
+ llvm::isa<fir::BaseBoxType>(entity.getType()) || !shapeIsConstant;
+ bool isPolymorphic = fir::isPolymorphicType(entity.getType());
+ mlir::Type resultType;
+ if (isPolymorphic) {
+ resultType = fir::ClassType::get(seqTy, isVolatile);
+ } else if (resultNeedsBox) {
+ resultType = fir::BoxType::get(seqTy, isVolatile);
+ } else {
+ resultType = fir::ReferenceType::get(seqTy, isVolatile);
+ }
+
+ // Generate section with hlfir.designate.
+ auto designate = hlfir::DesignateOp::create(
+ builder, loc, resultType, entity, /*component=*/"",
+ /*componentShape=*/mlir::Value{}, triplets,
+ /*substring=*/mlir::ValueRange{}, /*complexPartAttr=*/std::nullopt, shape,
+ lenParams);
+ return hlfir::Entity{designate.getResult()};
+}
+
+// Designate uses triplets based on object lower bounds while acc.bounds are
+// zero based. This helper shift the bounds to create the designate triplets.
+static hlfir::DesignateOp::Subscripts
+genTripletsFromAccBounds(fir::FirOpBuilder &builder, mlir::Location loc,
+ const llvm::SmallVector<mlir::Value> &accBounds,
+ hlfir::Entity entity) {
+ assert(entity.getRank() * 3 == static_cast<int>(accBounds.size()) &&
+ "must get lb,ub,step for each dimension");
+ hlfir::DesignateOp::Subscripts triplets;
+ for (unsigned i = 0; i < accBounds.size(); i += 3) {
+ mlir::Value lb = hlfir::genLBound(loc, builder, entity, i / 3);
+ lb = builder.createConvert(loc, accBounds[i].getType(), lb);
+ assert(accBounds[i].getType() == accBounds[i + 1].getType() &&
+ "mix of integer types in triplets");
+ mlir::Value sliceLB =
+ builder.createOrFold<mlir::arith::AddIOp>(loc, accBounds[i], lb);
+ mlir::Value sliceUB =
+ builder.createOrFold<mlir::arith::AddIOp>(loc, accBounds[i + 1], lb);
+ triplets.emplace_back(
+ hlfir::DesignateOp::Triplet{sliceLB, sliceUB, accBounds[i + 2]});
+ }
+ return triplets;
+}
+
+static std::pair<mlir::Value, llvm::SmallVector<mlir::Value>>
+computeSectionShapeAndExtents(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::ValueRange bounds) {
llvm::SmallVector<mlir::Value> extents;
+ // Compute the fir.shape of the array section and the triplets to create
+ // hlfir.designate.
mlir::Type idxTy = builder.getIndexType();
- for (auto extent : seqTy.getShape())
- extents.push_back(mlir::arith::ConstantOp::create(
- builder, loc, idxTy, builder.getIntegerAttr(idxTy, extent)));
- return fir::ShapeOp::create(builder, loc, extents);
+ for (unsigned i = 0; i + 2 < bounds.size(); i += 3)
+ extents.push_back(builder.genExtentFromTriplet(
+ loc, bounds[i], bounds[i + 1], bounds[i + 2], idxTy, /*fold=*/true));
+ mlir::Value shape = fir::ShapeOp::create(builder, loc, extents);
+ return {shape, extents};
+}
+
+static std::pair<hlfir::Entity, hlfir::Entity>
+genArraySectionsInRecipe(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::ValueRange bounds, hlfir::Entity lhs,
+ hlfir::Entity rhs) {
+ assert(lhs.getRank() * 3 == static_cast<int>(bounds.size()) &&
+ "must get lb,ub,step for each dimension");
+ lhs = hlfir::derefPointersAndAllocatables(loc, builder, lhs);
+ rhs = hlfir::derefPointersAndAllocatables(loc, builder, rhs);
+ // Get the list of lb,ub,step values for the sections that can be used inside
+ // the recipe region.
+ auto [shape, extents] = computeSectionShapeAndExtents(builder, loc, bounds);
+ hlfir::DesignateOp::Subscripts rhsTriplets =
+ genTripletsFromAccBounds(builder, loc, bounds, rhs);
+ hlfir::DesignateOp::Subscripts lhsTriplets;
+ // Share the bounds when both rhs/lhs are known to be 1-based to avoid noise
+ // in the IR for the most common cases.
+ if (!lhs.mayHaveNonDefaultLowerBounds() &&
+ !rhs.mayHaveNonDefaultLowerBounds())
+ lhsTriplets = rhsTriplets;
+ else
+ lhsTriplets = genTripletsFromAccBounds(builder, loc, bounds, lhs);
+ hlfir::Entity leftSection =
+ genDesignateWithTriplets(builder, loc, lhs, lhsTriplets, shape, extents);
+ hlfir::Entity rightSection =
+ genDesignateWithTriplets(builder, loc, rhs, rhsTriplets, shape, extents);
+ return {leftSection, rightSection};
+}
+
+static bool boundsAreAllConstants(mlir::ValueRange bounds) {
+ for (mlir::Value bound : bounds)
+ if (!fir::getIntIfConstant(bound).has_value())
+ return false;
+ return true;
}
template <typename Ty>
mlir::Value OpenACCMappableModel<Ty>::generatePrivateInit(
- mlir::Type type, mlir::OpBuilder &builder, mlir::Location loc,
+ mlir::Type type, mlir::OpBuilder &mlirBuilder, mlir::Location loc,
mlir::TypedValue<mlir::acc::MappableType> var, llvm::StringRef varName,
- mlir::ValueRange extents, mlir::Value initVal, bool &needsDestroy) const {
- needsDestroy = false;
- mlir::Value retVal;
- mlir::Type unwrappedTy = fir::unwrapRefType(type);
- mlir::ModuleOp mod = builder.getInsertionBlock()
+ mlir::ValueRange bounds, mlir::Value initVal, bool &needsDestroy) const {
+ mlir::ModuleOp mod = mlirBuilder.getInsertionBlock()
->getParent()
->getParentOfType<mlir::ModuleOp>();
-
- if (auto recType = llvm::dyn_cast<fir::RecordType>(
- fir::getFortranElementType(unwrappedTy))) {
+ assert(mod && "failed to retrieve ModuleOp");
+ fir::FirOpBuilder builder(mlirBuilder, mod);
+
+ hlfir::Entity inputVar = hlfir::Entity{var};
+ if (inputVar.isPolymorphic())
+ TODO(loc, "OpenACC: polymorphic variable privatization");
+ if (auto recType =
+ llvm::dyn_cast<fir::RecordType>(inputVar.getFortranElementType())) {
// Need to make deep copies of allocatable components.
if (fir::isRecordWithAllocatableMember(recType))
TODO(loc,
@@ -597,117 +709,161 @@ mlir::Value OpenACCMappableModel<Ty>::generatePrivateInit(
if (fir::isRecordWithFinalRoutine(recType, mod).value_or(false))
TODO(loc, "OpenACC: privatizing derived type with user assignment or "
"final routine ");
+ // Pointer components needs to be initialized to NULL() for private-like
+ // recipes.
+ if (fir::isRecordWithDescriptorMember(recType))
+ TODO(loc, "OpenACC: privatizing derived type with pointer components");
+ }
+ bool isPointerOrAllocatable = inputVar.isMutableBox();
+ hlfir::Entity dereferencedVar =
+ hlfir::derefPointersAndAllocatables(loc, builder, inputVar);
+
+ // Step 1: Gather the address, shape, extents, and lengths parameters of the
+ // entity being privatized. Designate the array section if only a section is
+ // privatized, otherwise just use the original variable.
+ hlfir::Entity privatizedVar = dereferencedVar;
+ mlir::Value tempShape;
+ llvm::SmallVector<mlir::Value> tempExtents;
+ // TODO: while it seems best to allocate as little memory as possible and
+ // allocate only the storage for the section, this may actually have drawbacks
+ // when the array has static size and can be privatized with an alloca while
+ // the section size is dynamic and requires an dynamic allocmem. Hence, we
+ // currently allocate the full array storage in such cases. This could be
+ // improved via some kind of threshold if the base array size is large enough
+ // to justify doing a dynamic allocation with the hope that it is much
+ // smaller.
+ bool allocateSection = false;
+ bool isDynamicSectionOfStaticSizeArray =
+ !bounds.empty() &&
+ !fir::hasDynamicSize(dereferencedVar.getElementOrSequenceType()) &&
+ !boundsAreAllConstants(bounds);
+ if (!bounds.empty() && !isDynamicSectionOfStaticSizeArray) {
+ allocateSection = true;
+ hlfir::DesignateOp::Subscripts triplets;
+ std::tie(tempShape, tempExtents) =
+ computeSectionShapeAndExtents(builder, loc, bounds);
+ triplets = genTripletsFromAccBounds(builder, loc, bounds, dereferencedVar);
+ privatizedVar = genDesignateWithTriplets(builder, loc, dereferencedVar,
+ triplets, tempShape, tempExtents);
+ } else if (privatizedVar.getRank() > 0) {
+ mlir::Value shape = hlfir::genShape(loc, builder, privatizedVar);
+ tempExtents = hlfir::getExplicitExtentsFromShape(shape, builder);
+ tempShape = fir::ShapeOp::create(builder, loc, tempExtents);
+ }
+ llvm::SmallVector<mlir::Value> typeParams;
+ hlfir::genLengthParameters(loc, builder, privatizedVar, typeParams);
+ mlir::Type baseType = privatizedVar.getElementOrSequenceType();
+ // Step2: Create a temporary allocation for the privatized part.
+ mlir::Value alloc;
+ if (fir::hasDynamicSize(baseType) ||
+ (isPointerOrAllocatable && bounds.empty())) {
+ // Note: heap allocation is forced for whole pointers/allocatable so that
+ // the private POINTER/ALLOCATABLE can be deallocated/reallocated on the
+ // device inside the compute region. It may not be a requirement, and this
+ // could be revisited. In practice, this only matters for scalars since
+ // array POINTER and ALLOCATABLE always have dynamic size. Constant sections
+ // of POINTER/ALLOCATABLE can use alloca since only part of the data is
+ // privatized (it makes no sense to deallocate them).
+ alloc = builder.createHeapTemporary(loc, baseType, varName, tempExtents,
+ typeParams);
+ needsDestroy = true;
+ } else {
+ alloc = builder.createTemporary(loc, baseType, varName, tempExtents,
+ typeParams);
+ }
+ // Step3: Assign the inital value to the privatized part if any.
+ if (initVal) {
+ mlir::Value tempEntity = alloc;
+ if (fir::hasDynamicSize(baseType))
+ tempEntity =
+ fir::EmboxOp::create(builder, loc, fir::BoxType::get(baseType), alloc,
+ tempShape, /*slice=*/mlir::Value{}, typeParams);
+ hlfir::genNoAliasAssignment(
+ loc, builder, hlfir::Entity{initVal}, hlfir::Entity{tempEntity},
+ /*emitWorkshareLoop=*/false, /*temporaryLHS=*/true);
}
- fir::FirOpBuilder firBuilder(builder, mod);
- auto getDeclareOpForType = [&](mlir::Type ty) -> hlfir::DeclareOp {
- auto alloca = fir::AllocaOp::create(firBuilder, loc, ty);
- return hlfir::DeclareOp::create(firBuilder, loc, alloca, varName);
- };
+ // Making a dynamic allocation of the size of the whole base instead of the
+ // section in case of section would lead to improper deallocation because
+ // generatePrivateDestroy always deallocates the start of the section when
+ // there is a section.
+ assert(!(needsDestroy && !bounds.empty() && !allocateSection) &&
+ "dynamic allocation of the whole base in case of section is not "
+ "expected");
+
+ if (inputVar.getType() == alloc.getType() && !allocateSection)
+ return alloc;
+
+ // Step4: reconstruct the input variable from the privatized part:
+ // - get a mock base address if the privatized part is a section (so that any
+ // addressing of the input variable can be replaced by the same addressing of
+ // the privatized part even though the allocated part for the private does not
+ // cover all the input variable storage. This is relying on OpenACC
+ // constraint that any addressing of such privatized variable inside the
+ // construct region can only address the variable inside the privatized
+ // section).
+ // - reconstruct a descriptor with the same bounds and type parameters as the
+ // input if needed.
+ // - store this new descriptor in a temporary allocation if the input variable
+ // is a POINTER/ALLOCATABLE.
+ llvm::SmallVector<mlir::Value> inputVarLowerBounds, inputVarExtents;
+ if (dereferencedVar.isArray()) {
+ for (int dim = 0; dim < dereferencedVar.getRank(); ++dim) {
+ inputVarLowerBounds.push_back(
+ hlfir::genLBound(loc, builder, dereferencedVar, dim));
+ inputVarExtents.push_back(
+ hlfir::genExtent(loc, builder, dereferencedVar, dim));
+ }
+ }
- if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(unwrappedTy)) {
- if (fir::isa_trivial(seqTy.getEleTy())) {
- mlir::Value shape;
- if (seqTy.hasDynamicExtents()) {
- shape = fir::ShapeOp::create(firBuilder, loc, llvm::to_vector(extents));
- } else {
- shape = genShapeOp(firBuilder, seqTy, loc);
- }
- auto alloca = fir::AllocaOp::create(
- firBuilder, loc, seqTy, /*typeparams=*/mlir::ValueRange{}, extents);
- auto declareOp =
- hlfir::DeclareOp::create(firBuilder, loc, alloca, varName, shape);
-
- if (initVal) {
- mlir::Type idxTy = firBuilder.getIndexType();
- mlir::Type refTy = fir::ReferenceType::get(seqTy.getEleTy());
- llvm::SmallVector<fir::DoLoopOp> loops;
- llvm::SmallVector<mlir::Value> ivs;
-
- if (seqTy.hasDynamicExtents()) {
- hlfir::AssignOp::create(firBuilder, loc, initVal,
- declareOp.getBase());
- } else {
- // Generate loop nest from slowest to fastest running dimension
- for (auto ext : llvm::reverse(seqTy.getShape())) {
- auto lb = firBuilder.createIntegerConstant(loc, idxTy, 0);
- auto ub = firBuilder.createIntegerConstant(loc, idxTy, ext - 1);
- auto step = firBuilder.createIntegerConstant(loc, idxTy, 1);
- auto loop = fir::DoLoopOp::create(firBuilder, loc, lb, ub, step,
- /*unordered=*/false);
- firBuilder.setInsertionPointToStart(loop.getBody());
- loops.push_back(loop);
- ivs.push_back(loop.getInductionVar());
- }
- // Reverse IVs to match CoordinateOp's canonical index order.
- std::reverse(ivs.begin(), ivs.end());
- auto coord = fir::CoordinateOp::create(firBuilder, loc, refTy,
- declareOp.getBase(), ivs);
- fir::StoreOp::create(firBuilder, loc, initVal, coord);
- firBuilder.setInsertionPointAfter(loops[0]);
- }
- }
- retVal = declareOp.getBase();
+ mlir::Value privateVarBaseAddr = alloc;
+ if (allocateSection) {
+ // To compute the mock base address without doing pointer arithmetic,
+ // compute: TYPE, TEMP(ZERO_BASED_SECTION_LB:) MOCK_BASE = TEMP(0)
+ // This addresses the section "backwards" (0 <= ZERO_BASED_SECTION_LB). This
+ // is currently OK, but care should be taken to avoid tripping bound checks
+ // if added in the future.
+ mlir::Type inputBaseAddrType =
+ dereferencedVar.getBoxType().getBaseAddressType();
+ mlir::Value tempBaseAddr =
+ builder.createConvert(loc, inputBaseAddrType, alloc);
+ mlir::Value zero =
+ builder.createIntegerConstant(loc, builder.getIndexType(), 0);
+ llvm::SmallVector<mlir::Value> lowerBounds;
+ llvm::SmallVector<mlir::Value> zeros;
+ for (unsigned i = 0; i < bounds.size(); i += 3) {
+ lowerBounds.push_back(bounds[i]);
+ zeros.push_back(zero);
}
- } else if (auto boxTy =
- mlir::dyn_cast_or_null<fir::BaseBoxType>(unwrappedTy)) {
- mlir::Type innerTy = fir::unwrapRefType(boxTy.getEleTy());
- if (fir::isa_trivial(innerTy)) {
- retVal = getDeclareOpForType(unwrappedTy).getBase();
- mlir::Value allocatedScalar =
- fir::AllocMemOp::create(builder, loc, innerTy);
- mlir::Value firClass =
- fir::EmboxOp::create(builder, loc, boxTy, allocatedScalar);
- fir::StoreOp::create(builder, loc, firClass, retVal);
- needsDestroy = true;
- } else if (mlir::isa<fir::SequenceType>(innerTy)) {
- hlfir::Entity source = hlfir::Entity{var};
- auto [temp, cleanupFlag] =
- hlfir::createTempFromMold(loc, firBuilder, source);
- if (fir::isa_ref_type(type)) {
- // When the temp is created - it is not a reference - thus we can
- // end up with a type inconsistency. Therefore ensure storage is created
- // for it.
- retVal = getDeclareOpForType(unwrappedTy).getBase();
- mlir::Value storeDst = retVal;
- if (fir::unwrapRefType(retVal.getType()) != temp.getType()) {
- // `createTempFromMold` makes the unfortunate choice to lose the
- // `fir.heap` and `fir.ptr` types when wrapping with a box. Namely,
- // when wrapping a `fir.heap<fir.array>`, it will create instead a
- // `fir.box<fir.array>`. Cast here to deal with this inconsistency.
- storeDst = firBuilder.createConvert(
- loc, firBuilder.getRefType(temp.getType()), retVal);
- }
- fir::StoreOp::create(builder, loc, temp, storeDst);
- } else {
- retVal = temp;
- }
- // If heap was allocated, a destroy is required later.
- if (cleanupFlag)
- needsDestroy = true;
+ mlir::Value offsetShapeShift =
+ builder.genShape(loc, lowerBounds, inputVarExtents);
+ mlir::Type eleRefType =
+ builder.getRefType(privatizedVar.getFortranElementType());
+ mlir::Value mockBase = fir::ArrayCoorOp::create(
+ builder, loc, eleRefType, tempBaseAddr, offsetShapeShift,
+ /*slice=*/mlir::Value{}, /*indices=*/zeros,
+ /*typeParams=*/mlir::ValueRange{});
+ privateVarBaseAddr =
+ builder.createConvert(loc, inputBaseAddrType, mockBase);
+ }
+
+ mlir::Value retVal = privateVarBaseAddr;
+ if (inputVar.isBoxAddressOrValue()) {
+ // Recreate descriptor with same bounds as the input variable.
+ mlir::Value shape;
+ if (!inputVarExtents.empty())
+ shape = builder.genShape(loc, inputVarLowerBounds, inputVarExtents);
+ mlir::Value box = fir::EmboxOp::create(builder, loc, inputVar.getBoxType(),
+ privateVarBaseAddr, shape,
+ /*slice=*/mlir::Value{}, typeParams);
+ if (inputVar.isMutableBox()) {
+ mlir::Value boxAlloc =
+ fir::AllocaOp::create(builder, loc, inputVar.getBoxType());
+ fir::StoreOp::create(builder, loc, box, boxAlloc);
+ retVal = boxAlloc;
} else {
- TODO(loc, "Unsupported boxed type for OpenACC private-like recipe");
+ retVal = box;
}
- if (initVal) {
- hlfir::AssignOp::create(builder, loc, initVal, retVal);
- }
- } else if (llvm::isa<fir::BoxCharType, fir::CharacterType>(unwrappedTy)) {
- TODO(loc, "Character type for OpenACC private-like recipe");
- } else {
- assert((fir::isa_trivial(unwrappedTy) ||
- llvm::isa<fir::RecordType>(unwrappedTy)) &&
- "expected numerical, logical, and derived type without length "
- "parameters");
- auto declareOp = getDeclareOpForType(unwrappedTy);
- if (initVal && fir::isa_trivial(unwrappedTy)) {
- auto convert = firBuilder.createConvert(loc, unwrappedTy, initVal);
- fir::StoreOp::create(firBuilder, loc, convert, declareOp.getBase());
- } else if (initVal) {
- // hlfir.assign with temporary LHS flag should just do it. Not implemented
- // because not clear it is needed, so cannot be tested.
- TODO(loc, "initial value for derived type in private-like recipe");
- }
- retVal = declareOp.getBase();
}
return retVal;
}
@@ -735,43 +891,250 @@ OpenACCMappableModel<fir::PointerType>::generatePrivateInit(
mlir::TypedValue<mlir::acc::MappableType> var, llvm::StringRef varName,
mlir::ValueRange extents, mlir::Value initVal, bool &needsDestroy) const;
+template <typename Ty>
+bool OpenACCMappableModel<Ty>::generateCopy(
+ mlir::Type type, mlir::OpBuilder &mlirBuilder, mlir::Location loc,
+ mlir::TypedValue<mlir::acc::MappableType> src,
+ mlir::TypedValue<mlir::acc::MappableType> dest,
+ mlir::ValueRange bounds) const {
+ mlir::ModuleOp mod =
+ mlirBuilder.getBlock()->getParent()->getParentOfType<mlir::ModuleOp>();
+ assert(mod && "failed to retrieve parent module");
+ fir::FirOpBuilder builder(mlirBuilder, mod);
+ hlfir::Entity source{src};
+ hlfir::Entity destination{dest};
+
+ source = hlfir::derefPointersAndAllocatables(loc, builder, source);
+ destination = hlfir::derefPointersAndAllocatables(loc, builder, destination);
+
+ if (!bounds.empty())
+ std::tie(source, destination) =
+ genArraySectionsInRecipe(builder, loc, bounds, source, destination);
+ // The source and the destination of the firstprivate copy cannot alias,
+ // the destination is already properly allocated, so a simple assignment
+ // can be generated right away to avoid ending-up with runtime calls
+ // for arrays of numerical, logical and, character types.
+ //
+ // The temporary_lhs flag allows indicating that user defined assignments
+ // should not be called while copying components, and that the LHS and RHS
+ // are known to not alias since the LHS is a created object.
+ //
+ // TODO: detect cases where user defined assignment is needed and add a TODO.
+ // using temporary_lhs allows more aggressive optimizations of simple derived
+ // types. Existing compilers supporting OpenACC do not call user defined
+ // assignments, some use case is needed to decide what to do.
+ source = hlfir::loadTrivialScalar(loc, builder, source);
+ hlfir::AssignOp::create(builder, loc, source, destination, /*realloc=*/false,
+ /*keep_lhs_length_if_realloc=*/false,
+ /*temporary_lhs=*/true);
+ return true;
+}
+
+template bool OpenACCMappableModel<fir::BaseBoxType>::generateCopy(
+ mlir::Type, mlir::OpBuilder &, mlir::Location,
+ mlir::TypedValue<mlir::acc::MappableType>,
+ mlir::TypedValue<mlir::acc::MappableType>, mlir::ValueRange) const;
+template bool OpenACCMappableModel<fir::ReferenceType>::generateCopy(
+ mlir::Type, mlir::OpBuilder &, mlir::Location,
+ mlir::TypedValue<mlir::acc::MappableType>,
+ mlir::TypedValue<mlir::acc::MappableType>, mlir::ValueRange) const;
+template bool OpenACCMappableModel<fir::PointerType>::generateCopy(
+ mlir::Type, mlir::OpBuilder &, mlir::Location,
+ mlir::TypedValue<mlir::acc::MappableType>,
+ mlir::TypedValue<mlir::acc::MappableType>, mlir::ValueRange) const;
+template bool OpenACCMappableModel<fir::HeapType>::generateCopy(
+ mlir::Type, mlir::OpBuilder &, mlir::Location,
+ mlir::TypedValue<mlir::acc::MappableType>,
+ mlir::TypedValue<mlir::acc::MappableType>, mlir::ValueRange) const;
+
+template <typename Op>
+static mlir::Value genLogicalCombiner(fir::FirOpBuilder &builder,
+ mlir::Location loc, mlir::Value value1,
+ mlir::Value value2) {
+ mlir::Type i1 = builder.getI1Type();
+ mlir::Value v1 = fir::ConvertOp::create(builder, loc, i1, value1);
+ mlir::Value v2 = fir::ConvertOp::create(builder, loc, i1, value2);
+ mlir::Value combined = Op::create(builder, loc, v1, v2);
+ return fir::ConvertOp::create(builder, loc, value1.getType(), combined);
+}
+
+static mlir::Value genComparisonCombiner(fir::FirOpBuilder &builder,
+ mlir::Location loc,
+ mlir::arith::CmpIPredicate pred,
+ mlir::Value value1,
+ mlir::Value value2) {
+ mlir::Type i1 = builder.getI1Type();
+ mlir::Value v1 = fir::ConvertOp::create(builder, loc, i1, value1);
+ mlir::Value v2 = fir::ConvertOp::create(builder, loc, i1, value2);
+ mlir::Value add = mlir::arith::CmpIOp::create(builder, loc, pred, v1, v2);
+ return fir::ConvertOp::create(builder, loc, value1.getType(), add);
+}
+
+static mlir::Value genScalarCombiner(fir::FirOpBuilder &builder,
+ mlir::Location loc,
+ mlir::acc::ReductionOperator op,
+ mlir::Type ty, mlir::Value value1,
+ mlir::Value value2) {
+ value1 = builder.loadIfRef(loc, value1);
+ value2 = builder.loadIfRef(loc, value2);
+ if (op == mlir::acc::ReductionOperator::AccAdd) {
+ if (ty.isIntOrIndex())
+ return mlir::arith::AddIOp::create(builder, loc, value1, value2);
+ if (mlir::isa<mlir::FloatType>(ty))
+ return mlir::arith::AddFOp::create(builder, loc, value1, value2);
+ if (auto cmplxTy = mlir::dyn_cast_or_null<mlir::ComplexType>(ty))
+ return fir::AddcOp::create(builder, loc, value1, value2);
+ TODO(loc, "reduction add type");
+ }
+
+ if (op == mlir::acc::ReductionOperator::AccMul) {
+ if (ty.isIntOrIndex())
+ return mlir::arith::MulIOp::create(builder, loc, value1, value2);
+ if (mlir::isa<mlir::FloatType>(ty))
+ return mlir::arith::MulFOp::create(builder, loc, value1, value2);
+ if (mlir::isa<mlir::ComplexType>(ty))
+ return fir::MulcOp::create(builder, loc, value1, value2);
+ TODO(loc, "reduction mul type");
+ }
+
+ if (op == mlir::acc::ReductionOperator::AccMin)
+ return fir::genMin(builder, loc, {value1, value2});
+
+ if (op == mlir::acc::ReductionOperator::AccMax)
+ return fir::genMax(builder, loc, {value1, value2});
+
+ if (op == mlir::acc::ReductionOperator::AccIand)
+ return mlir::arith::AndIOp::create(builder, loc, value1, value2);
+
+ if (op == mlir::acc::ReductionOperator::AccIor)
+ return mlir::arith::OrIOp::create(builder, loc, value1, value2);
+
+ if (op == mlir::acc::ReductionOperator::AccXor)
+ return mlir::arith::XOrIOp::create(builder, loc, value1, value2);
+
+ if (op == mlir::acc::ReductionOperator::AccLand)
+ return genLogicalCombiner<mlir::arith::AndIOp>(builder, loc, value1,
+ value2);
+
+ if (op == mlir::acc::ReductionOperator::AccLor)
+ return genLogicalCombiner<mlir::arith::OrIOp>(builder, loc, value1, value2);
+
+ if (op == mlir::acc::ReductionOperator::AccEqv)
+ return genComparisonCombiner(builder, loc, mlir::arith::CmpIPredicate::eq,
+ value1, value2);
+
+ if (op == mlir::acc::ReductionOperator::AccNeqv)
+ return genComparisonCombiner(builder, loc, mlir::arith::CmpIPredicate::ne,
+ value1, value2);
+
+ TODO(loc, "reduction operator");
+}
+
+template <typename Ty>
+bool OpenACCMappableModel<Ty>::generateCombiner(
+ mlir::Type type, mlir::OpBuilder &mlirBuilder, mlir::Location loc,
+ mlir::TypedValue<mlir::acc::MappableType> dest,
+ mlir::TypedValue<mlir::acc::MappableType> source, mlir::ValueRange bounds,
+ mlir::acc::ReductionOperator op, mlir::Attribute fastmathFlags) const {
+ mlir::ModuleOp mod =
+ mlirBuilder.getBlock()->getParent()->getParentOfType<mlir::ModuleOp>();
+ assert(mod && "failed to retrieve parent module");
+ fir::FirOpBuilder builder(mlirBuilder, mod);
+ if (fastmathFlags)
+ if (auto fastMathAttr =
+ mlir::dyn_cast<mlir::arith::FastMathFlagsAttr>(fastmathFlags))
+ builder.setFastMathFlags(fastMathAttr.getValue());
+ // Generate loops that combine and assign the inputs into dest (or array
+ // section of the inputs when there are bounds).
+ hlfir::Entity srcSection{source};
+ hlfir::Entity destSection{dest};
+ if (!bounds.empty()) {
+ std::tie(srcSection, destSection) =
+ genArraySectionsInRecipe(builder, loc, bounds, srcSection, destSection);
+ }
+
+ mlir::Type elementType = fir::getFortranElementType(dest.getType());
+ auto genKernel = [&](mlir::Location l, fir::FirOpBuilder &b,
+ hlfir::Entity srcElementValue,
+ hlfir::Entity destElementValue) -> hlfir::Entity {
+ return hlfir::Entity{genScalarCombiner(builder, loc, op, elementType,
+ srcElementValue, destElementValue)};
+ };
+ hlfir::genNoAliasAssignment(loc, builder, srcSection, destSection,
+ /*emitWorkshareLoop=*/false,
+ /*temporaryLHS=*/false, genKernel);
+ return true;
+}
+
+template bool OpenACCMappableModel<fir::BaseBoxType>::generateCombiner(
+ mlir::Type, mlir::OpBuilder &, mlir::Location,
+ mlir::TypedValue<mlir::acc::MappableType>,
+ mlir::TypedValue<mlir::acc::MappableType>, mlir::ValueRange,
+ mlir::acc::ReductionOperator op, mlir::Attribute) const;
+template bool OpenACCMappableModel<fir::ReferenceType>::generateCombiner(
+ mlir::Type, mlir::OpBuilder &, mlir::Location,
+ mlir::TypedValue<mlir::acc::MappableType>,
+ mlir::TypedValue<mlir::acc::MappableType>, mlir::ValueRange,
+ mlir::acc::ReductionOperator op, mlir::Attribute) const;
+template bool OpenACCMappableModel<fir::PointerType>::generateCombiner(
+ mlir::Type, mlir::OpBuilder &, mlir::Location,
+ mlir::TypedValue<mlir::acc::MappableType>,
+ mlir::TypedValue<mlir::acc::MappableType>, mlir::ValueRange,
+ mlir::acc::ReductionOperator op, mlir::Attribute) const;
+template bool OpenACCMappableModel<fir::HeapType>::generateCombiner(
+ mlir::Type, mlir::OpBuilder &, mlir::Location,
+ mlir::TypedValue<mlir::acc::MappableType>,
+ mlir::TypedValue<mlir::acc::MappableType>, mlir::ValueRange,
+ mlir::acc::ReductionOperator op, mlir::Attribute) const;
+
template <typename Ty>
bool OpenACCMappableModel<Ty>::generatePrivateDestroy(
- mlir::Type type, mlir::OpBuilder &builder, mlir::Location loc,
- mlir::Value privatized) const {
- mlir::Type unwrappedTy = fir::unwrapRefType(type);
- // For boxed scalars allocated with AllocMem during init, free the heap.
- if (auto boxTy = mlir::dyn_cast_or_null<fir::BaseBoxType>(unwrappedTy)) {
- mlir::Value boxVal = privatized;
- if (fir::isa_ref_type(boxVal.getType()))
- boxVal = fir::LoadOp::create(builder, loc, boxVal);
- mlir::Value addr = fir::BoxAddrOp::create(builder, loc, boxVal);
- // FreeMem only accepts fir.heap and this may not be represented in the box
- // type if the privatized entity is not an allocatable.
+ mlir::Type type, mlir::OpBuilder &mlirBuilder, mlir::Location loc,
+ mlir::Value privatized, mlir::ValueRange bounds) const {
+ hlfir::Entity inputVar = hlfir::Entity{privatized};
+ mlir::ModuleOp mod =
+ mlirBuilder.getBlock()->getParent()->getParentOfType<mlir::ModuleOp>();
+ assert(mod && "failed to retrieve parent module");
+ fir::FirOpBuilder builder(mlirBuilder, mod);
+ auto genFreeRawAddress = [&](hlfir::Entity entity) {
+ mlir::Value addr = hlfir::genVariableRawAddress(loc, builder, entity);
mlir::Type heapType =
fir::HeapType::get(fir::unwrapRefType(addr.getType()));
if (heapType != addr.getType())
addr = fir::ConvertOp::create(builder, loc, heapType, addr);
fir::FreeMemOp::create(builder, loc, addr);
+ };
+ if (bounds.empty()) {
+ genFreeRawAddress(inputVar);
return true;
}
-
- // Nothing to do for other categories by default, they are stack allocated.
+ // The input variable is an array section, the base address is not the real
+ // allocation. Compute the section base address and deallocate that.
+ hlfir::Entity dereferencedVar =
+ hlfir::derefPointersAndAllocatables(loc, builder, inputVar);
+ hlfir::DesignateOp::Subscripts triplets;
+ auto [tempShape, tempExtents] =
+ computeSectionShapeAndExtents(builder, loc, bounds);
+ (void)tempExtents;
+ triplets = genTripletsFromAccBounds(builder, loc, bounds, dereferencedVar);
+ hlfir::Entity arraySection = genDesignateWithTriplets(
+ builder, loc, dereferencedVar, triplets, tempShape, tempExtents);
+ genFreeRawAddress(arraySection);
return true;
}
template bool OpenACCMappableModel<fir::BaseBoxType>::generatePrivateDestroy(
mlir::Type type, mlir::OpBuilder &builder, mlir::Location loc,
- mlir::Value privatized) const;
+ mlir::Value privatized, mlir::ValueRange bounds) const;
template bool OpenACCMappableModel<fir::ReferenceType>::generatePrivateDestroy(
mlir::Type type, mlir::OpBuilder &builder, mlir::Location loc,
- mlir::Value privatized) const;
+ mlir::Value privatized, mlir::ValueRange bounds) const;
template bool OpenACCMappableModel<fir::HeapType>::generatePrivateDestroy(
mlir::Type type, mlir::OpBuilder &builder, mlir::Location loc,
- mlir::Value privatized) const;
+ mlir::Value privatized, mlir::ValueRange bounds) const;
template bool OpenACCMappableModel<fir::PointerType>::generatePrivateDestroy(
mlir::Type type, mlir::OpBuilder &builder, mlir::Location loc,
- mlir::Value privatized) const;
+ mlir::Value privatized, mlir::ValueRange bounds) const;
template <typename Ty>
mlir::Value OpenACCPointerLikeModel<Ty>::genAllocate(
diff --git a/flang/lib/Optimizer/OpenACC/Support/FIROpenACCUtils.cpp b/flang/lib/Optimizer/OpenACC/Support/FIROpenACCUtils.cpp
index e5b8123305c62..b88936426657d 100644
--- a/flang/lib/Optimizer/OpenACC/Support/FIROpenACCUtils.cpp
+++ b/flang/lib/Optimizer/OpenACC/Support/FIROpenACCUtils.cpp
@@ -237,15 +237,9 @@ std::string getRecipeName(mlir::acc::RecipeKind kind, Type type, Value var,
switch (kind) {
case mlir::acc::RecipeKind::private_recipe:
prefixOS << "privatization";
- // Private recipes do not currently include bounds in the name
- // TODO: They should include them - but lowering tests would need to
- // be updated.
break;
case mlir::acc::RecipeKind::firstprivate_recipe:
prefixOS << "firstprivatization";
- // Add bounds to the prefix if applicable (only for firstprivate)
- if (!bounds.empty() && areAllBoundsConstant(bounds))
- prefixOS << getBoundsString(bounds);
break;
case mlir::acc::RecipeKind::reduction_recipe:
prefixOS << "reduction";
@@ -253,12 +247,12 @@ std::string getRecipeName(mlir::acc::RecipeKind kind, Type type, Value var,
if (reductionOp != mlir::acc::ReductionOperator::AccNone)
prefixOS << "_"
<< mlir::acc::stringifyReductionOperator(reductionOp).str();
- // Add bounds to the prefix if applicable (only for reduction)
- if (!bounds.empty() && areAllBoundsConstant(bounds))
- prefixOS << getBoundsString(bounds);
break;
}
+ if (!bounds.empty())
+ prefixOS << getBoundsString(bounds);
+
auto kindMap = var && var.getDefiningOp()
? fir::getKindMapping(var.getDefiningOp())
: fir::KindMapping(type.getContext());
diff --git a/flang/test/Fir/OpenACC/recipe-populate-firstprivate.mlir b/flang/test/Fir/OpenACC/recipe-populate-firstprivate.mlir
index 0c3f3fea13fa0..a033734d2ff0e 100644
--- a/flang/test/Fir/OpenACC/recipe-populate-firstprivate.mlir
+++ b/flang/test/Fir/OpenACC/recipe-populate-firstprivate.mlir
@@ -8,8 +8,7 @@
// CHECK: acc.firstprivate.recipe @firstprivate_scalar : !fir.ref<f32> init {
// CHECK: ^bb0(%{{.*}}: !fir.ref<f32>):
// CHECK: %[[ALLOC:.*]] = fir.alloca f32
-// CHECK: %{{.*}}:2 = hlfir.declare %[[ALLOC]] {uniq_name = "scalar"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
-// CHECK: acc.yield %{{.*}}#0 : !fir.ref<f32>
+// CHECK: acc.yield %[[ALLOC]] : !fir.ref<f32>
// CHECK: } copy {
// CHECK: ^bb0(%[[SRC:.*]]: !fir.ref<f32>, %[[DST:.*]]: !fir.ref<f32>):
// CHECK: %[[LOAD:.*]] = fir.load %[[SRC]] : !fir.ref<f32>
@@ -31,8 +30,7 @@ func.func @test_scalar() {
// CHECK: acc.firstprivate.recipe @firstprivate_int : !fir.ref<i32> init {
// CHECK: ^bb0(%{{.*}}: !fir.ref<i32>):
// CHECK: %[[ALLOC:.*]] = fir.alloca i32
-// CHECK: %{{.*}}:2 = hlfir.declare %[[ALLOC]] {uniq_name = "int"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
-// CHECK: acc.yield %{{.*}}#0 : !fir.ref<i32>
+// CHECK: acc.yield %[[ALLOC]] : !fir.ref<i32>
// CHECK: } copy {
// CHECK: ^bb0(%[[SRC:.*]]: !fir.ref<i32>, %[[DST:.*]]: !fir.ref<i32>):
// CHECK: %[[LOAD:.*]] = fir.load %[[SRC]] : !fir.ref<i32>
@@ -54,8 +52,7 @@ func.func @test_int() {
// CHECK: acc.firstprivate.recipe @firstprivate_logical : !fir.ref<!fir.logical<4>> init {
// CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.logical<4>>):
// CHECK: %[[ALLOC:.*]] = fir.alloca !fir.logical<4>
-// CHECK: %{{.*}}:2 = hlfir.declare %[[ALLOC]] {uniq_name = "logical"} : (!fir.ref<!fir.logical<4>>) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>)
-// CHECK: acc.yield %{{.*}}#0 : !fir.ref<!fir.logical<4>>
+// CHECK: acc.yield %[[ALLOC]] : !fir.ref<!fir.logical<4>>
// CHECK: } copy {
// CHECK: ^bb0(%[[SRC:.*]]: !fir.ref<!fir.logical<4>>, %[[DST:.*]]: !fir.ref<!fir.logical<4>>):
// CHECK: %[[LOAD:.*]] = fir.load %[[SRC]] : !fir.ref<!fir.logical<4>>
@@ -77,8 +74,7 @@ func.func @test_logical() {
// CHECK: acc.firstprivate.recipe @firstprivate_complex : !fir.ref<complex<f32>> init {
// CHECK: ^bb0(%{{.*}}: !fir.ref<complex<f32>>):
// CHECK: %[[ALLOC:.*]] = fir.alloca complex<f32>
-// CHECK: %{{.*}}:2 = hlfir.declare %[[ALLOC]] {uniq_name = "complex"} : (!fir.ref<complex<f32>>) -> (!fir.ref<complex<f32>>, !fir.ref<complex<f32>>)
-// CHECK: acc.yield %{{.*}}#0 : !fir.ref<complex<f32>>
+// CHECK: acc.yield %[[ALLOC]] : !fir.ref<complex<f32>>
// CHECK: } copy {
// CHECK: ^bb0(%[[SRC:.*]]: !fir.ref<complex<f32>>, %[[DST:.*]]: !fir.ref<complex<f32>>):
// CHECK: %[[LOAD:.*]] = fir.load %[[SRC]] : !fir.ref<complex<f32>>
@@ -99,11 +95,8 @@ func.func @test_complex() {
// Test 1D static array
// CHECK: acc.firstprivate.recipe @firstprivate_array_1d : !fir.ref<!fir.array<100xf32>> init {
// CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<100xf32>>):
-// CHECK: %[[C100:.*]] = arith.constant 100 : index
-// CHECK: %[[SHAPE:.*]] = fir.shape %[[C100]] : (index) -> !fir.shape<1>
// CHECK: %[[ALLOC:.*]] = fir.alloca !fir.array<100xf32>
-// CHECK: %{{.*}}:2 = hlfir.declare %[[ALLOC]](%[[SHAPE]]) {uniq_name = "array_1d"} : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<100xf32>>, !fir.ref<!fir.array<100xf32>>)
-// CHECK: acc.yield %{{.*}}#0 : !fir.ref<!fir.array<100xf32>>
+// CHECK: acc.yield %[[ALLOC]] : !fir.ref<!fir.array<100xf32>>
// CHECK: } copy {
// CHECK: ^bb0(%[[SRC:.*]]: !fir.ref<!fir.array<100xf32>>, %[[DST:.*]]: !fir.ref<!fir.array<100xf32>>):
// CHECK: hlfir.assign %[[SRC]] to %[[DST]] : !fir.ref<!fir.array<100xf32>>, !fir.ref<!fir.array<100xf32>>
@@ -123,12 +116,8 @@ func.func @test_array_1d() {
// Test 2D static array
// CHECK: acc.firstprivate.recipe @firstprivate_array_2d : !fir.ref<!fir.array<10x20xi32>> init {
// CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<10x20xi32>>):
-// CHECK: %[[C10:.*]] = arith.constant 10 : index
-// CHECK: %[[C20:.*]] = arith.constant 20 : index
-// CHECK: %[[SHAPE:.*]] = fir.shape %[[C10]], %[[C20]] : (index, index) -> !fir.shape<2>
// CHECK: %[[ALLOC:.*]] = fir.alloca !fir.array<10x20xi32>
-// CHECK: %{{.*}}:2 = hlfir.declare %[[ALLOC]](%[[SHAPE]]) {uniq_name = "array_2d"} : (!fir.ref<!fir.array<10x20xi32>>, !fir.shape<2>) -> (!fir.ref<!fir.array<10x20xi32>>, !fir.ref<!fir.array<10x20xi32>>)
-// CHECK: acc.yield %{{.*}}#0 : !fir.ref<!fir.array<10x20xi32>>
+// CHECK: acc.yield %[[ALLOC]] : !fir.ref<!fir.array<10x20xi32>>
// CHECK: } copy {
// CHECK: ^bb0(%[[SRC:.*]]: !fir.ref<!fir.array<10x20xi32>>, %[[DST:.*]]: !fir.ref<!fir.array<10x20xi32>>):
// CHECK: hlfir.assign %[[SRC]] to %[[DST]] : !fir.ref<!fir.array<10x20xi32>>, !fir.ref<!fir.array<10x20xi32>>
@@ -149,8 +138,7 @@ func.func @test_array_2d() {
// CHECK: acc.firstprivate.recipe @firstprivate_derived : !fir.ref<!fir.type<_QTpoint{x:f32,y:f32,z:f32}>> init {
// CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.type<_QTpoint{x:f32,y:f32,z:f32}>>):
// CHECK: %[[ALLOC:.*]] = fir.alloca !fir.type<_QTpoint{x:f32,y:f32,z:f32}>
-// CHECK: %{{.*}}:2 = hlfir.declare %[[ALLOC]] {uniq_name = "derived"} : (!fir.ref<!fir.type<_QTpoint{x:f32,y:f32,z:f32}>>) -> (!fir.ref<!fir.type<_QTpoint{x:f32,y:f32,z:f32}>>, !fir.ref<!fir.type<_QTpoint{x:f32,y:f32,z:f32}>>)
-// CHECK: acc.yield %{{.*}}#0 : !fir.ref<!fir.type<_QTpoint{x:f32,y:f32,z:f32}>>
+// CHECK: acc.yield %[[ALLOC]] : !fir.ref<!fir.type<_QTpoint{x:f32,y:f32,z:f32}>>
// CHECK: } copy {
// CHECK: ^bb0(%[[SRC:.*]]: !fir.ref<!fir.type<_QTpoint{x:f32,y:f32,z:f32}>>, %[[DST:.*]]: !fir.ref<!fir.type<_QTpoint{x:f32,y:f32,z:f32}>>):
// CHECK: hlfir.assign %[[SRC]] to %[[DST]] : !fir.ref<!fir.type<_QTpoint{x:f32,y:f32,z:f32}>>, !fir.ref<!fir.type<_QTpoint{x:f32,y:f32,z:f32}>>
diff --git a/flang/test/Fir/OpenACC/recipe-populate-private.mlir b/flang/test/Fir/OpenACC/recipe-populate-private.mlir
index aeb60d6b4a37f..f5200f70a3ba8 100644
--- a/flang/test/Fir/OpenACC/recipe-populate-private.mlir
+++ b/flang/test/Fir/OpenACC/recipe-populate-private.mlir
@@ -8,8 +8,7 @@
// CHECK: acc.private.recipe @private_scalar : !fir.ref<f32> init {
// CHECK: ^bb0(%{{.*}}: !fir.ref<f32>):
// CHECK: %[[ALLOC:.*]] = fir.alloca f32
-// CHECK: %{{.*}}:2 = hlfir.declare %[[ALLOC]] {uniq_name = "scalar"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
-// CHECK: acc.yield %{{.*}}#0 : !fir.ref<f32>
+// CHECK: acc.yield %[[ALLOC]] : !fir.ref<f32>
// CHECK: }
// CHECK-NOT: destroy
@@ -26,8 +25,7 @@ func.func @test_scalar() {
// CHECK: acc.private.recipe @private_logical : !fir.ref<!fir.logical<4>> init {
// CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.logical<4>>):
// CHECK: %[[ALLOC:.*]] = fir.alloca !fir.logical<4>
-// CHECK: %{{.*}}:2 = hlfir.declare %[[ALLOC]] {uniq_name = "logical"} : (!fir.ref<!fir.logical<4>>) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>)
-// CHECK: acc.yield %{{.*}}#0 : !fir.ref<!fir.logical<4>>
+// CHECK: acc.yield %[[ALLOC]] : !fir.ref<!fir.logical<4>>
// CHECK: }
// CHECK-NOT: destroy
@@ -44,8 +42,7 @@ func.func @test_logical() {
// CHECK: acc.private.recipe @private_complex : !fir.ref<complex<f32>> init {
// CHECK: ^bb0(%{{.*}}: !fir.ref<complex<f32>>):
// CHECK: %[[ALLOC:.*]] = fir.alloca complex<f32>
-// CHECK: %{{.*}}:2 = hlfir.declare %[[ALLOC]] {uniq_name = "complex"} : (!fir.ref<complex<f32>>) -> (!fir.ref<complex<f32>>, !fir.ref<complex<f32>>)
-// CHECK: acc.yield %{{.*}}#0 : !fir.ref<complex<f32>>
+// CHECK: acc.yield %[[ALLOC]] : !fir.ref<complex<f32>>
// CHECK: }
// CHECK-NOT: destroy
@@ -61,11 +58,8 @@ func.func @test_complex() {
// Test 1D static array
// CHECK: acc.private.recipe @private_array_1d : !fir.ref<!fir.array<100xf32>> init {
// CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<100xf32>>):
-// CHECK: %[[C100:.*]] = arith.constant 100 : index
-// CHECK: %[[SHAPE:.*]] = fir.shape %[[C100]] : (index) -> !fir.shape<1>
// CHECK: %[[ALLOC:.*]] = fir.alloca !fir.array<100xf32>
-// CHECK: %{{.*}}:2 = hlfir.declare %[[ALLOC]](%[[SHAPE]]) {uniq_name = "array_1d"} : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<100xf32>>, !fir.ref<!fir.array<100xf32>>)
-// CHECK: acc.yield %{{.*}}#0 : !fir.ref<!fir.array<100xf32>>
+// CHECK: acc.yield %[[ALLOC]] : !fir.ref<!fir.array<100xf32>>
// CHECK: }
// CHECK-NOT: destroy
@@ -81,13 +75,8 @@ func.func @test_array_1d() {
// Test 3D static array
// CHECK: acc.private.recipe @private_array_3d : !fir.ref<!fir.array<5x10x15xi32>> init {
// CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<5x10x15xi32>>):
-// CHECK: %[[C5:.*]] = arith.constant 5 : index
-// CHECK: %[[C10:.*]] = arith.constant 10 : index
-// CHECK: %[[C15:.*]] = arith.constant 15 : index
-// CHECK: %[[SHAPE:.*]] = fir.shape %[[C5]], %[[C10]], %[[C15]] : (index, index, index) -> !fir.shape<3>
// CHECK: %[[ALLOC:.*]] = fir.alloca !fir.array<5x10x15xi32>
-// CHECK: %{{.*}}:2 = hlfir.declare %[[ALLOC]](%[[SHAPE]]) {uniq_name = "array_3d"} : (!fir.ref<!fir.array<5x10x15xi32>>, !fir.shape<3>) -> (!fir.ref<!fir.array<5x10x15xi32>>, !fir.ref<!fir.array<5x10x15xi32>>)
-// CHECK: acc.yield %{{.*}}#0 : !fir.ref<!fir.array<5x10x15xi32>>
+// CHECK: acc.yield %[[ALLOC]] : !fir.ref<!fir.array<5x10x15xi32>>
// CHECK: }
// CHECK-NOT: destroy
@@ -104,8 +93,7 @@ func.func @test_array_3d() {
// CHECK: acc.private.recipe @private_derived : !fir.ref<!fir.type<_QTpoint{x:f32,y:f32,z:f32}>> init {
// CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.type<_QTpoint{x:f32,y:f32,z:f32}>>):
// CHECK: %[[ALLOC:.*]] = fir.alloca !fir.type<_QTpoint{x:f32,y:f32,z:f32}>
-// CHECK: %{{.*}}:2 = hlfir.declare %[[ALLOC]] {uniq_name = "derived"} : (!fir.ref<!fir.type<_QTpoint{x:f32,y:f32,z:f32}>>) -> (!fir.ref<!fir.type<_QTpoint{x:f32,y:f32,z:f32}>>, !fir.ref<!fir.type<_QTpoint{x:f32,y:f32,z:f32}>>)
-// CHECK: acc.yield %{{.*}}#0 : !fir.ref<!fir.type<_QTpoint{x:f32,y:f32,z:f32}>>
+// CHECK: acc.yield %[[ALLOC]] : !fir.ref<!fir.type<_QTpoint{x:f32,y:f32,z:f32}>>
// CHECK: }
// CHECK-NOT: destroy
@@ -121,12 +109,11 @@ func.func @test_derived() {
// Test box type with heap scalar (needs destroy)
// CHECK: acc.private.recipe @private_box_heap_scalar : !fir.ref<!fir.box<!fir.heap<f64>>> init {
// CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.box<!fir.heap<f64>>>):
-// CHECK: %[[BOXALLOC:.*]] = fir.alloca !fir.box<!fir.heap<f64>>
-// CHECK: %{{.*}}:2 = hlfir.declare %[[BOXALLOC]] {uniq_name = "box_heap_scalar"} : (!fir.ref<!fir.box<!fir.heap<f64>>>) -> (!fir.ref<!fir.box<!fir.heap<f64>>>, !fir.ref<!fir.box<!fir.heap<f64>>>)
// CHECK: %[[SCALAR:.*]] = fir.allocmem f64
// CHECK: %[[EMBOX:.*]] = fir.embox %[[SCALAR]] : (!fir.heap<f64>) -> !fir.box<!fir.heap<f64>>
-// CHECK: fir.store %[[EMBOX]] to %{{.*}}#0 : !fir.ref<!fir.box<!fir.heap<f64>>>
-// CHECK: acc.yield %{{.*}}#0 : !fir.ref<!fir.box<!fir.heap<f64>>>
+// CHECK: %[[BOXALLOC:.*]] = fir.alloca !fir.box<!fir.heap<f64>>
+// CHECK: fir.store %[[EMBOX]] to %[[BOXALLOC]] : !fir.ref<!fir.box<!fir.heap<f64>>>
+// CHECK: acc.yield %[[BOXALLOC]] : !fir.ref<!fir.box<!fir.heap<f64>>>
// CHECK: } destroy {
// CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.box<!fir.heap<f64>>>, %{{.*}}: !fir.ref<!fir.box<!fir.heap<f64>>>):
// CHECK: acc.terminator
@@ -144,12 +131,11 @@ func.func @test_box_heap_scalar() {
// Test box type with pointer scalar (needs destroy)
// CHECK: acc.private.recipe @private_box_ptr_scalar : !fir.ref<!fir.box<!fir.ptr<i32>>> init {
// CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.box<!fir.ptr<i32>>>):
-// CHECK: %[[BOXALLOC:.*]] = fir.alloca !fir.box<!fir.ptr<i32>>
-// CHECK: %{{.*}}:2 = hlfir.declare %[[BOXALLOC]] {uniq_name = "box_ptr_scalar"} : (!fir.ref<!fir.box<!fir.ptr<i32>>>) -> (!fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.ref<!fir.box<!fir.ptr<i32>>>)
// CHECK: %[[SCALAR:.*]] = fir.allocmem i32
// CHECK: %[[EMBOX:.*]] = fir.embox %[[SCALAR]] : (!fir.heap<i32>) -> !fir.box<!fir.ptr<i32>>
-// CHECK: fir.store %[[EMBOX]] to %{{.*}}#0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
-// CHECK: acc.yield %{{.*}}#0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
+// CHECK: %[[BOXALLOC:.*]] = fir.alloca !fir.box<!fir.ptr<i32>>
+// CHECK: fir.store %[[EMBOX]] to %[[BOXALLOC]] : !fir.ref<!fir.box<!fir.ptr<i32>>>
+// CHECK: acc.yield %[[BOXALLOC]] : !fir.ref<!fir.box<!fir.ptr<i32>>>
// CHECK: } destroy {
// CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.box<!fir.ptr<i32>>>, %{{.*}}: !fir.ref<!fir.box<!fir.ptr<i32>>>):
// CHECK: acc.terminator
@@ -168,8 +154,7 @@ func.func @test_box_ptr_scalar() {
// CHECK: acc.private.recipe @private_box_heap_array_1d : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>> init {
// CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>):
// CHECK: %[[BOXALLOC:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xf32>>>
-// CHECK: %{{.*}}:2 = hlfir.declare %[[BOXALLOC]] {uniq_name = "box_heap_array_1d"} : (!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: acc.yield %{{.*}}#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+// CHECK: acc.yield %[[BOXALLOC]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
// CHECK: } destroy {
// CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, %{{.*}}: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>):
// CHECK: acc.terminator
@@ -188,8 +173,7 @@ func.func @test_box_heap_array_1d() {
// CHECK: acc.private.recipe @private_box_heap_array_2d : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xi64>>>> init {
// CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xi64>>>>):
// CHECK: %[[BOXALLOC:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?x?xi64>>>
-// CHECK: %{{.*}}:2 = hlfir.declare %[[BOXALLOC]] {uniq_name = "box_heap_array_2d"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x?xi64>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?x?xi64>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xi64>>>>)
-// CHECK: acc.yield %{{.*}}#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xi64>>>>
+// CHECK: acc.yield %[[BOXALLOC]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xi64>>>>
// CHECK: } destroy {
// CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xi64>>>>, %{{.*}}: !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xi64>>>>):
// CHECK: acc.terminator
@@ -208,8 +192,7 @@ func.func @test_box_heap_array_2d() {
// CHECK: acc.private.recipe @private_box_ptr_array : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>> init {
// CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>):
// CHECK: %[[BOXALLOC:.*]] = fir.alloca !fir.box<!fir.ptr<!fir.array<?xf32>>>
-// CHECK: %{{.*}}:2 = hlfir.declare %[[BOXALLOC]] {uniq_name = "box_ptr_array"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>)
-// CHECK: acc.yield %{{.*}}#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
+// CHECK: acc.yield %[[BOXALLOC]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
// CHECK: } destroy {
// CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>, %{{.*}}: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>):
// CHECK: acc.terminator
diff --git a/flang/test/Lower/OpenACC/acc-firstprivate-derived-pointer-component.f90 b/flang/test/Lower/OpenACC/acc-firstprivate-derived-pointer-component.f90
index 61f3d0237d668..e5083e58da493 100644
--- a/flang/test/Lower/OpenACC/acc-firstprivate-derived-pointer-component.f90
+++ b/flang/test/Lower/OpenACC/acc-firstprivate-derived-pointer-component.f90
@@ -1,6 +1,12 @@
! Test lowering of firstprivate on derived type with pointer components.
! No deep copy must be done.
+! TODO: clarify the intended behavior of private with pointer components (deep
+! copy or not).
+! Until then, a TODO is emitted in lowering.
+
+! XFAIL: *
+
! RUN: bbc -fopenacc -emit-hlfir %s -o - | FileCheck %s
! RUN: bbc -fopenacc -emit-fir %s -o - | FileCheck %s --check-prefix=FIR-CHECK
@@ -22,8 +28,7 @@ subroutine test(a)
! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_rec__QMm_firstprivate_derived_ptr_compTpoint : !fir.ref<!fir.type<_QMm_firstprivate_derived_ptr_compTpoint{x:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>> init {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.type<_QMm_firstprivate_derived_ptr_compTpoint{x:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>):
! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.type<_QMm_firstprivate_derived_ptr_compTpoint{x:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>
-! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_1]] {uniq_name = "acc.private.init"} : (!fir.ref<!fir.type<_QMm_firstprivate_derived_ptr_compTpoint{x:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>) -> (!fir.ref<!fir.type<_QMm_firstprivate_derived_ptr_compTpoint{x:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>, !fir.ref<!fir.type<_QMm_firstprivate_derived_ptr_compTpoint{x:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>)
-! CHECK: acc.yield %[[VAL_2]]#0 : !fir.ref<!fir.type<_QMm_firstprivate_derived_ptr_compTpoint{x:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>
+! CHECK: acc.yield %[[VAL_1]] : !fir.ref<!fir.type<_QMm_firstprivate_derived_ptr_compTpoint{x:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>
!
! CHECK: } copy {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.type<_QMm_firstprivate_derived_ptr_compTpoint{x:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>, %[[VAL_1:.*]]: !fir.ref<!fir.type<_QMm_firstprivate_derived_ptr_compTpoint{x:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>):
@@ -67,8 +72,7 @@ subroutine test(a)
! FIR-CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_rec__QMm_firstprivate_derived_ptr_compTpoint : !fir.ref<!fir.type<_QMm_firstprivate_derived_ptr_compTpoint{x:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>> init {
! FIR-CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.type<_QMm_firstprivate_derived_ptr_compTpoint{x:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>):
! FIR-CHECK: %[[VAL_1:.*]] = fir.alloca !fir.type<_QMm_firstprivate_derived_ptr_compTpoint{x:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>
-! FIR-CHECK: %[[VAL_2:.*]] = fir.declare %[[VAL_1]] {uniq_name = "acc.private.init"} : (!fir.ref<!fir.type<_QMm_firstprivate_derived_ptr_compTpoint{x:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>) -> !fir.ref<!fir.type<_QMm_firstprivate_derived_ptr_compTpoint{x:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>
-! FIR-CHECK: acc.yield %[[VAL_2]] : !fir.ref<!fir.type<_QMm_firstprivate_derived_ptr_compTpoint{x:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>
+! FIR-CHECK: acc.yield %[[VAL_1]] : !fir.ref<!fir.type<_QMm_firstprivate_derived_ptr_compTpoint{x:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>
!
! FIR-CHECK-LABEL: } copy {
! FIR-CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.type<_QMm_firstprivate_derived_ptr_compTpoint{x:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>, %[[VAL_1:.*]]: !fir.ref<!fir.type<_QMm_firstprivate_derived_ptr_compTpoint{x:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>):
diff --git a/flang/test/Lower/OpenACC/acc-firstprivate-derived-user-assign.f90 b/flang/test/Lower/OpenACC/acc-firstprivate-derived-user-assign.f90
index 9ada6d360edd0..98ae36f1eef2a 100644
--- a/flang/test/Lower/OpenACC/acc-firstprivate-derived-user-assign.f90
+++ b/flang/test/Lower/OpenACC/acc-firstprivate-derived-user-assign.f90
@@ -36,8 +36,7 @@ subroutine test()
! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_rec__QMm_firstprivate_derived_user_defTpoint : !fir.ref<!fir.type<_QMm_firstprivate_derived_user_defTpoint{x:f32,y:f32,z:f32}>> init {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.type<_QMm_firstprivate_derived_user_defTpoint{x:f32,y:f32,z:f32}>>):
! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.type<_QMm_firstprivate_derived_user_defTpoint{x:f32,y:f32,z:f32}>
-! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_1]] {uniq_name = "acc.private.init"} : (!fir.ref<!fir.type<_QMm_firstprivate_derived_user_defTpoint{x:f32,y:f32,z:f32}>>) -> (!fir.ref<!fir.type<_QMm_firstprivate_derived_user_defTpoint{x:f32,y:f32,z:f32}>>, !fir.ref<!fir.type<_QMm_firstprivate_derived_user_defTpoint{x:f32,y:f32,z:f32}>>)
-! CHECK: acc.yield %[[VAL_2]]#0 : !fir.ref<!fir.type<_QMm_firstprivate_derived_user_defTpoint{x:f32,y:f32,z:f32}>>
+! CHECK: acc.yield %[[VAL_1]] : !fir.ref<!fir.type<_QMm_firstprivate_derived_user_defTpoint{x:f32,y:f32,z:f32}>>
!
! CHECK: } copy {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.type<_QMm_firstprivate_derived_user_defTpoint{x:f32,y:f32,z:f32}>>, %[[VAL_1:.*]]: !fir.ref<!fir.type<_QMm_firstprivate_derived_user_defTpoint{x:f32,y:f32,z:f32}>>):
@@ -77,8 +76,7 @@ subroutine test()
! FIR-CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_rec__QMm_firstprivate_derived_user_defTpoint : !fir.ref<!fir.type<_QMm_firstprivate_derived_user_defTpoint{x:f32,y:f32,z:f32}>> init {
! FIR-CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.type<_QMm_firstprivate_derived_user_defTpoint{x:f32,y:f32,z:f32}>>):
! FIR-CHECK: %[[VAL_1:.*]] = fir.alloca !fir.type<_QMm_firstprivate_derived_user_defTpoint{x:f32,y:f32,z:f32}>
-! FIR-CHECK: %[[VAL_2:.*]] = fir.declare %[[VAL_1]] {uniq_name = "acc.private.init"} : (!fir.ref<!fir.type<_QMm_firstprivate_derived_user_defTpoint{x:f32,y:f32,z:f32}>>) -> !fir.ref<!fir.type<_QMm_firstprivate_derived_user_defTpoint{x:f32,y:f32,z:f32}>>
-! FIR-CHECK: acc.yield %[[VAL_2]] : !fir.ref<!fir.type<_QMm_firstprivate_derived_user_defTpoint{x:f32,y:f32,z:f32}>>
+! FIR-CHECK: acc.yield %[[VAL_1]] : !fir.ref<!fir.type<_QMm_firstprivate_derived_user_defTpoint{x:f32,y:f32,z:f32}>>
! FIR-CHECK: } copy {
! FIR-CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.type<_QMm_firstprivate_derived_user_defTpoint{x:f32,y:f32,z:f32}>>, %[[VAL_1:.*]]: !fir.ref<!fir.type<_QMm_firstprivate_derived_user_defTpoint{x:f32,y:f32,z:f32}>>):
! FIR-CHECK: %[[VAL_2:.*]] = fir.field_index x, !fir.type<_QMm_firstprivate_derived_user_defTpoint{x:f32,y:f32,z:f32}>
diff --git a/flang/test/Lower/OpenACC/acc-firstprivate-derived.f90 b/flang/test/Lower/OpenACC/acc-firstprivate-derived.f90
index 6260f753aa90a..3b59a0353b199 100644
--- a/flang/test/Lower/OpenACC/acc-firstprivate-derived.f90
+++ b/flang/test/Lower/OpenACC/acc-firstprivate-derived.f90
@@ -22,8 +22,7 @@ subroutine test()
! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_rec__QMm_firstprivate_derivedTpoint : !fir.ref<!fir.type<_QMm_firstprivate_derivedTpoint{x:f32,y:f32,z:f32}>> init {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.type<_QMm_firstprivate_derivedTpoint{x:f32,y:f32,z:f32}>>):
! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.type<_QMm_firstprivate_derivedTpoint{x:f32,y:f32,z:f32}>
-! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_1]] {uniq_name = "acc.private.init"} : (!fir.ref<!fir.type<_QMm_firstprivate_derivedTpoint{x:f32,y:f32,z:f32}>>) -> (!fir.ref<!fir.type<_QMm_firstprivate_derivedTpoint{x:f32,y:f32,z:f32}>>, !fir.ref<!fir.type<_QMm_firstprivate_derivedTpoint{x:f32,y:f32,z:f32}>>)
-! CHECK: acc.yield %[[VAL_2]]#0 : !fir.ref<!fir.type<_QMm_firstprivate_derivedTpoint{x:f32,y:f32,z:f32}>>
+! CHECK: acc.yield %[[VAL_1]] : !fir.ref<!fir.type<_QMm_firstprivate_derivedTpoint{x:f32,y:f32,z:f32}>>
!
! CHECK: } copy {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.type<_QMm_firstprivate_derivedTpoint{x:f32,y:f32,z:f32}>>, %[[VAL_1:.*]]: !fir.ref<!fir.type<_QMm_firstprivate_derivedTpoint{x:f32,y:f32,z:f32}>>):
@@ -63,8 +62,7 @@ subroutine test()
! FIR-CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_rec__QMm_firstprivate_derivedTpoint : !fir.ref<!fir.type<_QMm_firstprivate_derivedTpoint{x:f32,y:f32,z:f32}>> init {
! FIR-CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.type<_QMm_firstprivate_derivedTpoint{x:f32,y:f32,z:f32}>>):
! FIR-CHECK: %[[VAL_1:.*]] = fir.alloca !fir.type<_QMm_firstprivate_derivedTpoint{x:f32,y:f32,z:f32}>
-! FIR-CHECK: %[[VAL_2:.*]] = fir.declare %[[VAL_1]] {uniq_name = "acc.private.init"} : (!fir.ref<!fir.type<_QMm_firstprivate_derivedTpoint{x:f32,y:f32,z:f32}>>) -> !fir.ref<!fir.type<_QMm_firstprivate_derivedTpoint{x:f32,y:f32,z:f32}>>
-! FIR-CHECK: acc.yield %[[VAL_2]] : !fir.ref<!fir.type<_QMm_firstprivate_derivedTpoint{x:f32,y:f32,z:f32}>>
+! FIR-CHECK: acc.yield %[[VAL_1]] : !fir.ref<!fir.type<_QMm_firstprivate_derivedTpoint{x:f32,y:f32,z:f32}>>
! FIR-CHECK: } copy {
! FIR-CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.type<_QMm_firstprivate_derivedTpoint{x:f32,y:f32,z:f32}>>, %[[VAL_1:.*]]: !fir.ref<!fir.type<_QMm_firstprivate_derivedTpoint{x:f32,y:f32,z:f32}>>):
! FIR-CHECK: %[[VAL_2:.*]] = fir.field_index x, !fir.type<_QMm_firstprivate_derivedTpoint{x:f32,y:f32,z:f32}>
diff --git a/flang/test/Lower/OpenACC/acc-parallel.f90 b/flang/test/Lower/OpenACC/acc-parallel.f90
index 103dec203daa1..6d6cc9c623ce5 100644
--- a/flang/test/Lower/OpenACC/acc-parallel.f90
+++ b/flang/test/Lower/OpenACC/acc-parallel.f90
@@ -4,10 +4,8 @@
! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_10x10xf32 : !fir.ref<!fir.array<10x10xf32>> init {
! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<10x10xf32>>):
-! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2>
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<10x10xf32>
-! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.private.init"} : (!fir.ref<!fir.array<10x10xf32>>, !fir.shape<2>) -> (!fir.ref<!fir.array<10x10xf32>>, !fir.ref<!fir.array<10x10xf32>>)
-! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<10x10xf32>>
+! CHECK: acc.yield %[[ALLOCA]] : !fir.ref<!fir.array<10x10xf32>>
! CHECK: } copy {
! CHECK: ^bb0(%arg0: !fir.ref<!fir.array<10x10xf32>>, %arg1: !fir.ref<!fir.array<10x10xf32>>):
! CHECK: acc.terminator
@@ -15,9 +13,8 @@
! CHECK-LABEL: acc.private.recipe @privatization_ref_10x10xf32 : !fir.ref<!fir.array<10x10xf32>> init {
! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<10x10xf32>>):
-! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2>
-! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.private.init"} : (!fir.ref<!fir.array<10x10xf32>>, !fir.shape<2>) -> (!fir.ref<!fir.array<10x10xf32>>, !fir.ref<!fir.array<10x10xf32>>)
-! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<10x10xf32>>
+! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<10x10xf32>
+! CHECK: acc.yield %[[ALLOCA]] : !fir.ref<!fir.array<10x10xf32>>
! CHECK: }
! CHECK-LABEL: func.func @_QPacc_parallel()
diff --git a/flang/test/Lower/OpenACC/acc-private.f90 b/flang/test/Lower/OpenACC/acc-private.f90
index c62e918b12c18..494267b26fed8 100644
--- a/flang/test/Lower/OpenACC/acc-private.f90
+++ b/flang/test/Lower/OpenACC/acc-private.f90
@@ -2,230 +2,371 @@
! RUN: bbc -fopenacc -emit-hlfir %s -o - | FileCheck %s
-! CHECK-LABEL: acc.private.recipe @privatization_ptr_10xf32 : !fir.ptr<!fir.array<10xf32>> init {
-! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ptr<!fir.array<10xf32>>):
-! CHECK: %[[C10:.*]] = arith.constant 10 : index
-! CHECK: %[[SHAPE:.*]] = fir.shape %[[C10]] : (index) -> !fir.shape<1>
-! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<10xf32>
-! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.private.init"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>)
-! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<10xf32>>
-! CHECK: }
-
-! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_box_UxUx2xi32 : !fir.box<!fir.array<?x?x2xi32>> init {
-! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box<!fir.array<?x?x2xi32>>):
-! CHECK: %[[DIM0:.*]]:3 = fir.box_dims %arg0, %c0{{.*}} : (!fir.box<!fir.array<?x?x2xi32>>, index) -> (index, index, index)
-! CHECK: %[[DIM1:.*]]:3 = fir.box_dims %arg0, %c1{{.*}} : (!fir.box<!fir.array<?x?x2xi32>>, index) -> (index, index, index)
-! CHECK: %[[SHAPE:.*]] = fir.shape %[[DIM0]]#1, %[[DIM1]]#1, %c2{{.*}} : (index, index, index) -> !fir.shape<3>
-! CHECK: %[[TEMP:.*]] = fir.allocmem !fir.array<?x?x2xi32>, %[[DIM0]]#1, %[[DIM1]]#1 {bindc_name = ".tmp", uniq_name = ""}
-! CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[TEMP]](%[[SHAPE]]) {uniq_name = ".tmp"} : (!fir.heap<!fir.array<?x?x2xi32>>, !fir.shape<3>) -> (!fir.box<!fir.array<?x?x2xi32>>, !fir.heap<!fir.array<?x?x2xi32>>)
-! CHECK: acc.yield %[[DECL]]#0 : !fir.box<!fir.array<?x?x2xi32>>
-! CHECK: } copy {
-! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box<!fir.array<?x?x2xi32>>, %[[ARG1:.*]]: !fir.box<!fir.array<?x?x2xi32>>):
-! CHECK: hlfir.assign %[[ARG0]] to %[[ARG1]] temporary_lhs : !fir.box<!fir.array<?x?x2xi32>>, !fir.box<!fir.array<?x?x2xi32>>
-! CHECK: acc.terminator
-! CHECK: } destroy {
-! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box<!fir.array<?x?x2xi32>>, %[[ARG1:.*]]: !fir.box<!fir.array<?x?x2xi32>>):
-! CHECK: %[[ADDR:.*]] = fir.box_addr %[[ARG1]] : (!fir.box<!fir.array<?x?x2xi32>>) -> !fir.ref<!fir.array<?x?x2xi32>>
-! CHECK: %[[CAST:.*]] = fir.convert %[[ADDR]] : (!fir.ref<!fir.array<?x?x2xi32>>) -> !fir.heap<!fir.array<?x?x2xi32>>
-! CHECK: fir.freemem %[[CAST]] : !fir.heap<!fir.array<?x?x2xi32>>
-! CHECK: acc.terminator
-! CHECK: }
-
-! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_section_lb4.ub9_box_Uxi32 : !fir.box<!fir.array<?xi32>> init {
-! CHECK: ^bb0(%{{.*}}: !fir.box<!fir.array<?xi32>>):
-! CHECK: } copy {
-! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box<!fir.array<?xi32>>, %[[ARG1:.*]]: !fir.box<!fir.array<?xi32>>):
-! CHECK: hlfir.assign {{.*}} to {{.*}} temporary_lhs : !fir.box<!fir.array<?xi32>>, !fir.box<!fir.array<?xi32>>
-! CHECK: acc.terminator
-! CHECK: } destroy {
-! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box<!fir.array<?xi32>>, %[[ARG1:.*]]: !fir.box<!fir.array<?xi32>>):
-! CHECK: %[[ADDR:.*]] = fir.box_addr %[[ARG1]] : (!fir.box<!fir.array<?xi32>>) -> !fir.ref<!fir.array<?xi32>>
-! CHECK: %[[CAST:.*]] = fir.convert %[[ADDR]] : (!fir.ref<!fir.array<?xi32>>) -> !fir.heap<!fir.array<?xi32>>
-! CHECK: fir.freemem %[[CAST]] : !fir.heap<!fir.array<?xi32>>
-! CHECK: acc.terminator
-! CHECK: }
-
-! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_box_Uxi32 : !fir.box<!fir.array<?xi32>> init {
-! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box<!fir.array<?xi32>>):
-! CHECK: %[[C0:.*]] = arith.constant 0 : index
-! CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[ARG0]], %c0 : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
-! CHECK: %[[SHAPE:.*]] = fir.shape %[[BOX_DIMS]]#1 : (index) -> !fir.shape<1>
-! CHECK: %[[TEMP:.*]] = fir.allocmem !fir.array<?xi32>, %[[BOX_DIMS]]#1 {bindc_name = ".tmp", uniq_name = ""}
-! CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[TEMP]](%[[SHAPE]]) {uniq_name = ".tmp"} : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xi32>>, !fir.heap<!fir.array<?xi32>>)
-! CHECK: acc.yield %[[DECL]]#0 : !fir.box<!fir.array<?xi32>>
-! CHECK: } copy {
-! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box<!fir.array<?xi32>>, %[[ARG1:.*]]: !fir.box<!fir.array<?xi32>>):
-! CHECK: hlfir.assign %[[ARG0]] to %[[ARG1]] temporary_lhs : !fir.box<!fir.array<?xi32>>, !fir.box<!fir.array<?xi32>>
-! CHECK: acc.terminator
-! CHECK: } destroy {
-! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box<!fir.array<?xi32>>, %[[ARG1:.*]]: !fir.box<!fir.array<?xi32>>):
-! CHECK: %[[ADDR:.*]] = fir.box_addr %[[ARG1]] : (!fir.box<!fir.array<?xi32>>) -> !fir.ref<!fir.array<?xi32>>
-! CHECK: %[[CAST:.*]] = fir.convert %[[ADDR]] : (!fir.ref<!fir.array<?xi32>>) -> !fir.heap<!fir.array<?xi32>>
-! CHECK: fir.freemem %[[CAST]] : !fir.heap<!fir.array<?xi32>>
-! CHECK: acc.terminator
-! CHECK: }
-
-! CHECK-LABEL: acc.private.recipe @privatization_box_UxUx2xi32 : !fir.box<!fir.array<?x?x2xi32>> init {
-! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box<!fir.array<?x?x2xi32>>):
-! CHECK: %[[DIM0:.*]]:3 = fir.box_dims %arg0, %c0{{.*}} : (!fir.box<!fir.array<?x?x2xi32>>, index) -> (index, index, index)
-! CHECK: %[[DIM1:.*]]:3 = fir.box_dims %arg0, %c1{{.*}} : (!fir.box<!fir.array<?x?x2xi32>>, index) -> (index, index, index)
-! CHECK: %[[SHAPE:.*]] = fir.shape %[[DIM0]]#1, %[[DIM1]]#1, %c2{{.*}} : (index, index, index) -> !fir.shape<3>
-! CHECK: %[[TEMP:.*]] = fir.allocmem !fir.array<?x?x2xi32>, %[[DIM0]]#1, %[[DIM1]]#1 {bindc_name = ".tmp", uniq_name = ""}
-! CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[TEMP]](%[[SHAPE]]) {uniq_name = ".tmp"} : (!fir.heap<!fir.array<?x?x2xi32>>, !fir.shape<3>) -> (!fir.box<!fir.array<?x?x2xi32>>, !fir.heap<!fir.array<?x?x2xi32>>)
-! CHECK: acc.yield %[[DECL]]#0 : !fir.box<!fir.array<?x?x2xi32>>
-! CHECK: } destroy {
-! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box<!fir.array<?x?x2xi32>>, %[[ARG1:.*]]: !fir.box<!fir.array<?x?x2xi32>>):
-! CHECK: %[[ADDR:.*]] = fir.box_addr %[[ARG1]] : (!fir.box<!fir.array<?x?x2xi32>>) -> !fir.ref<!fir.array<?x?x2xi32>>
-! CHECK: %[[CAST:.*]] = fir.convert %[[ADDR]] : (!fir.ref<!fir.array<?x?x2xi32>>) -> !fir.heap<!fir.array<?x?x2xi32>>
-! CHECK: fir.freemem %[[CAST]] : !fir.heap<!fir.array<?x?x2xi32>>
-! CHECK: acc.terminator
-! CHECK: }
-
-! CHECK-LABEL: acc.private.recipe @privatization_ref_box_ptr_Uxi32 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>> init {
-! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>):
-! CHECK: %[[LOADBOX:.*]] = fir.load %[[ARG0]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
-! CHECK: %[[C0:.*]] = arith.constant 0 : index
-! CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[LOADBOX]], %c0 : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, index) -> (index, index, index)
-! CHECK: %[[SHAPE:.*]] = fir.shape %[[BOX_DIMS]]#1 : (index) -> !fir.shape<1>
-! CHECK: %[[TEMP:.*]] = fir.allocmem !fir.array<?xi32>, %[[BOX_DIMS]]#1 {bindc_name = ".tmp", uniq_name = ""}
-! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[TEMP]](%[[SHAPE]]) {uniq_name = ".tmp"} : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xi32>>, !fir.heap<!fir.array<?xi32>>)
-! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.box<!fir.ptr<!fir.array<?xi32>>>
-! CHECK: %[[DECLAREBOX:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.private.init"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>)
-! CHECK: %[[CONV:.*]] = fir.convert %[[DECLAREBOX]]#0 : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>) -> !fir.ref<!fir.box<!fir.array<?xi32>>>
-! CHECK: fir.store %[[DECLARE]]#0 to %[[CONV]] : !fir.ref<!fir.box<!fir.array<?xi32>>>
-! CHECK: acc.yield %[[DECLAREBOX]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
-! CHECK: } destroy {
-! CHECK: ^bb0(%arg0: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>, %arg1: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>):
-! CHECK: %[[LOAD:.*]] = fir.load %arg1 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
-! CHECK: %[[ADDR:.*]] = fir.box_addr %[[LOAD]] : (!fir.box<!fir.ptr<!fir.array<?xi32>>>) -> !fir.ptr<!fir.array<?xi32>>
-! CHECK: %[[CAST:.*]] = fir.convert %[[ADDR]] : (!fir.ptr<!fir.array<?xi32>>) -> !fir.heap<!fir.array<?xi32>>
-! CHECK: fir.freemem %[[CAST]] : !fir.heap<!fir.array<?xi32>>
-! CHECK: acc.terminator
-! CHECK: }
-
-! CHECK-LABEL: @privatization_ref_box_heap_i32 : !fir.ref<!fir.box<!fir.heap<i32>>> init {
-! CHECK: ^bb0(%arg0: !fir.ref<!fir.box<!fir.heap<i32>>>):
-! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.box<!fir.heap<i32>>
-! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.private.init"} : (!fir.ref<!fir.box<!fir.heap<i32>>>) -> (!fir.ref<!fir.box<!fir.heap<i32>>>, !fir.ref<!fir.box<!fir.heap<i32>>>)
-! CHECK: %[[ALLOCMEM:.*]] = fir.allocmem i32
-! CHECK: %[[BOX:.*]] = fir.embox %[[ALLOCMEM]] : (!fir.heap<i32>) -> !fir.box<!fir.heap<i32>>
-! CHECK: fir.store %[[BOX]] to %[[DECLARE]]#0 : !fir.ref<!fir.box<!fir.heap<i32>>>
-! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.box<!fir.heap<i32>>>
-! CHECK: } destroy {
-! CHECK: ^bb0(%arg0: !fir.ref<!fir.box<!fir.heap<i32>>>, %arg1: !fir.ref<!fir.box<!fir.heap<i32>>>):
-! CHECK: %[[LOAD:.*]] = fir.load %arg1 : !fir.ref<!fir.box<!fir.heap<i32>>>
-! CHECK: %[[ADDR:.*]] = fir.box_addr %[[LOAD]] : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
-! CHECK: fir.freemem %[[ADDR]] : !fir.heap<i32>
-! CHECK: acc.terminator
-! CHECK: }
-
-! CHECK-LABEL: acc.private.recipe @privatization_ref_box_heap_Uxi32 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> init {
-! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>):
-! CHECK: %[[LOADBOX:.*]] = fir.load %[[ARG0]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
-! CHECK: %[[C0:.*]] = arith.constant 0 : index
-! CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[LOADBOX]], %[[C0]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
-! CHECK: %[[SHAPE:.*]] = fir.shape %[[BOX_DIMS]]#1 : (index) -> !fir.shape<1>
-! CHECK: %[[TEMP:.*]] = fir.allocmem !fir.array<?xi32>, %[[BOX_DIMS]]#1 {bindc_name = ".tmp", uniq_name = ""}
-! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[TEMP]](%[[SHAPE]]) {uniq_name = ".tmp"} : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xi32>>, !fir.heap<!fir.array<?xi32>>)
-! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xi32>>>
-! CHECK: %[[DECLAREBOX:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.private.init"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>)
-! CHECK: %[[CONV:.*]] = fir.convert %[[DECLAREBOX]]#0 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> !fir.ref<!fir.box<!fir.array<?xi32>>>
-! CHECK: fir.store %[[DECLARE]]#0 to %[[CONV]] : !fir.ref<!fir.box<!fir.array<?xi32>>>
-! CHECK: acc.yield %[[DECLAREBOX]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
-! CHECK: } destroy {
-! CHECK: ^bb0(%arg0: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, %arg1: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>):
-! CHECK: %[[LOAD:.*]] = fir.load %arg1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
-! CHECK: %[[ADDR:.*]] = fir.box_addr %[[LOAD]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
-! CHECK: fir.freemem %[[ADDR]] : !fir.heap<!fir.array<?xi32>>
-! CHECK: acc.terminator
-! CHECK: }
-
-! CHECK-LABEL: acc.private.recipe @privatization_box_Uxi32 : !fir.box<!fir.array<?xi32>> init {
-! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box<!fir.array<?xi32>>):
-! CHECK: %[[C0:.*]] = arith.constant 0 : index
-! CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[ARG0]], %[[C0]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
-! CHECK: %[[SHAPE:.*]] = fir.shape %[[BOX_DIMS]]#1 : (index) -> !fir.shape<1>
-! CHECK: %[[TEMP:.*]] = fir.allocmem !fir.array<?xi32>, %0#1 {bindc_name = ".tmp", uniq_name = ""}
-! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[TEMP]](%[[SHAPE]]) {uniq_name = ".tmp"} : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xi32>>, !fir.heap<!fir.array<?xi32>>)
-! CHECK: acc.yield %[[DECLARE:.*]]#0 : !fir.box<!fir.array<?xi32>>
-! CHECK: } destroy {
-! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box<!fir.array<?xi32>>, %[[ARG1:.*]]: !fir.box<!fir.array<?xi32>>):
-! CHECK: %[[ADDR:.*]] = fir.box_addr %[[ARG1]] : (!fir.box<!fir.array<?xi32>>) -> !fir.ref<!fir.array<?xi32>>
-! CHECK: %[[CAST:.*]] = fir.convert %[[ADDR]] : (!fir.ref<!fir.array<?xi32>>) -> !fir.heap<!fir.array<?xi32>>
-! CHECK: fir.freemem %[[CAST]] : !fir.heap<!fir.array<?xi32>>
-! CHECK: acc.terminator
-! CHECK: }
-
-! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_section_lb50.ub99_ref_50xf32 : !fir.ref<!fir.array<50xf32>> init {
-! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<50xf32>>):
-! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1>
-! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<50xf32>
-! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.private.init"} : (!fir.ref<!fir.array<50xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<50xf32>>, !fir.ref<!fir.array<50xf32>>)
-! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<50xf32>>
-! CHECK: } copy {
-! CHECK: ^bb0(%[[SRC:.*]]: !fir.ref<!fir.array<50xf32>>, %[[DST:.*]]: !fir.ref<!fir.array<50xf32>>):
-! CHECK: %[[C50:.*]] = arith.constant 50 : index
-! CHECK: %[[C99:.*]] = arith.constant 99 : index
-! CHECK: %[[C1:.*]] = arith.constant 1 : index
-! CHECK: %[[C0:.*]] = arith.constant 0 : index
-! CHECK: %[[D0:.*]] = arith.subi %[[C99]], %[[C50]] : index
-! CHECK: %[[D1:.*]] = arith.addi %[[D0]], %[[C1]] : index
-! CHECK: %[[D2:.*]] = arith.divsi %[[D1]], %[[C1]] : index
-! CHECK: %[[CMP:.*]] = arith.cmpi sgt, %[[D2]], %[[C0]] : index
-! CHECK: %[[SEL:.*]] = arith.select %[[CMP]], %[[D2]], %[[C0]] : index
-! CHECK: %[[SH:.*]] = fir.shape %[[SEL]] : (index) -> !fir.shape<1>
-! CHECK: %[[SEC_SRC:.*]] = hlfir.designate %[[SRC]] (%c51{{.*}}:%c100{{.*}}:%c1{{.*}}) shape %[[SH]] : (!fir.ref<!fir.array<50xf32>>, index, index, index, !fir.shape<1>) -> !fir.ref<!fir.array<50xf32>>
-! CHECK: %[[SEC_DST:.*]] = hlfir.designate %[[DST]] (%c51{{.*}}:%c100{{.*}}:%c1{{.*}}) shape %[[SH]] : (!fir.ref<!fir.array<50xf32>>, index, index, index, !fir.shape<1>) -> !fir.ref<!fir.array<50xf32>>
-! CHECK: hlfir.assign %[[SEC_SRC]] to %[[SEC_DST]] temporary_lhs : !fir.ref<!fir.array<50xf32>>, !fir.ref<!fir.array<50xf32>>
-! CHECK: acc.terminator
-! CHECK: }
-
-! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_100xf32 : !fir.ref<!fir.array<100xf32>> init {
-! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<100xf32>>):
-! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1>
-! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<100xf32>
-! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.private.init"} : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<100xf32>>, !fir.ref<!fir.array<100xf32>>)
-! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<100xf32>>
-! CHECK: } copy {
-! CHECK: ^bb0(%[[SRC:.*]]: !fir.ref<!fir.array<100xf32>>, %[[DST:.*]]: !fir.ref<!fir.array<100xf32>>):
-! CHECK: hlfir.assign %[[SRC]] to %[[DST]] temporary_lhs : !fir.ref<!fir.array<100xf32>>, !fir.ref<!fir.array<100xf32>>
-! CHECK: acc.terminator
-! CHECK: }
-
-! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_i32 : !fir.ref<i32> init {
-! CHECK: ^bb0(%{{.*}}: !fir.ref<i32>):
-! CHECK: %[[ALLOCA:.*]] = fir.alloca i32
-! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.private.init"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
-! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref<i32>
-! CHECK: } copy {
-! CHECK: ^bb0(%[[SRC:.*]]: !fir.ref<i32>, %[[DST:.*]]: !fir.ref<i32>):
-! CHECK: %[[VALUE:.*]] = fir.load %[[SRC]] : !fir.ref<i32>
-! CHECK: fir.assign %[[VALUE]] to %[[DST]] temporary_lhs : i32, !fir.ref<i32>
-! CHECK: acc.terminator
-! CHECK: }
-
-! CHECK-LABEL: acc.private.recipe @privatization_ref_50xf32 : !fir.ref<!fir.array<50xf32>> init {
-! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<50xf32>>):
-! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1>
-! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<50xf32>
-! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.private.init"} : (!fir.ref<!fir.array<50xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<50xf32>>, !fir.ref<!fir.array<50xf32>>)
-! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<50xf32>>
-! CHECK: }
-
-! CHECK-LABEL: acc.private.recipe @privatization_ref_100xf32 : !fir.ref<!fir.array<100xf32>> init {
-! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<100xf32>>):
-! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1>
-! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<100xf32>
-! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.private.init"} : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<100xf32>>, !fir.ref<!fir.array<100xf32>>)
-! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<100xf32>>
-! CHECK: }
-
-! CHECK-LABEL: acc.private.recipe @privatization_ref_i32 : !fir.ref<i32> init {
-! CHECK: ^bb0(%{{.*}}: !fir.ref<i32>):
-! CHECK: %[[ALLOCA:.*]] = fir.alloca i32
-! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.private.init"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
-! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref<i32>
-! CHECK: }
+
+! CHECK-LABEL: acc.private.recipe @privatization_ptr_10xf32 : !fir.ptr<!fir.array<10xf32>> init {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ptr<!fir.array<10xf32>>):
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<10xf32> {bindc_name = "acc.private.init"}
+! CHECK: %[[CONSTANT_0:.*]] = arith.constant 10 : index
+! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_0]] : (index) -> !fir.shape<1>
+! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[CONSTANT_0]] : (index) -> !fir.shape<1>
+! CHECK: %[[CONSTANT_1:.*]] = arith.constant 1 : index
+! CHECK: %[[CONSTANT_2:.*]] = arith.constant 10 : index
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<!fir.array<10xf32>>
+! CHECK: }
+
+! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_box_UxUx2xi32 : !fir.box<!fir.array<?x?x2xi32>> init {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box<!fir.array<?x?x2xi32>>):
+! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_0]] : (!fir.box<!fir.array<?x?x2xi32>>, index) -> (index, index, index)
+! CHECK: %[[CONSTANT_1:.*]] = arith.constant 1 : index
+! CHECK: %[[BOX_DIMS_1:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_1]] : (!fir.box<!fir.array<?x?x2xi32>>, index) -> (index, index, index)
+! CHECK: %[[CONSTANT_2:.*]] = arith.constant 2 : index
+! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[BOX_DIMS_0]]#1, %[[BOX_DIMS_1]]#1, %[[CONSTANT_2]] : (index, index, index) -> !fir.shape<3>
+! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[BOX_DIMS_0]]#1, %[[BOX_DIMS_1]]#1, %[[CONSTANT_2]] : (index, index, index) -> !fir.shape<3>
+! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array<?x?x2xi32>, %[[BOX_DIMS_0]]#1, %[[BOX_DIMS_1]]#1 {bindc_name = "acc.private.init", uniq_name = ""}
+! CHECK: %[[CONSTANT_3:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_2:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_3]] : (!fir.box<!fir.array<?x?x2xi32>>, index) -> (index, index, index)
+! CHECK: %[[CONSTANT_4:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_3:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_4]] : (!fir.box<!fir.array<?x?x2xi32>>, index) -> (index, index, index)
+! CHECK: %[[CONSTANT_5:.*]] = arith.constant 1 : index
+! CHECK: %[[BOX_DIMS_4:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_5]] : (!fir.box<!fir.array<?x?x2xi32>>, index) -> (index, index, index)
+! CHECK: %[[CONSTANT_6:.*]] = arith.constant 1 : index
+! CHECK: %[[BOX_DIMS_5:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_6]] : (!fir.box<!fir.array<?x?x2xi32>>, index) -> (index, index, index)
+! CHECK: %[[CONSTANT_7:.*]] = arith.constant 2 : index
+! CHECK: %[[BOX_DIMS_6:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_7]] : (!fir.box<!fir.array<?x?x2xi32>>, index) -> (index, index, index)
+! CHECK: %[[CONSTANT_8:.*]] = arith.constant 2 : index
+! CHECK: %[[SHAPE_SHIFT_0:.*]] = fir.shape_shift %[[BOX_DIMS_2]]#0, %[[BOX_DIMS_3]]#1, %[[BOX_DIMS_4]]#0, %[[BOX_DIMS_5]]#1, %[[BOX_DIMS_6]]#0, %[[CONSTANT_8]] : (index, index, index, index, index, index) -> !fir.shapeshift<3>
+! CHECK: %[[EMBOX_0:.*]] = fir.embox %[[ALLOCMEM_0]](%[[SHAPE_SHIFT_0]]) : (!fir.heap<!fir.array<?x?x2xi32>>, !fir.shapeshift<3>) -> !fir.box<!fir.array<?x?x2xi32>>
+! CHECK: acc.yield %[[EMBOX_0]] : !fir.box<!fir.array<?x?x2xi32>>
+
+! CHECK-LABEL: } copy {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box<!fir.array<?x?x2xi32>>, %[[VAL_1:.*]]: !fir.box<!fir.array<?x?x2xi32>>):
+! CHECK: hlfir.assign %[[VAL_0]] to %[[VAL_1]] temporary_lhs : !fir.box<!fir.array<?x?x2xi32>>, !fir.box<!fir.array<?x?x2xi32>>
+! CHECK: acc.terminator
+
+! CHECK-LABEL: } destroy {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box<!fir.array<?x?x2xi32>>, %[[VAL_1:.*]]: !fir.box<!fir.array<?x?x2xi32>>):
+! CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box<!fir.array<?x?x2xi32>>) -> !fir.ref<!fir.array<?x?x2xi32>>
+! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[BOX_ADDR_0]] : (!fir.ref<!fir.array<?x?x2xi32>>) -> !fir.heap<!fir.array<?x?x2xi32>>
+! CHECK: fir.freemem %[[CONVERT_0]] : !fir.heap<!fir.array<?x?x2xi32>>
+! CHECK: acc.terminator
+! CHECK: }
+
+! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_section_lb4.ub9_box_Uxi32 : !fir.box<!fir.array<?xi32>> init {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box<!fir.array<?xi32>>):
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<6xi32> {bindc_name = "acc.private.init"}
+! CHECK: %[[CONSTANT_0:.*]] = arith.constant 1 : index
+! CHECK: %[[CONSTANT_1:.*]] = arith.constant 4 : index
+! CHECK: %[[CONSTANT_2:.*]] = arith.constant 9 : index
+! CHECK: %[[CONSTANT_3:.*]] = arith.constant 0 : index
+! CHECK: %[[CONSTANT_4:.*]] = arith.constant 5 : index
+! CHECK: %[[CONSTANT_5:.*]] = arith.constant 6 : index
+! CHECK: %[[CONSTANT_6:.*]] = arith.constant true
+! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_5]] : (index) -> !fir.shape<1>
+! CHECK: %[[CONSTANT_7:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_7]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
+! CHECK: %[[ADDI_0:.*]] = arith.addi %[[BOX_DIMS_0]]#0, %[[CONSTANT_1]] : index
+! CHECK: %[[ADDI_1:.*]] = arith.addi %[[BOX_DIMS_0]]#0, %[[CONSTANT_2]] : index
+! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_0]] (%[[ADDI_0]]:%[[ADDI_1]]:%[[CONSTANT_0]]) shape %[[SHAPE_0]] : (!fir.box<!fir.array<?xi32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<6xi32>>
+! CHECK: %[[CONSTANT_8:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_1:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_8]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
+! CHECK: %[[CONSTANT_9:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_2:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_9]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
+! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[ALLOCA_0]] : (!fir.ref<!fir.array<6xi32>>) -> !fir.ref<!fir.array<?xi32>>
+! CHECK: %[[CONSTANT_10:.*]] = arith.constant 0 : index
+! CHECK: %[[SHAPE_SHIFT_0:.*]] = fir.shape_shift %[[CONSTANT_1]], %[[BOX_DIMS_2]]#1 : (index, index) -> !fir.shapeshift<1>
+! CHECK: %[[ARRAY_COOR_0:.*]] = fir.array_coor %[[CONVERT_0]](%[[SHAPE_SHIFT_0]]) %[[CONSTANT_10]] : (!fir.ref<!fir.array<?xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>
+! CHECK: %[[CONVERT_1:.*]] = fir.convert %[[ARRAY_COOR_0]] : (!fir.ref<i32>) -> !fir.ref<!fir.array<?xi32>>
+! CHECK: %[[SHAPE_SHIFT_1:.*]] = fir.shape_shift %[[BOX_DIMS_1]]#0, %[[BOX_DIMS_2]]#1 : (index, index) -> !fir.shapeshift<1>
+! CHECK: %[[EMBOX_0:.*]] = fir.embox %[[CONVERT_1]](%[[SHAPE_SHIFT_1]]) : (!fir.ref<!fir.array<?xi32>>, !fir.shapeshift<1>) -> !fir.box<!fir.array<?xi32>>
+! CHECK: acc.yield %[[EMBOX_0]] : !fir.box<!fir.array<?xi32>>
+
+! CHECK-LABEL: } copy {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box<!fir.array<?xi32>>, %[[VAL_1:.*]]: !fir.box<!fir.array<?xi32>>):
+! CHECK: %[[CONSTANT_0:.*]] = arith.constant 1 : index
+! CHECK: %[[CONSTANT_1:.*]] = arith.constant 4 : index
+! CHECK: %[[CONSTANT_2:.*]] = arith.constant 9 : index
+! CHECK: %[[CONSTANT_3:.*]] = arith.constant 0 : index
+! CHECK: %[[CONSTANT_4:.*]] = arith.constant 5 : index
+! CHECK: %[[CONSTANT_5:.*]] = arith.constant 6 : index
+! CHECK: %[[CONSTANT_6:.*]] = arith.constant true
+! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_5]] : (index) -> !fir.shape<1>
+! CHECK: %[[CONSTANT_7:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[VAL_1]], %[[CONSTANT_7]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
+! CHECK: %[[ADDI_0:.*]] = arith.addi %[[BOX_DIMS_0]]#0, %[[CONSTANT_1]] : index
+! CHECK: %[[ADDI_1:.*]] = arith.addi %[[BOX_DIMS_0]]#0, %[[CONSTANT_2]] : index
+! CHECK: %[[CONSTANT_8:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_1:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_8]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
+! CHECK: %[[ADDI_2:.*]] = arith.addi %[[BOX_DIMS_1]]#0, %[[CONSTANT_1]] : index
+! CHECK: %[[ADDI_3:.*]] = arith.addi %[[BOX_DIMS_1]]#0, %[[CONSTANT_2]] : index
+! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_0]] (%[[ADDI_2]]:%[[ADDI_3]]:%[[CONSTANT_0]]) shape %[[SHAPE_0]] : (!fir.box<!fir.array<?xi32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<6xi32>>
+! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_1]] (%[[ADDI_0]]:%[[ADDI_1]]:%[[CONSTANT_0]]) shape %[[SHAPE_0]] : (!fir.box<!fir.array<?xi32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<6xi32>>
+! CHECK: hlfir.assign %[[DESIGNATE_0]] to %[[DESIGNATE_1]] temporary_lhs : !fir.box<!fir.array<6xi32>>, !fir.box<!fir.array<6xi32>>
+! CHECK: acc.terminator
+! CHECK: }
+
+! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_box_Uxi32 : !fir.box<!fir.array<?xi32>> init {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box<!fir.array<?xi32>>):
+! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_0]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
+! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[BOX_DIMS_0]]#1 : (index) -> !fir.shape<1>
+! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[BOX_DIMS_0]]#1 : (index) -> !fir.shape<1>
+! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array<?xi32>, %[[BOX_DIMS_0]]#1 {bindc_name = "acc.private.init", uniq_name = ""}
+! CHECK: %[[CONSTANT_1:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_1:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_1]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
+! CHECK: %[[CONSTANT_2:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_2:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_2]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
+! CHECK: %[[SHAPE_SHIFT_0:.*]] = fir.shape_shift %[[BOX_DIMS_1]]#0, %[[BOX_DIMS_2]]#1 : (index, index) -> !fir.shapeshift<1>
+! CHECK: %[[EMBOX_0:.*]] = fir.embox %[[ALLOCMEM_0]](%[[SHAPE_SHIFT_0]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shapeshift<1>) -> !fir.box<!fir.array<?xi32>>
+! CHECK: acc.yield %[[EMBOX_0]] : !fir.box<!fir.array<?xi32>>
+
+! CHECK-LABEL: } copy {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box<!fir.array<?xi32>>, %[[VAL_1:.*]]: !fir.box<!fir.array<?xi32>>):
+! CHECK: hlfir.assign %[[VAL_0]] to %[[VAL_1]] temporary_lhs : !fir.box<!fir.array<?xi32>>, !fir.box<!fir.array<?xi32>>
+! CHECK: acc.terminator
+
+! CHECK-LABEL: } destroy {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box<!fir.array<?xi32>>, %[[VAL_1:.*]]: !fir.box<!fir.array<?xi32>>):
+! CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box<!fir.array<?xi32>>) -> !fir.ref<!fir.array<?xi32>>
+! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[BOX_ADDR_0]] : (!fir.ref<!fir.array<?xi32>>) -> !fir.heap<!fir.array<?xi32>>
+! CHECK: fir.freemem %[[CONVERT_0]] : !fir.heap<!fir.array<?xi32>>
+! CHECK: acc.terminator
+! CHECK: }
+
+! CHECK-LABEL: acc.private.recipe @privatization_box_UxUx2xi32 : !fir.box<!fir.array<?x?x2xi32>> init {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box<!fir.array<?x?x2xi32>>):
+! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_0]] : (!fir.box<!fir.array<?x?x2xi32>>, index) -> (index, index, index)
+! CHECK: %[[CONSTANT_1:.*]] = arith.constant 1 : index
+! CHECK: %[[BOX_DIMS_1:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_1]] : (!fir.box<!fir.array<?x?x2xi32>>, index) -> (index, index, index)
+! CHECK: %[[CONSTANT_2:.*]] = arith.constant 2 : index
+! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[BOX_DIMS_0]]#1, %[[BOX_DIMS_1]]#1, %[[CONSTANT_2]] : (index, index, index) -> !fir.shape<3>
+! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[BOX_DIMS_0]]#1, %[[BOX_DIMS_1]]#1, %[[CONSTANT_2]] : (index, index, index) -> !fir.shape<3>
+! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array<?x?x2xi32>, %[[BOX_DIMS_0]]#1, %[[BOX_DIMS_1]]#1 {bindc_name = "acc.private.init", uniq_name = ""}
+! CHECK: %[[CONSTANT_3:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_2:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_3]] : (!fir.box<!fir.array<?x?x2xi32>>, index) -> (index, index, index)
+! CHECK: %[[CONSTANT_4:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_3:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_4]] : (!fir.box<!fir.array<?x?x2xi32>>, index) -> (index, index, index)
+! CHECK: %[[CONSTANT_5:.*]] = arith.constant 1 : index
+! CHECK: %[[BOX_DIMS_4:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_5]] : (!fir.box<!fir.array<?x?x2xi32>>, index) -> (index, index, index)
+! CHECK: %[[CONSTANT_6:.*]] = arith.constant 1 : index
+! CHECK: %[[BOX_DIMS_5:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_6]] : (!fir.box<!fir.array<?x?x2xi32>>, index) -> (index, index, index)
+! CHECK: %[[CONSTANT_7:.*]] = arith.constant 2 : index
+! CHECK: %[[BOX_DIMS_6:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_7]] : (!fir.box<!fir.array<?x?x2xi32>>, index) -> (index, index, index)
+! CHECK: %[[CONSTANT_8:.*]] = arith.constant 2 : index
+! CHECK: %[[SHAPE_SHIFT_0:.*]] = fir.shape_shift %[[BOX_DIMS_2]]#0, %[[BOX_DIMS_3]]#1, %[[BOX_DIMS_4]]#0, %[[BOX_DIMS_5]]#1, %[[BOX_DIMS_6]]#0, %[[CONSTANT_8]] : (index, index, index, index, index, index) -> !fir.shapeshift<3>
+! CHECK: %[[EMBOX_0:.*]] = fir.embox %[[ALLOCMEM_0]](%[[SHAPE_SHIFT_0]]) : (!fir.heap<!fir.array<?x?x2xi32>>, !fir.shapeshift<3>) -> !fir.box<!fir.array<?x?x2xi32>>
+! CHECK: acc.yield %[[EMBOX_0]] : !fir.box<!fir.array<?x?x2xi32>>
+
+! CHECK-LABEL: } destroy {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box<!fir.array<?x?x2xi32>>, %[[VAL_1:.*]]: !fir.box<!fir.array<?x?x2xi32>>):
+! CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box<!fir.array<?x?x2xi32>>) -> !fir.ref<!fir.array<?x?x2xi32>>
+! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[BOX_ADDR_0]] : (!fir.ref<!fir.array<?x?x2xi32>>) -> !fir.heap<!fir.array<?x?x2xi32>>
+! CHECK: fir.freemem %[[CONVERT_0]] : !fir.heap<!fir.array<?x?x2xi32>>
+! CHECK: acc.terminator
+! CHECK: }
+
+! CHECK-LABEL: acc.private.recipe @privatization_ref_box_ptr_Uxi32 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>> init {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>):
+! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
+! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[LOAD_0]], %[[CONSTANT_0]] : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, index) -> (index, index, index)
+! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[BOX_DIMS_0]]#1 : (index) -> !fir.shape<1>
+! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[BOX_DIMS_0]]#1 : (index) -> !fir.shape<1>
+! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array<?xi32>, %[[BOX_DIMS_0]]#1 {bindc_name = "acc.private.init", uniq_name = ""}
+! CHECK: %[[CONSTANT_1:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_1:.*]]:3 = fir.box_dims %[[LOAD_0]], %[[CONSTANT_1]] : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, index) -> (index, index, index)
+! CHECK: %[[CONSTANT_2:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_2:.*]]:3 = fir.box_dims %[[LOAD_0]], %[[CONSTANT_2]] : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, index) -> (index, index, index)
+! CHECK: %[[SHAPE_SHIFT_0:.*]] = fir.shape_shift %[[BOX_DIMS_1]]#0, %[[BOX_DIMS_2]]#1 : (index, index) -> !fir.shapeshift<1>
+! CHECK: %[[EMBOX_0:.*]] = fir.embox %[[ALLOCMEM_0]](%[[SHAPE_SHIFT_0]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shapeshift<1>) -> !fir.box<!fir.ptr<!fir.array<?xi32>>>
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.box<!fir.ptr<!fir.array<?xi32>>>
+! CHECK: fir.store %[[EMBOX_0]] to %[[ALLOCA_0]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
+
+! CHECK-LABEL: } destroy {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>, %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>):
+! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
+! CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_0]] : (!fir.box<!fir.ptr<!fir.array<?xi32>>>) -> !fir.ptr<!fir.array<?xi32>>
+! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[BOX_ADDR_0]] : (!fir.ptr<!fir.array<?xi32>>) -> !fir.heap<!fir.array<?xi32>>
+! CHECK: fir.freemem %[[CONVERT_0]] : !fir.heap<!fir.array<?xi32>>
+! CHECK: acc.terminator
+! CHECK: }
+
+! CHECK-LABEL: acc.private.recipe @privatization_ref_box_heap_i32 : !fir.ref<!fir.box<!fir.heap<i32>>> init {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.heap<i32>>>):
+! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.heap<i32>>>
+! CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_0]] : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
+! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem i32 {bindc_name = "acc.private.init", uniq_name = ""}
+! CHECK: %[[EMBOX_0:.*]] = fir.embox %[[ALLOCMEM_0]] : (!fir.heap<i32>) -> !fir.box<!fir.heap<i32>>
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.box<!fir.heap<i32>>
+! CHECK: fir.store %[[EMBOX_0]] to %[[ALLOCA_0]] : !fir.ref<!fir.box<!fir.heap<i32>>>
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<!fir.box<!fir.heap<i32>>>
+
+! CHECK-LABEL: } destroy {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.heap<i32>>>, %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.heap<i32>>>):
+! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.heap<i32>>>
+! CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_0]] : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
+! CHECK: fir.freemem %[[BOX_ADDR_0]] : !fir.heap<i32>
+! CHECK: acc.terminator
+! CHECK: }
+
+! CHECK-LABEL: acc.private.recipe @privatization_ref_box_heap_Uxi32 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> init {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>):
+! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[LOAD_0]], %[[CONSTANT_0]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
+! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[BOX_DIMS_0]]#1 : (index) -> !fir.shape<1>
+! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[BOX_DIMS_0]]#1 : (index) -> !fir.shape<1>
+! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array<?xi32>, %[[BOX_DIMS_0]]#1 {bindc_name = "acc.private.init", uniq_name = ""}
+! CHECK: %[[CONSTANT_1:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_1:.*]]:3 = fir.box_dims %[[LOAD_0]], %[[CONSTANT_1]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
+! CHECK: %[[CONSTANT_2:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_2:.*]]:3 = fir.box_dims %[[LOAD_0]], %[[CONSTANT_2]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
+! CHECK: %[[SHAPE_SHIFT_0:.*]] = fir.shape_shift %[[BOX_DIMS_1]]#0, %[[BOX_DIMS_2]]#1 : (index, index) -> !fir.shapeshift<1>
+! CHECK: %[[EMBOX_0:.*]] = fir.embox %[[ALLOCMEM_0]](%[[SHAPE_SHIFT_0]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shapeshift<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xi32>>>
+! CHECK: fir.store %[[EMBOX_0]] to %[[ALLOCA_0]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+
+! CHECK-LABEL: } destroy {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>):
+! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+! CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_0]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
+! CHECK: fir.freemem %[[BOX_ADDR_0]] : !fir.heap<!fir.array<?xi32>>
+! CHECK: acc.terminator
+! CHECK: }
+
+! CHECK-LABEL: acc.private.recipe @privatization_box_Uxi32 : !fir.box<!fir.array<?xi32>> init {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box<!fir.array<?xi32>>):
+! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_0]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
+! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[BOX_DIMS_0]]#1 : (index) -> !fir.shape<1>
+! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[BOX_DIMS_0]]#1 : (index) -> !fir.shape<1>
+! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array<?xi32>, %[[BOX_DIMS_0]]#1 {bindc_name = "acc.private.init", uniq_name = ""}
+! CHECK: %[[CONSTANT_1:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_1:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_1]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
+! CHECK: %[[CONSTANT_2:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_2:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_2]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
+! CHECK: %[[SHAPE_SHIFT_0:.*]] = fir.shape_shift %[[BOX_DIMS_1]]#0, %[[BOX_DIMS_2]]#1 : (index, index) -> !fir.shapeshift<1>
+! CHECK: %[[EMBOX_0:.*]] = fir.embox %[[ALLOCMEM_0]](%[[SHAPE_SHIFT_0]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shapeshift<1>) -> !fir.box<!fir.array<?xi32>>
+! CHECK: acc.yield %[[EMBOX_0]] : !fir.box<!fir.array<?xi32>>
+
+! CHECK-LABEL: } destroy {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box<!fir.array<?xi32>>, %[[VAL_1:.*]]: !fir.box<!fir.array<?xi32>>):
+! CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box<!fir.array<?xi32>>) -> !fir.ref<!fir.array<?xi32>>
+! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[BOX_ADDR_0]] : (!fir.ref<!fir.array<?xi32>>) -> !fir.heap<!fir.array<?xi32>>
+! CHECK: fir.freemem %[[CONVERT_0]] : !fir.heap<!fir.array<?xi32>>
+! CHECK: acc.terminator
+! CHECK: }
+
+! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_section_lb50.ub99_ref_100xf32 : !fir.ref<!fir.array<100xf32>> init {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.array<100xf32>>):
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<50xf32> {bindc_name = "acc.private.init"}
+! CHECK: %[[CONSTANT_0:.*]] = arith.constant 1 : index
+! CHECK: %[[CONSTANT_1:.*]] = arith.constant 50 : index
+! CHECK: %[[CONSTANT_2:.*]] = arith.constant 99 : index
+! CHECK: %[[CONSTANT_3:.*]] = arith.constant 0 : index
+! CHECK: %[[CONSTANT_4:.*]] = arith.constant 49 : index
+! CHECK: %[[CONSTANT_5:.*]] = arith.constant 50 : index
+! CHECK: %[[CONSTANT_6:.*]] = arith.constant true
+! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_5]] : (index) -> !fir.shape<1>
+! CHECK: %[[CONSTANT_7:.*]] = arith.constant 1 : index
+! CHECK: %[[CONSTANT_8:.*]] = arith.constant 51 : index
+! CHECK: %[[CONSTANT_9:.*]] = arith.constant 100 : index
+! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_0]] (%[[CONSTANT_8]]:%[[CONSTANT_9]]:%[[CONSTANT_0]]) shape %[[SHAPE_0]] : (!fir.ref<!fir.array<100xf32>>, index, index, index, !fir.shape<1>) -> !fir.ref<!fir.array<50xf32>>
+! CHECK: %[[CONSTANT_10:.*]] = arith.constant 1 : index
+! CHECK: %[[CONSTANT_11:.*]] = arith.constant 100 : index
+! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[ALLOCA_0]] : (!fir.ref<!fir.array<50xf32>>) -> !fir.ref<!fir.array<100xf32>>
+! CHECK: %[[CONSTANT_12:.*]] = arith.constant 0 : index
+! CHECK: %[[SHAPE_SHIFT_0:.*]] = fir.shape_shift %[[CONSTANT_1]], %[[CONSTANT_11]] : (index, index) -> !fir.shapeshift<1>
+! CHECK: %[[ARRAY_COOR_0:.*]] = fir.array_coor %[[CONVERT_0]](%[[SHAPE_SHIFT_0]]) %[[CONSTANT_12]] : (!fir.ref<!fir.array<100xf32>>, !fir.shapeshift<1>, index) -> !fir.ref<f32>
+! CHECK: %[[CONVERT_1:.*]] = fir.convert %[[ARRAY_COOR_0]] : (!fir.ref<f32>) -> !fir.ref<!fir.array<100xf32>>
+! CHECK: acc.yield %[[CONVERT_1]] : !fir.ref<!fir.array<100xf32>>
+
+! CHECK-LABEL: } copy {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.array<100xf32>>, %[[VAL_1:.*]]: !fir.ref<!fir.array<100xf32>>):
+! CHECK: %[[CONSTANT_0:.*]] = arith.constant 1 : index
+! CHECK: %[[CONSTANT_1:.*]] = arith.constant 50 : index
+! CHECK: %[[CONSTANT_2:.*]] = arith.constant 99 : index
+! CHECK: %[[CONSTANT_3:.*]] = arith.constant 0 : index
+! CHECK: %[[CONSTANT_4:.*]] = arith.constant 49 : index
+! CHECK: %[[CONSTANT_5:.*]] = arith.constant 50 : index
+! CHECK: %[[CONSTANT_6:.*]] = arith.constant true
+! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_5]] : (index) -> !fir.shape<1>
+! CHECK: %[[CONSTANT_7:.*]] = arith.constant 1 : index
+! CHECK: %[[CONSTANT_8:.*]] = arith.constant 51 : index
+! CHECK: %[[CONSTANT_9:.*]] = arith.constant 100 : index
+! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_0]] (%[[CONSTANT_8]]:%[[CONSTANT_9]]:%[[CONSTANT_0]]) shape %[[SHAPE_0]] : (!fir.ref<!fir.array<100xf32>>, index, index, index, !fir.shape<1>) -> !fir.ref<!fir.array<50xf32>>
+! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_1]] (%[[CONSTANT_8]]:%[[CONSTANT_9]]:%[[CONSTANT_0]]) shape %[[SHAPE_0]] : (!fir.ref<!fir.array<100xf32>>, index, index, index, !fir.shape<1>) -> !fir.ref<!fir.array<50xf32>>
+! CHECK: hlfir.assign %[[DESIGNATE_0]] to %[[DESIGNATE_1]] temporary_lhs : !fir.ref<!fir.array<50xf32>>, !fir.ref<!fir.array<50xf32>>
+! CHECK: acc.terminator
+! CHECK: }
+
+! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_100xf32 : !fir.ref<!fir.array<100xf32>> init {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.array<100xf32>>):
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<100xf32> {bindc_name = "acc.private.init"}
+! CHECK: %[[CONSTANT_0:.*]] = arith.constant 100 : index
+! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_0]] : (index) -> !fir.shape<1>
+! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[CONSTANT_0]] : (index) -> !fir.shape<1>
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<!fir.array<100xf32>>
+
+! CHECK-LABEL: } copy {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.array<100xf32>>, %[[VAL_1:.*]]: !fir.ref<!fir.array<100xf32>>):
+! CHECK: hlfir.assign %[[VAL_0]] to %[[VAL_1]] temporary_lhs : !fir.ref<!fir.array<100xf32>>, !fir.ref<!fir.array<100xf32>>
+! CHECK: acc.terminator
+! CHECK: }
+
+! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_i32 : !fir.ref<i32> init {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>):
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 {bindc_name = "acc.private.init"}
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<i32>
+
+! CHECK-LABEL: } copy {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>, %[[VAL_1:.*]]: !fir.ref<i32>):
+! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_0]] : !fir.ref<i32>
+! CHECK: hlfir.assign %[[LOAD_0]] to %[[VAL_1]] temporary_lhs : i32, !fir.ref<i32>
+! CHECK: acc.terminator
+! CHECK: }
+
+! CHECK-LABEL: acc.private.recipe @privatization_section_lb0.ub49_ref_100xf32 : !fir.ref<!fir.array<100xf32>> init {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.array<100xf32>>):
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<50xf32> {bindc_name = "acc.private.init"}
+! CHECK: %[[CONSTANT_0:.*]] = arith.constant 1 : index
+! CHECK: %[[CONSTANT_1:.*]] = arith.constant 0 : index
+! CHECK: %[[CONSTANT_2:.*]] = arith.constant 49 : index
+! CHECK: %[[CONSTANT_3:.*]] = arith.constant 0 : index
+! CHECK: %[[CONSTANT_4:.*]] = arith.constant 50 : index
+! CHECK: %[[CONSTANT_5:.*]] = arith.constant true
+! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_4]] : (index) -> !fir.shape<1>
+! CHECK: %[[CONSTANT_6:.*]] = arith.constant 1 : index
+! CHECK: %[[CONSTANT_7:.*]] = arith.constant 1 : index
+! CHECK: %[[CONSTANT_8:.*]] = arith.constant 50 : index
+! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_0]] (%[[CONSTANT_7]]:%[[CONSTANT_8]]:%[[CONSTANT_0]]) shape %[[SHAPE_0]] : (!fir.ref<!fir.array<100xf32>>, index, index, index, !fir.shape<1>) -> !fir.ref<!fir.array<50xf32>>
+! CHECK: %[[CONSTANT_9:.*]] = arith.constant 1 : index
+! CHECK: %[[CONSTANT_10:.*]] = arith.constant 100 : index
+! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[ALLOCA_0]] : (!fir.ref<!fir.array<50xf32>>) -> !fir.ref<!fir.array<100xf32>>
+! CHECK: %[[CONSTANT_11:.*]] = arith.constant 0 : index
+! CHECK: %[[SHAPE_SHIFT_0:.*]] = fir.shape_shift %[[CONSTANT_1]], %[[CONSTANT_10]] : (index, index) -> !fir.shapeshift<1>
+! CHECK: %[[ARRAY_COOR_0:.*]] = fir.array_coor %[[CONVERT_0]](%[[SHAPE_SHIFT_0]]) %[[CONSTANT_11]] : (!fir.ref<!fir.array<100xf32>>, !fir.shapeshift<1>, index) -> !fir.ref<f32>
+! CHECK: %[[CONVERT_1:.*]] = fir.convert %[[ARRAY_COOR_0]] : (!fir.ref<f32>) -> !fir.ref<!fir.array<100xf32>>
+! CHECK: acc.yield %[[CONVERT_1]] : !fir.ref<!fir.array<100xf32>>
+! CHECK: }
+
+! CHECK-LABEL: acc.private.recipe @privatization_ref_100xf32 : !fir.ref<!fir.array<100xf32>> init {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.array<100xf32>>):
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<100xf32> {bindc_name = "acc.private.init"}
+! CHECK: %[[CONSTANT_0:.*]] = arith.constant 100 : index
+! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_0]] : (index) -> !fir.shape<1>
+! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[CONSTANT_0]] : (index) -> !fir.shape<1>
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<!fir.array<100xf32>>
+! CHECK: }
+
+! CHECK-LABEL: acc.private.recipe @privatization_ref_i32 : !fir.ref<i32> init {
+! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>):
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 {bindc_name = "acc.private.init"}
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<i32>
+! CHECK: }
program acc_private
integer :: i, c
@@ -267,8 +408,8 @@ program acc_private
! CHECK: %[[LB:.*]] = arith.constant 0 : index
! CHECK: %[[UB:.*]] = arith.constant 49 : index
! CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%[[LB]] : index) upperbound(%[[UB]] : index) extent(%{{.*}} : index) stride(%[[C1]] : index) startIdx(%[[C1]] : index)
-! CHECK: %[[B_PRIVATE:.*]] = acc.private varPtr(%[[DECLB]]#0 : !fir.ref<!fir.array<100xf32>>) bounds(%[[BOUND]]) recipe(@privatization_ref_50xf32) -> !fir.ref<!fir.array<50xf32>> {name = "b(1:50)"}
-! CHECK: acc.loop private(%[[B_PRIVATE]]{{.*}} : !fir.ref<!fir.array<50xf32>>{{.*}})
+! CHECK: %[[B_PRIVATE:.*]] = acc.private varPtr(%[[DECLB]]#0 : !fir.ref<!fir.array<100xf32>>) bounds(%[[BOUND]]) recipe(@privatization_section_lb0.ub49_ref_100xf32) -> !fir.ref<!fir.array<100xf32>> {name = "b(1:50)"}
+! CHECK: acc.loop private(%[[B_PRIVATE]]{{.*}} : !fir.ref<!fir.array<100xf32>>{{.*}})
!$acc parallel loop firstprivate(c)
DO i = 1, n
@@ -300,8 +441,8 @@ program acc_private
! CHECK: %[[LB:.*]] = arith.constant 50 : index
! CHECK: %[[UB:.*]] = arith.constant 99 : index
! CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%[[LB]] : index) upperbound(%[[UB]] : index) extent(%{{.*}} : index) stride(%[[C1]] : index) startIdx(%[[C1]] : index)
-! CHECK: %[[FP_B:.*]] = acc.firstprivate varPtr(%[[DECLB]]#0 : !fir.ref<!fir.array<100xf32>>) bounds(%[[BOUND]]) recipe(@firstprivatization_section_lb50.ub99_ref_50xf32) -> !fir.ref<!fir.array<50xf32>> {name = "b(51:100)"}
-! CHECK: acc.parallel {{.*}} firstprivate(%[[FP_B]] : !fir.ref<!fir.array<50xf32>>)
+! CHECK: %[[FP_B:.*]] = acc.firstprivate varPtr(%[[DECLB]]#0 : !fir.ref<!fir.array<100xf32>>) bounds(%[[BOUND]]) recipe(@firstprivatization_section_lb50.ub99_ref_100xf32) -> !fir.ref<!fir.array<100xf32>> {name = "b(51:100)"}
+! CHECK: acc.parallel {{.*}} firstprivate(%[[FP_B]] : !fir.ref<!fir.array<100xf32>>)
end program
diff --git a/flang/test/Lower/OpenACC/acc-reduction.f90 b/flang/test/Lower/OpenACC/acc-reduction.f90
index 940332b96e3f5..1981b01aa45d1 100644
--- a/flang/test/Lower/OpenACC/acc-reduction.f90
+++ b/flang/test/Lower/OpenACC/acc-reduction.f90
@@ -10,10 +10,32 @@
! CHECK: %[[CONSTANT_2:.*]] = arith.constant 1 : index
! CHECK: %[[BOX_DIMS_1:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_2]] : (!fir.box<!fir.array<?x?xf32>>, index) -> (index, index, index)
! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[BOX_DIMS_0]]#1, %[[BOX_DIMS_1]]#1 : (index, index) -> !fir.shape<2>
-! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array<?x?xf32>, %[[BOX_DIMS_0]]#1, %[[BOX_DIMS_1]]#1 {bindc_name = ".tmp", uniq_name = ""}
-! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCMEM_0]](%[[SHAPE_0]]) {uniq_name = ".tmp"} : (!fir.heap<!fir.array<?x?xf32>>, !fir.shape<2>) -> (!fir.box<!fir.array<?x?xf32>>, !fir.heap<!fir.array<?x?xf32>>)
-! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : f32, !fir.box<!fir.array<?x?xf32>>
-! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.box<!fir.array<?x?xf32>>
+! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[BOX_DIMS_0]]#1, %[[BOX_DIMS_1]]#1 : (index, index) -> !fir.shape<2>
+! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array<?x?xf32>, %[[BOX_DIMS_0]]#1, %[[BOX_DIMS_1]]#1 {bindc_name = "acc.reduction.init", uniq_name = ""}
+! CHECK: %[[EMBOX_0:.*]] = fir.embox %[[ALLOCMEM_0]](%[[SHAPE_1]]) : (!fir.heap<!fir.array<?x?xf32>>, !fir.shape<2>) -> !fir.box<!fir.array<?x?xf32>>
+! CHECK: %[[CONSTANT_3:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_2:.*]]:3 = fir.box_dims %[[EMBOX_0]], %[[CONSTANT_3]] : (!fir.box<!fir.array<?x?xf32>>, index) -> (index, index, index)
+! CHECK: %[[CONSTANT_4:.*]] = arith.constant 1 : index
+! CHECK: %[[BOX_DIMS_3:.*]]:3 = fir.box_dims %[[EMBOX_0]], %[[CONSTANT_4]] : (!fir.box<!fir.array<?x?xf32>>, index) -> (index, index, index)
+! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[BOX_DIMS_2]]#1, %[[BOX_DIMS_3]]#1 : (index, index) -> !fir.shape<2>
+! CHECK: %[[CONSTANT_5:.*]] = arith.constant 1 : index
+! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_5]] to %[[BOX_DIMS_3]]#1 step %[[CONSTANT_5]] unordered {
+! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_5]] to %[[BOX_DIMS_2]]#1 step %[[CONSTANT_5]] unordered {
+! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[EMBOX_0]] (%[[VAL_2]], %[[VAL_1]]) : (!fir.box<!fir.array<?x?xf32>>, index, index) -> !fir.ref<f32>
+! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_0]] temporary_lhs : f32, !fir.ref<f32>
+! CHECK: }
+! CHECK: }
+! CHECK: %[[CONSTANT_6:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_4:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_6]] : (!fir.box<!fir.array<?x?xf32>>, index) -> (index, index, index)
+! CHECK: %[[CONSTANT_7:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_5:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_7]] : (!fir.box<!fir.array<?x?xf32>>, index) -> (index, index, index)
+! CHECK: %[[CONSTANT_8:.*]] = arith.constant 1 : index
+! CHECK: %[[BOX_DIMS_6:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_8]] : (!fir.box<!fir.array<?x?xf32>>, index) -> (index, index, index)
+! CHECK: %[[CONSTANT_9:.*]] = arith.constant 1 : index
+! CHECK: %[[BOX_DIMS_7:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_9]] : (!fir.box<!fir.array<?x?xf32>>, index) -> (index, index, index)
+! CHECK: %[[SHAPE_SHIFT_0:.*]] = fir.shape_shift %[[BOX_DIMS_4]]#0, %[[BOX_DIMS_5]]#1, %[[BOX_DIMS_6]]#0, %[[BOX_DIMS_7]]#1 : (index, index, index, index) -> !fir.shapeshift<2>
+! CHECK: %[[EMBOX_1:.*]] = fir.embox %[[ALLOCMEM_0]](%[[SHAPE_SHIFT_0]]) : (!fir.heap<!fir.array<?x?xf32>>, !fir.shapeshift<2>) -> !fir.box<!fir.array<?x?xf32>>
+! CHECK: acc.yield %[[EMBOX_1]] : !fir.box<!fir.array<?x?xf32>>
! CHECK-LABEL: } combiner {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box<!fir.array<?x?xf32>>, %[[VAL_1:.*]]: !fir.box<!fir.array<?x?xf32>>):
@@ -74,14 +96,26 @@
! CHECK: %[[CONSTANT_1:.*]] = arith.constant 0 : index
! CHECK: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[LOAD_0]], %[[CONSTANT_1]] : (!fir.box<!fir.ptr<!fir.array<?xf32>>>, index) -> (index, index, index)
! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[BOX_DIMS_0]]#1 : (index) -> !fir.shape<1>
-! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array<?xf32>, %[[BOX_DIMS_0]]#1 {bindc_name = ".tmp", uniq_name = ""}
-! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCMEM_0]](%[[SHAPE_0]]) {uniq_name = ".tmp"} : (!fir.heap<!fir.array<?xf32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xf32>>, !fir.heap<!fir.array<?xf32>>)
+! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[BOX_DIMS_0]]#1 : (index) -> !fir.shape<1>
+! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array<?xf32>, %[[BOX_DIMS_0]]#1 {bindc_name = "acc.reduction.init", uniq_name = ""}
+! CHECK: %[[EMBOX_0:.*]] = fir.embox %[[ALLOCMEM_0]](%[[SHAPE_1]]) : (!fir.heap<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
+! CHECK: %[[CONSTANT_2:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_1:.*]]:3 = fir.box_dims %[[EMBOX_0]], %[[CONSTANT_2]] : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)
+! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[BOX_DIMS_1]]#1 : (index) -> !fir.shape<1>
+! CHECK: %[[CONSTANT_3:.*]] = arith.constant 1 : index
+! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_3]] to %[[BOX_DIMS_1]]#1 step %[[CONSTANT_3]] unordered {
+! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[EMBOX_0]] (%[[VAL_1]]) : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
+! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_0]] temporary_lhs : f32, !fir.ref<f32>
+! CHECK: }
+! CHECK: %[[CONSTANT_4:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_2:.*]]:3 = fir.box_dims %[[LOAD_0]], %[[CONSTANT_4]] : (!fir.box<!fir.ptr<!fir.array<?xf32>>>, index) -> (index, index, index)
+! CHECK: %[[CONSTANT_5:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_3:.*]]:3 = fir.box_dims %[[LOAD_0]], %[[CONSTANT_5]] : (!fir.box<!fir.ptr<!fir.array<?xf32>>>, index) -> (index, index, index)
+! CHECK: %[[SHAPE_SHIFT_0:.*]] = fir.shape_shift %[[BOX_DIMS_2]]#0, %[[BOX_DIMS_3]]#1 : (index, index) -> !fir.shapeshift<1>
+! CHECK: %[[EMBOX_1:.*]] = fir.embox %[[ALLOCMEM_0]](%[[SHAPE_SHIFT_0]]) : (!fir.heap<!fir.array<?xf32>>, !fir.shapeshift<1>) -> !fir.box<!fir.ptr<!fir.array<?xf32>>>
! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.box<!fir.ptr<!fir.array<?xf32>>>
-! CHECK: %[[DECLARE_1:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>)
-! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[DECLARE_1]]#0 : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<!fir.array<?xf32>>>
-! CHECK: fir.store %[[DECLARE_0]]#0 to %[[CONVERT_0]] : !fir.ref<!fir.box<!fir.array<?xf32>>>
-! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DECLARE_1]]#0 : f32, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
-! CHECK: acc.yield %[[DECLARE_1]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
+! CHECK: fir.store %[[EMBOX_1]] to %[[ALLOCA_0]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
! CHECK-LABEL: } combiner {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>, %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>):
@@ -131,14 +165,26 @@
! CHECK: %[[CONSTANT_1:.*]] = arith.constant 0 : index
! CHECK: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[LOAD_0]], %[[CONSTANT_1]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>, index) -> (index, index, index)
! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[BOX_DIMS_0]]#1 : (index) -> !fir.shape<1>
-! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array<?xf32>, %[[BOX_DIMS_0]]#1 {bindc_name = ".tmp", uniq_name = ""}
-! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCMEM_0]](%[[SHAPE_0]]) {uniq_name = ".tmp"} : (!fir.heap<!fir.array<?xf32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xf32>>, !fir.heap<!fir.array<?xf32>>)
+! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[BOX_DIMS_0]]#1 : (index) -> !fir.shape<1>
+! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array<?xf32>, %[[BOX_DIMS_0]]#1 {bindc_name = "acc.reduction.init", uniq_name = ""}
+! CHECK: %[[EMBOX_0:.*]] = fir.embox %[[ALLOCMEM_0]](%[[SHAPE_1]]) : (!fir.heap<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
+! CHECK: %[[CONSTANT_2:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_1:.*]]:3 = fir.box_dims %[[EMBOX_0]], %[[CONSTANT_2]] : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)
+! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[BOX_DIMS_1]]#1 : (index) -> !fir.shape<1>
+! CHECK: %[[CONSTANT_3:.*]] = arith.constant 1 : index
+! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_3]] to %[[BOX_DIMS_1]]#1 step %[[CONSTANT_3]] unordered {
+! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[EMBOX_0]] (%[[VAL_1]]) : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
+! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_0]] temporary_lhs : f32, !fir.ref<f32>
+! CHECK: }
+! CHECK: %[[CONSTANT_4:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_2:.*]]:3 = fir.box_dims %[[LOAD_0]], %[[CONSTANT_4]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>, index) -> (index, index, index)
+! CHECK: %[[CONSTANT_5:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_3:.*]]:3 = fir.box_dims %[[LOAD_0]], %[[CONSTANT_5]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>, index) -> (index, index, index)
+! CHECK: %[[SHAPE_SHIFT_0:.*]] = fir.shape_shift %[[BOX_DIMS_2]]#0, %[[BOX_DIMS_3]]#1 : (index, index) -> !fir.shapeshift<1>
+! CHECK: %[[EMBOX_1:.*]] = fir.embox %[[ALLOCMEM_0]](%[[SHAPE_SHIFT_0]]) : (!fir.heap<!fir.array<?xf32>>, !fir.shapeshift<1>) -> !fir.box<!fir.heap<!fir.array<?xf32>>>
! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xf32>>>
-! CHECK: %[[DECLARE_1:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!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: %[[CONVERT_0:.*]] = fir.convert %[[DECLARE_1]]#0 : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<!fir.array<?xf32>>>
-! CHECK: fir.store %[[DECLARE_0]]#0 to %[[CONVERT_0]] : !fir.ref<!fir.box<!fir.array<?xf32>>>
-! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DECLARE_1]]#0 : f32, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
-! CHECK: acc.yield %[[DECLARE_1]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+! CHECK: fir.store %[[EMBOX_1]] to %[[ALLOCA_0]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
! CHECK-LABEL: } combiner {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>):
@@ -182,52 +228,71 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_add_section_lb1.ub3_box_Uxi32 : !fir.box<!fir.array<?xi32>> reduction_operator <add> init {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box<!fir.array<?xi32>>):
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<3xi32> {bindc_name = "acc.reduction.init"}
! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : i32
-! CHECK: %[[CONSTANT_1:.*]] = arith.constant 0 : index
-! CHECK: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_1]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
-! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[BOX_DIMS_0]]#1 : (index) -> !fir.shape<1>
-! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array<?xi32>, %[[BOX_DIMS_0]]#1 {bindc_name = ".tmp", uniq_name = ""}
-! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCMEM_0]](%[[SHAPE_0]]) {uniq_name = ".tmp"} : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xi32>>, !fir.heap<!fir.array<?xi32>>)
-! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : i32, !fir.box<!fir.array<?xi32>>
-! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.box<!fir.array<?xi32>>
+! CHECK: %[[CONSTANT_1:.*]] = arith.constant 1 : index
+! CHECK: %[[CONSTANT_2:.*]] = arith.constant 1 : index
+! CHECK: %[[CONSTANT_3:.*]] = arith.constant 3 : index
+! CHECK: %[[CONSTANT_4:.*]] = arith.constant 0 : index
+! CHECK: %[[CONSTANT_5:.*]] = arith.constant 2 : index
+! CHECK: %[[CONSTANT_6:.*]] = arith.constant 3 : index
+! CHECK: %[[CONSTANT_7:.*]] = arith.constant true
+! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_6]] : (index) -> !fir.shape<1>
+! CHECK: %[[CONSTANT_8:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_8]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
+! CHECK: %[[ADDI_0:.*]] = arith.addi %[[BOX_DIMS_0]]#0, %[[CONSTANT_2]] : index
+! CHECK: %[[ADDI_1:.*]] = arith.addi %[[BOX_DIMS_0]]#0, %[[CONSTANT_3]] : index
+! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_0]] (%[[ADDI_0]]:%[[ADDI_1]]:%[[CONSTANT_1]]) shape %[[SHAPE_0]] : (!fir.box<!fir.array<?xi32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<3xi32>>
+! CHECK: %[[CONSTANT_9:.*]] = arith.constant 3 : index
+! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[CONSTANT_9]] : (index) -> !fir.shape<1>
+! CHECK: %[[CONSTANT_10:.*]] = arith.constant 1 : index
+! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_10]] to %[[CONSTANT_9]] step %[[CONSTANT_10]] unordered {
+! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[ALLOCA_0]] (%[[VAL_1]]) : (!fir.ref<!fir.array<3xi32>>, index) -> !fir.ref<i32>
+! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_1]] temporary_lhs : i32, !fir.ref<i32>
+! CHECK: }
+! CHECK: %[[CONSTANT_11:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_1:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_11]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
+! CHECK: %[[CONSTANT_12:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_2:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_12]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
+! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[ALLOCA_0]] : (!fir.ref<!fir.array<3xi32>>) -> !fir.ref<!fir.array<?xi32>>
+! CHECK: %[[CONSTANT_13:.*]] = arith.constant 0 : index
+! CHECK: %[[SHAPE_SHIFT_0:.*]] = fir.shape_shift %[[CONSTANT_2]], %[[BOX_DIMS_2]]#1 : (index, index) -> !fir.shapeshift<1>
+! CHECK: %[[ARRAY_COOR_0:.*]] = fir.array_coor %[[CONVERT_0]](%[[SHAPE_SHIFT_0]]) %[[CONSTANT_13]] : (!fir.ref<!fir.array<?xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>
+! CHECK: %[[CONVERT_1:.*]] = fir.convert %[[ARRAY_COOR_0]] : (!fir.ref<i32>) -> !fir.ref<!fir.array<?xi32>>
+! CHECK: %[[SHAPE_SHIFT_1:.*]] = fir.shape_shift %[[BOX_DIMS_1]]#0, %[[BOX_DIMS_2]]#1 : (index, index) -> !fir.shapeshift<1>
+! CHECK: %[[EMBOX_0:.*]] = fir.embox %[[CONVERT_1]](%[[SHAPE_SHIFT_1]]) : (!fir.ref<!fir.array<?xi32>>, !fir.shapeshift<1>) -> !fir.box<!fir.array<?xi32>>
+! CHECK: acc.yield %[[EMBOX_0]] : !fir.box<!fir.array<?xi32>>
! CHECK-LABEL: } combiner {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box<!fir.array<?xi32>>, %[[VAL_1:.*]]: !fir.box<!fir.array<?xi32>>):
! CHECK: %[[CONSTANT_0:.*]] = arith.constant 1 : index
-! CHECK: %[[CONSTANT_1:.*]] = arith.constant 3 : index
-! CHECK: %[[CONSTANT_2:.*]] = arith.constant 1 : index
+! CHECK: %[[CONSTANT_1:.*]] = arith.constant 1 : index
+! CHECK: %[[CONSTANT_2:.*]] = arith.constant 3 : index
! CHECK: %[[CONSTANT_3:.*]] = arith.constant 0 : index
-! CHECK: %[[SUBI_0:.*]] = arith.subi %[[CONSTANT_1]], %[[CONSTANT_0]] : index
-! CHECK: %[[ADDI_0:.*]] = arith.addi %[[SUBI_0]], %[[CONSTANT_2]] : index
-! CHECK: %[[DIVSI_0:.*]] = arith.divsi %[[ADDI_0]], %[[CONSTANT_2]] : index
-! CHECK: %[[CMPI_0:.*]] = arith.cmpi sgt, %[[DIVSI_0]], %[[CONSTANT_3]] : index
-! CHECK: %[[SELECT_0:.*]] = arith.select %[[CMPI_0]], %[[DIVSI_0]], %[[CONSTANT_3]] : index
-! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[SELECT_0]] : (index) -> !fir.shape<1>
-! CHECK: %[[BD_LHS:.*]]:3 = fir.box_dims %[[VAL_0]], %c0{{.*}} : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
-! CHECK: %[[LB_LHS:.*]] = arith.addi %[[BD_LHS]]#0, %c1{{.*}} : index
-! CHECK: %[[UB_LHS:.*]] = arith.addi %[[BD_LHS]]#0, %c3{{.*}} : index
-! CHECK: %[[BD_RHS:.*]]:3 = fir.box_dims %[[VAL_1]], %c0{{.*}} : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
-! CHECK: %[[LB_RHS:.*]] = arith.addi %[[BD_RHS]]#0, %c1{{.*}} : index
-! CHECK: %[[UB_RHS:.*]] = arith.addi %[[BD_RHS]]#0, %c3{{.*}} : index
-! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_1]] (%[[LB_RHS]]:%[[UB_RHS]]:%c1{{.*}}) shape %[[SHAPE_0]] : (!fir.box<!fir.array<?xi32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xi32>>
-! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%[[LB_LHS]]:%[[UB_LHS]]:%c1{{.*}}) shape %[[SHAPE_0]] : (!fir.box<!fir.array<?xi32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xi32>>
-! CHECK: %[[CONSTANT_4:.*]] = arith.constant 1 : index
-! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_4]] to %[[SELECT_0]] step %[[CONSTANT_4]] unordered {
-! CHECK: %[[DESIGNATE_2:.*]] = hlfir.designate %[[DESIGNATE_0]] (%[[VAL_2]]) : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
+! CHECK: %[[CONSTANT_4:.*]] = arith.constant 2 : index
+! CHECK: %[[CONSTANT_5:.*]] = arith.constant 3 : index
+! CHECK: %[[CONSTANT_6:.*]] = arith.constant true
+! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_5]] : (index) -> !fir.shape<1>
+! CHECK: %[[CONSTANT_7:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_7]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
+! CHECK: %[[ADDI_0:.*]] = arith.addi %[[BOX_DIMS_0]]#0, %[[CONSTANT_1]] : index
+! CHECK: %[[ADDI_1:.*]] = arith.addi %[[BOX_DIMS_0]]#0, %[[CONSTANT_2]] : index
+! CHECK: %[[CONSTANT_8:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_1:.*]]:3 = fir.box_dims %[[VAL_1]], %[[CONSTANT_8]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
+! CHECK: %[[ADDI_2:.*]] = arith.addi %[[BOX_DIMS_1]]#0, %[[CONSTANT_1]] : index
+! CHECK: %[[ADDI_3:.*]] = arith.addi %[[BOX_DIMS_1]]#0, %[[CONSTANT_2]] : index
+! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_1]] (%[[ADDI_2]]:%[[ADDI_3]]:%[[CONSTANT_0]]) shape %[[SHAPE_0]] : (!fir.box<!fir.array<?xi32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<3xi32>>
+! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%[[ADDI_0]]:%[[ADDI_1]]:%[[CONSTANT_0]]) shape %[[SHAPE_0]] : (!fir.box<!fir.array<?xi32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<3xi32>>
+! CHECK: %[[CONSTANT_9:.*]] = arith.constant 1 : index
+! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_9]] to %[[CONSTANT_5]] step %[[CONSTANT_9]] unordered {
+! CHECK: %[[DESIGNATE_2:.*]] = hlfir.designate %[[DESIGNATE_0]] (%[[VAL_2]]) : (!fir.box<!fir.array<3xi32>>, index) -> !fir.ref<i32>
! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_2]] : !fir.ref<i32>
-! CHECK: %[[DESIGNATE_3:.*]] = hlfir.designate %[[DESIGNATE_1]] (%[[VAL_2]]) : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
+! CHECK: %[[DESIGNATE_3:.*]] = hlfir.designate %[[DESIGNATE_1]] (%[[VAL_2]]) : (!fir.box<!fir.array<3xi32>>, index) -> !fir.ref<i32>
! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_3]] : !fir.ref<i32>
-! CHECK: %[[ADDI_1:.*]] = arith.addi %[[LOAD_1]], %[[LOAD_0]] : i32
-! CHECK: hlfir.assign %[[ADDI_1]] to %[[DESIGNATE_3]] : i32, !fir.ref<i32>
+! CHECK: %[[ADDI_4:.*]] = arith.addi %[[LOAD_1]], %[[LOAD_0]] : i32
+! CHECK: hlfir.assign %[[ADDI_4]] to %[[DESIGNATE_3]] : i32, !fir.ref<i32>
! CHECK: }
! CHECK: acc.yield %[[VAL_0]] : !fir.box<!fir.array<?xi32>>
-
-! CHECK-LABEL: } destroy {
-! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box<!fir.array<?xi32>>, %[[VAL_1:.*]]: !fir.box<!fir.array<?xi32>>):
-! CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box<!fir.array<?xi32>>) -> !fir.ref<!fir.array<?xi32>>
-! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[BOX_ADDR_0]] : (!fir.ref<!fir.array<?xi32>>) -> !fir.heap<!fir.array<?xi32>>
-! CHECK: fir.freemem %[[CONVERT_0]] : !fir.heap<!fir.array<?xi32>>
-! CHECK: acc.terminator
! CHECK: }
! CHECK-LABEL: acc.reduction.recipe @reduction_max_box_Uxf32 : !fir.box<!fir.array<?xf32>> reduction_operator <max> init {
@@ -236,10 +301,24 @@
! CHECK: %[[CONSTANT_1:.*]] = arith.constant 0 : index
! CHECK: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_1]] : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)
! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[BOX_DIMS_0]]#1 : (index) -> !fir.shape<1>
-! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array<?xf32>, %[[BOX_DIMS_0]]#1 {bindc_name = ".tmp", uniq_name = ""}
-! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCMEM_0]](%[[SHAPE_0]]) {uniq_name = ".tmp"} : (!fir.heap<!fir.array<?xf32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xf32>>, !fir.heap<!fir.array<?xf32>>)
-! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : f32, !fir.box<!fir.array<?xf32>>
-! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.box<!fir.array<?xf32>>
+! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[BOX_DIMS_0]]#1 : (index) -> !fir.shape<1>
+! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array<?xf32>, %[[BOX_DIMS_0]]#1 {bindc_name = "acc.reduction.init", uniq_name = ""}
+! CHECK: %[[EMBOX_0:.*]] = fir.embox %[[ALLOCMEM_0]](%[[SHAPE_1]]) : (!fir.heap<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
+! CHECK: %[[CONSTANT_2:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_1:.*]]:3 = fir.box_dims %[[EMBOX_0]], %[[CONSTANT_2]] : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)
+! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[BOX_DIMS_1]]#1 : (index) -> !fir.shape<1>
+! CHECK: %[[CONSTANT_3:.*]] = arith.constant 1 : index
+! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_3]] to %[[BOX_DIMS_1]]#1 step %[[CONSTANT_3]] unordered {
+! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[EMBOX_0]] (%[[VAL_1]]) : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
+! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_0]] temporary_lhs : f32, !fir.ref<f32>
+! CHECK: }
+! CHECK: %[[CONSTANT_4:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_2:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_4]] : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)
+! CHECK: %[[CONSTANT_5:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_3:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_5]] : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)
+! CHECK: %[[SHAPE_SHIFT_0:.*]] = fir.shape_shift %[[BOX_DIMS_2]]#0, %[[BOX_DIMS_3]]#1 : (index, index) -> !fir.shapeshift<1>
+! CHECK: %[[EMBOX_1:.*]] = fir.embox %[[ALLOCMEM_0]](%[[SHAPE_SHIFT_0]]) : (!fir.heap<!fir.array<?xf32>>, !fir.shapeshift<1>) -> !fir.box<!fir.array<?xf32>>
+! CHECK: acc.yield %[[EMBOX_1]] : !fir.box<!fir.array<?xf32>>
! CHECK-LABEL: } combiner {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box<!fir.array<?xf32>>, %[[VAL_1:.*]]: !fir.box<!fir.array<?xf32>>):
@@ -285,10 +364,24 @@
! CHECK: %[[CONSTANT_1:.*]] = arith.constant 0 : index
! CHECK: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_1]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[BOX_DIMS_0]]#1 : (index) -> !fir.shape<1>
-! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array<?xi32>, %[[BOX_DIMS_0]]#1 {bindc_name = ".tmp", uniq_name = ""}
-! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCMEM_0]](%[[SHAPE_0]]) {uniq_name = ".tmp"} : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xi32>>, !fir.heap<!fir.array<?xi32>>)
-! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : i32, !fir.box<!fir.array<?xi32>>
-! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.box<!fir.array<?xi32>>
+! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[BOX_DIMS_0]]#1 : (index) -> !fir.shape<1>
+! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array<?xi32>, %[[BOX_DIMS_0]]#1 {bindc_name = "acc.reduction.init", uniq_name = ""}
+! CHECK: %[[EMBOX_0:.*]] = fir.embox %[[ALLOCMEM_0]](%[[SHAPE_1]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<?xi32>>
+! CHECK: %[[CONSTANT_2:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_1:.*]]:3 = fir.box_dims %[[EMBOX_0]], %[[CONSTANT_2]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
+! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[BOX_DIMS_1]]#1 : (index) -> !fir.shape<1>
+! CHECK: %[[CONSTANT_3:.*]] = arith.constant 1 : index
+! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_3]] to %[[BOX_DIMS_1]]#1 step %[[CONSTANT_3]] unordered {
+! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[EMBOX_0]] (%[[VAL_1]]) : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
+! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_0]] temporary_lhs : i32, !fir.ref<i32>
+! CHECK: }
+! CHECK: %[[CONSTANT_4:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_2:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_4]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
+! CHECK: %[[CONSTANT_5:.*]] = arith.constant 0 : index
+! CHECK: %[[BOX_DIMS_3:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_5]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
+! CHECK: %[[SHAPE_SHIFT_0:.*]] = fir.shape_shift %[[BOX_DIMS_2]]#0, %[[BOX_DIMS_3]]#1 : (index, index) -> !fir.shapeshift<1>
+! CHECK: %[[EMBOX_1:.*]] = fir.embox %[[ALLOCMEM_0]](%[[SHAPE_SHIFT_0]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shapeshift<1>) -> !fir.box<!fir.array<?xi32>>
+! CHECK: acc.yield %[[EMBOX_1]] : !fir.box<!fir.array<?xi32>>
! CHECK-LABEL: } combiner {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box<!fir.array<?xi32>>, %[[VAL_1:.*]]: !fir.box<!fir.array<?xi32>>):
@@ -329,58 +422,78 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_add_section_lb0.ub9xlb0.ub19_ref_10x20xi32 : !fir.ref<!fir.array<10x20xi32>> reduction_operator <add> init {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.array<10x20xi32>>):
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<10x20xi32> {bindc_name = "acc.reduction.init"}
! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : i32
-! CHECK: %[[CONSTANT_1:.*]] = arith.constant 10 : index
-! CHECK: %[[CONSTANT_2:.*]] = arith.constant 20 : index
-! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_1]], %[[CONSTANT_2]] : (index, index) -> !fir.shape<2>
-! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<10x20xi32>
-! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]](%[[SHAPE_0]]) {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.array<10x20xi32>>, !fir.shape<2>) -> (!fir.ref<!fir.array<10x20xi32>>, !fir.ref<!fir.array<10x20xi32>>)
-! CHECK: %[[CONSTANT_3:.*]] = arith.constant 0 : index
-! CHECK: %[[CONSTANT_4:.*]] = arith.constant 19 : index
-! CHECK: %[[CONSTANT_5:.*]] = arith.constant 1 : index
-! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_3]] to %[[CONSTANT_4]] step %[[CONSTANT_5]] {
-! CHECK: %[[CONSTANT_6:.*]] = arith.constant 0 : index
-! CHECK: %[[CONSTANT_7:.*]] = arith.constant 9 : index
-! CHECK: %[[CONSTANT_8:.*]] = arith.constant 1 : index
-! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_6]] to %[[CONSTANT_7]] step %[[CONSTANT_8]] {
-! CHECK: %[[COORDINATE_OF_0:.*]] = fir.coordinate_of %[[DECLARE_0]]#0, %[[VAL_2]], %[[VAL_1]] : (!fir.ref<!fir.array<10x20xi32>>, index, index) -> !fir.ref<i32>
-! CHECK: fir.store %[[CONSTANT_0]] to %[[COORDINATE_OF_0]] : !fir.ref<i32>
+! CHECK: %[[CONSTANT_1:.*]] = arith.constant 1 : index
+! CHECK: %[[CONSTANT_2:.*]] = arith.constant 0 : index
+! CHECK: %[[CONSTANT_3:.*]] = arith.constant 9 : index
+! CHECK: %[[CONSTANT_4:.*]] = arith.constant 0 : index
+! CHECK: %[[CONSTANT_5:.*]] = arith.constant 19 : index
+! CHECK: %[[CONSTANT_6:.*]] = arith.constant 0 : index
+! CHECK: %[[CONSTANT_7:.*]] = arith.constant 10 : index
+! CHECK: %[[CONSTANT_8:.*]] = arith.constant true
+! CHECK: %[[CONSTANT_9:.*]] = arith.constant 0 : index
+! CHECK: %[[CONSTANT_10:.*]] = arith.constant 20 : index
+! CHECK: %[[CONSTANT_11:.*]] = arith.constant true
+! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_7]], %[[CONSTANT_10]] : (index, index) -> !fir.shape<2>
+! CHECK: %[[CONSTANT_12:.*]] = arith.constant 1 : index
+! CHECK: %[[CONSTANT_13:.*]] = arith.constant 1 : index
+! CHECK: %[[CONSTANT_14:.*]] = arith.constant 10 : index
+! CHECK: %[[CONSTANT_15:.*]] = arith.constant 1 : index
+! CHECK: %[[CONSTANT_16:.*]] = arith.constant 1 : index
+! CHECK: %[[CONSTANT_17:.*]] = arith.constant 20 : index
+! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_0]] (%[[CONSTANT_13]]:%[[CONSTANT_14]]:%[[CONSTANT_1]], %[[CONSTANT_16]]:%[[CONSTANT_17]]:%[[CONSTANT_1]]) shape %[[SHAPE_0]] : (!fir.ref<!fir.array<10x20xi32>>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.ref<!fir.array<10x20xi32>>
+! CHECK: %[[CONSTANT_18:.*]] = arith.constant 10 : index
+! CHECK: %[[CONSTANT_19:.*]] = arith.constant 20 : index
+! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[CONSTANT_18]], %[[CONSTANT_19]] : (index, index) -> !fir.shape<2>
+! CHECK: %[[CONSTANT_20:.*]] = arith.constant 1 : index
+! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_20]] to %[[CONSTANT_19]] step %[[CONSTANT_20]] unordered {
+! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_20]] to %[[CONSTANT_18]] step %[[CONSTANT_20]] unordered {
+! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[ALLOCA_0]] (%[[VAL_2]], %[[VAL_1]]) : (!fir.ref<!fir.array<10x20xi32>>, index, index) -> !fir.ref<i32>
+! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_1]] temporary_lhs : i32, !fir.ref<i32>
! CHECK: }
! CHECK: }
-! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref<!fir.array<10x20xi32>>
+! CHECK: %[[CONSTANT_21:.*]] = arith.constant 1 : index
+! CHECK: %[[CONSTANT_22:.*]] = arith.constant 10 : index
+! CHECK: %[[CONSTANT_23:.*]] = arith.constant 1 : index
+! CHECK: %[[CONSTANT_24:.*]] = arith.constant 20 : index
+! CHECK: %[[CONSTANT_25:.*]] = arith.constant 0 : index
+! CHECK: %[[SHAPE_SHIFT_0:.*]] = fir.shape_shift %[[CONSTANT_2]], %[[CONSTANT_22]], %[[CONSTANT_4]], %[[CONSTANT_24]] : (index, index, index, index) -> !fir.shapeshift<2>
+! CHECK: %[[ARRAY_COOR_0:.*]] = fir.array_coor %[[ALLOCA_0]](%[[SHAPE_SHIFT_0]]) %[[CONSTANT_25]], %[[CONSTANT_25]] : (!fir.ref<!fir.array<10x20xi32>>, !fir.shapeshift<2>, index, index) -> !fir.ref<i32>
+! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[ARRAY_COOR_0]] : (!fir.ref<i32>) -> !fir.ref<!fir.array<10x20xi32>>
+! CHECK: acc.yield %[[CONVERT_0]] : !fir.ref<!fir.array<10x20xi32>>
! CHECK-LABEL: } combiner {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.array<10x20xi32>>, %[[VAL_1:.*]]: !fir.ref<!fir.array<10x20xi32>>):
-! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : index
-! CHECK: %[[CONSTANT_1:.*]] = arith.constant 9 : index
-! CHECK: %[[CONSTANT_2:.*]] = arith.constant 1 : index
+! CHECK: %[[CONSTANT_0:.*]] = arith.constant 1 : index
+! CHECK: %[[CONSTANT_1:.*]] = arith.constant 0 : index
+! CHECK: %[[CONSTANT_2:.*]] = arith.constant 9 : index
! CHECK: %[[CONSTANT_3:.*]] = arith.constant 0 : index
! CHECK: %[[CONSTANT_4:.*]] = arith.constant 19 : index
-! CHECK: %[[CONSTANT_5:.*]] = arith.constant 1 : index
-! CHECK: %[[CONSTANT_6:.*]] = arith.constant 0 : index
-! CHECK: %[[SUBI_0:.*]] = arith.subi %[[CONSTANT_1]], %[[CONSTANT_0]] : index
-! CHECK: %[[ADDI_0:.*]] = arith.addi %[[SUBI_0]], %[[CONSTANT_2]] : index
-! CHECK: %[[DIVSI_0:.*]] = arith.divsi %[[ADDI_0]], %[[CONSTANT_2]] : index
-! CHECK: %[[CMPI_0:.*]] = arith.cmpi sgt, %[[DIVSI_0]], %[[CONSTANT_6]] : index
-! CHECK: %[[SELECT_0:.*]] = arith.select %[[CMPI_0]], %[[DIVSI_0]], %[[CONSTANT_6]] : index
-! CHECK: %[[CONSTANT_7:.*]] = arith.constant 0 : index
-! CHECK: %[[SUBI_1:.*]] = arith.subi %[[CONSTANT_4]], %[[CONSTANT_3]] : index
-! CHECK: %[[ADDI_1:.*]] = arith.addi %[[SUBI_1]], %[[CONSTANT_5]] : index
-! CHECK: %[[DIVSI_1:.*]] = arith.divsi %[[ADDI_1]], %[[CONSTANT_5]] : index
-! CHECK: %[[CMPI_1:.*]] = arith.cmpi sgt, %[[DIVSI_1]], %[[CONSTANT_7]] : index
-! CHECK: %[[SELECT_1:.*]] = arith.select %[[CMPI_1]], %[[DIVSI_1]], %[[CONSTANT_7]] : index
-! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[SELECT_0]], %[[SELECT_1]] : (index, index) -> !fir.shape<2>
-! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_1]] (%c1{{.*}}:%c10{{.*}}:%c1{{.*}}, %c1{{.*}}:%c20{{.*}}:%c1{{.*}}) shape %[[SHAPE_0]] : (!fir.ref<!fir.array<10x20xi32>>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.ref<!fir.array<10x20xi32>>
-! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%c1{{.*}}:%c10{{.*}}:%c1{{.*}}, %c1{{.*}}:%c20{{.*}}:%c1{{.*}}) shape %[[SHAPE_0]] : (!fir.ref<!fir.array<10x20xi32>>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.ref<!fir.array<10x20xi32>>
-! CHECK: %[[CONSTANT_8:.*]] = arith.constant 1 : index
-! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_8]] to %[[SELECT_1]] step %[[CONSTANT_8]] unordered {
-! CHECK: fir.do_loop %[[VAL_3:.*]] = %[[CONSTANT_8]] to %[[SELECT_0]] step %[[CONSTANT_8]] unordered {
+! CHECK: %[[CONSTANT_5:.*]] = arith.constant 0 : index
+! CHECK: %[[CONSTANT_6:.*]] = arith.constant 10 : index
+! CHECK: %[[CONSTANT_7:.*]] = arith.constant true
+! CHECK: %[[CONSTANT_8:.*]] = arith.constant 0 : index
+! CHECK: %[[CONSTANT_9:.*]] = arith.constant 20 : index
+! CHECK: %[[CONSTANT_10:.*]] = arith.constant true
+! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_6]], %[[CONSTANT_9]] : (index, index) -> !fir.shape<2>
+! CHECK: %[[CONSTANT_11:.*]] = arith.constant 1 : index
+! CHECK: %[[CONSTANT_12:.*]] = arith.constant 1 : index
+! CHECK: %[[CONSTANT_13:.*]] = arith.constant 10 : index
+! CHECK: %[[CONSTANT_14:.*]] = arith.constant 1 : index
+! CHECK: %[[CONSTANT_15:.*]] = arith.constant 1 : index
+! CHECK: %[[CONSTANT_16:.*]] = arith.constant 20 : index
+! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_1]] (%[[CONSTANT_12]]:%[[CONSTANT_13]]:%[[CONSTANT_0]], %[[CONSTANT_15]]:%[[CONSTANT_16]]:%[[CONSTANT_0]]) shape %[[SHAPE_0]] : (!fir.ref<!fir.array<10x20xi32>>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.ref<!fir.array<10x20xi32>>
+! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%[[CONSTANT_12]]:%[[CONSTANT_13]]:%[[CONSTANT_0]], %[[CONSTANT_15]]:%[[CONSTANT_16]]:%[[CONSTANT_0]]) shape %[[SHAPE_0]] : (!fir.ref<!fir.array<10x20xi32>>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.ref<!fir.array<10x20xi32>>
+! CHECK: %[[CONSTANT_17:.*]] = arith.constant 1 : index
+! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_17]] to %[[CONSTANT_9]] step %[[CONSTANT_17]] unordered {
+! CHECK: fir.do_loop %[[VAL_3:.*]] = %[[CONSTANT_17]] to %[[CONSTANT_6]] step %[[CONSTANT_17]] unordered {
! CHECK: %[[DESIGNATE_2:.*]] = hlfir.designate %[[DESIGNATE_0]] (%[[VAL_3]], %[[VAL_2]]) : (!fir.ref<!fir.array<10x20xi32>>, index, index) -> !fir.ref<i32>
! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_2]] : !fir.ref<i32>
! CHECK: %[[DESIGNATE_3:.*]] = hlfir.designate %[[DESIGNATE_1]] (%[[VAL_3]], %[[VAL_2]]) : (!fir.ref<!fir.array<10x20xi32>>, index, index) -> !fir.ref<i32>
! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_3]] : !fir.ref<i32>
-! CHECK: %[[ADDI_2:.*]] = arith.addi %[[LOAD_1]], %[[LOAD_0]] : i32
-! CHECK: hlfir.assign %[[ADDI_2]] to %[[DESIGNATE_3]] : i32, !fir.ref<i32>
+! CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_1]], %[[LOAD_0]] : i32
+! CHECK: hlfir.assign %[[ADDI_0]] to %[[DESIGNATE_3]] : i32, !fir.ref<i32>
! CHECK: }
! CHECK: }
! CHECK: acc.yield %[[VAL_0]] : !fir.ref<!fir.array<10x20xi32>>
@@ -388,42 +501,59 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_add_section_lb10.ub19_ref_100xi32 : !fir.ref<!fir.array<100xi32>> reduction_operator <add> init {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.array<100xi32>>):
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<10xi32> {bindc_name = "acc.reduction.init"}
! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : i32
-! CHECK: %[[CONSTANT_1:.*]] = arith.constant 100 : index
-! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_1]] : (index) -> !fir.shape<1>
-! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<100xi32>
-! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]](%[[SHAPE_0]]) {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.array<100xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<100xi32>>, !fir.ref<!fir.array<100xi32>>)
-! CHECK: %[[CONSTANT_2:.*]] = arith.constant 0 : index
-! CHECK: %[[CONSTANT_3:.*]] = arith.constant 99 : index
-! CHECK: %[[CONSTANT_4:.*]] = arith.constant 1 : index
-! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_2]] to %[[CONSTANT_3]] step %[[CONSTANT_4]] {
-! CHECK: %[[COORDINATE_OF_0:.*]] = fir.coordinate_of %[[DECLARE_0]]#0, %[[VAL_1]] : (!fir.ref<!fir.array<100xi32>>, index) -> !fir.ref<i32>
-! CHECK: fir.store %[[CONSTANT_0]] to %[[COORDINATE_OF_0]] : !fir.ref<i32>
+! CHECK: %[[CONSTANT_1:.*]] = arith.constant 1 : index
+! CHECK: %[[CONSTANT_2:.*]] = arith.constant 10 : index
+! CHECK: %[[CONSTANT_3:.*]] = arith.constant 19 : index
+! CHECK: %[[CONSTANT_4:.*]] = arith.constant 0 : index
+! CHECK: %[[CONSTANT_5:.*]] = arith.constant 9 : index
+! CHECK: %[[CONSTANT_6:.*]] = arith.constant 10 : index
+! CHECK: %[[CONSTANT_7:.*]] = arith.constant true
+! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_6]] : (index) -> !fir.shape<1>
+! CHECK: %[[CONSTANT_8:.*]] = arith.constant 1 : index
+! CHECK: %[[CONSTANT_9:.*]] = arith.constant 11 : index
+! CHECK: %[[CONSTANT_10:.*]] = arith.constant 20 : index
+! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_0]] (%[[CONSTANT_9]]:%[[CONSTANT_10]]:%[[CONSTANT_1]]) shape %[[SHAPE_0]] : (!fir.ref<!fir.array<100xi32>>, index, index, index, !fir.shape<1>) -> !fir.ref<!fir.array<10xi32>>
+! CHECK: %[[CONSTANT_11:.*]] = arith.constant 10 : index
+! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[CONSTANT_11]] : (index) -> !fir.shape<1>
+! CHECK: %[[CONSTANT_12:.*]] = arith.constant 1 : index
+! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_12]] to %[[CONSTANT_11]] step %[[CONSTANT_12]] unordered {
+! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[ALLOCA_0]] (%[[VAL_1]]) : (!fir.ref<!fir.array<10xi32>>, index) -> !fir.ref<i32>
+! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_1]] temporary_lhs : i32, !fir.ref<i32>
! CHECK: }
-! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref<!fir.array<100xi32>>
+! CHECK: %[[CONSTANT_13:.*]] = arith.constant 1 : index
+! CHECK: %[[CONSTANT_14:.*]] = arith.constant 100 : index
+! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[ALLOCA_0]] : (!fir.ref<!fir.array<10xi32>>) -> !fir.ref<!fir.array<100xi32>>
+! CHECK: %[[CONSTANT_15:.*]] = arith.constant 0 : index
+! CHECK: %[[SHAPE_SHIFT_0:.*]] = fir.shape_shift %[[CONSTANT_2]], %[[CONSTANT_14]] : (index, index) -> !fir.shapeshift<1>
+! CHECK: %[[ARRAY_COOR_0:.*]] = fir.array_coor %[[CONVERT_0]](%[[SHAPE_SHIFT_0]]) %[[CONSTANT_15]] : (!fir.ref<!fir.array<100xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>
+! CHECK: %[[CONVERT_1:.*]] = fir.convert %[[ARRAY_COOR_0]] : (!fir.ref<i32>) -> !fir.ref<!fir.array<100xi32>>
+! CHECK: acc.yield %[[CONVERT_1]] : !fir.ref<!fir.array<100xi32>>
! CHECK-LABEL: } combiner {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.array<100xi32>>, %[[VAL_1:.*]]: !fir.ref<!fir.array<100xi32>>):
-! CHECK: %[[CONSTANT_0:.*]] = arith.constant 10 : index
-! CHECK: %[[CONSTANT_1:.*]] = arith.constant 19 : index
-! CHECK: %[[CONSTANT_2:.*]] = arith.constant 1 : index
+! CHECK: %[[CONSTANT_0:.*]] = arith.constant 1 : index
+! CHECK: %[[CONSTANT_1:.*]] = arith.constant 10 : index
+! CHECK: %[[CONSTANT_2:.*]] = arith.constant 19 : index
! CHECK: %[[CONSTANT_3:.*]] = arith.constant 0 : index
-! CHECK: %[[SUBI_0:.*]] = arith.subi %[[CONSTANT_1]], %[[CONSTANT_0]] : index
-! CHECK: %[[ADDI_0:.*]] = arith.addi %[[SUBI_0]], %[[CONSTANT_2]] : index
-! CHECK: %[[DIVSI_0:.*]] = arith.divsi %[[ADDI_0]], %[[CONSTANT_2]] : index
-! CHECK: %[[CMPI_0:.*]] = arith.cmpi sgt, %[[DIVSI_0]], %[[CONSTANT_3]] : index
-! CHECK: %[[SELECT_0:.*]] = arith.select %[[CMPI_0]], %[[DIVSI_0]], %[[CONSTANT_3]] : index
-! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[SELECT_0]] : (index) -> !fir.shape<1>
-! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_1]] (%c11{{.*}}:%c20{{.*}}:%c1{{.*}}) shape %[[SHAPE_0]] : (!fir.ref<!fir.array<100xi32>>, index, index, index, !fir.shape<1>) -> !fir.ref<!fir.array<100xi32>>
-! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%c11{{.*}}:%c20{{.*}}:%c1{{.*}}) shape %[[SHAPE_0]] : (!fir.ref<!fir.array<100xi32>>, index, index, index, !fir.shape<1>) -> !fir.ref<!fir.array<100xi32>>
-! CHECK: %[[CONSTANT_4:.*]] = arith.constant 1 : index
-! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_4]] to %[[SELECT_0]] step %[[CONSTANT_4]] unordered {
-! CHECK: %[[DESIGNATE_2:.*]] = hlfir.designate %[[DESIGNATE_0]] (%[[VAL_2]]) : (!fir.ref<!fir.array<100xi32>>, index) -> !fir.ref<i32>
+! CHECK: %[[CONSTANT_4:.*]] = arith.constant 9 : index
+! CHECK: %[[CONSTANT_5:.*]] = arith.constant 10 : index
+! CHECK: %[[CONSTANT_6:.*]] = arith.constant true
+! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_5]] : (index) -> !fir.shape<1>
+! CHECK: %[[CONSTANT_7:.*]] = arith.constant 1 : index
+! CHECK: %[[CONSTANT_8:.*]] = arith.constant 11 : index
+! CHECK: %[[CONSTANT_9:.*]] = arith.constant 20 : index
+! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_1]] (%[[CONSTANT_8]]:%[[CONSTANT_9]]:%[[CONSTANT_0]]) shape %[[SHAPE_0]] : (!fir.ref<!fir.array<100xi32>>, index, index, index, !fir.shape<1>) -> !fir.ref<!fir.array<10xi32>>
+! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%[[CONSTANT_8]]:%[[CONSTANT_9]]:%[[CONSTANT_0]]) shape %[[SHAPE_0]] : (!fir.ref<!fir.array<100xi32>>, index, index, index, !fir.shape<1>) -> !fir.ref<!fir.array<10xi32>>
+! CHECK: %[[CONSTANT_10:.*]] = arith.constant 1 : index
+! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_10]] to %[[CONSTANT_5]] step %[[CONSTANT_10]] unordered {
+! CHECK: %[[DESIGNATE_2:.*]] = hlfir.designate %[[DESIGNATE_0]] (%[[VAL_2]]) : (!fir.ref<!fir.array<10xi32>>, index) -> !fir.ref<i32>
! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_2]] : !fir.ref<i32>
-! CHECK: %[[DESIGNATE_3:.*]] = hlfir.designate %[[DESIGNATE_1]] (%[[VAL_2]]) : (!fir.ref<!fir.array<100xi32>>, index) -> !fir.ref<i32>
+! CHECK: %[[DESIGNATE_3:.*]] = hlfir.designate %[[DESIGNATE_1]] (%[[VAL_2]]) : (!fir.ref<!fir.array<10xi32>>, index) -> !fir.ref<i32>
! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_3]] : !fir.ref<i32>
-! CHECK: %[[ADDI_1:.*]] = arith.addi %[[LOAD_1]], %[[LOAD_0]] : i32
-! CHECK: hlfir.assign %[[ADDI_1]] to %[[DESIGNATE_3]] : i32, !fir.ref<i32>
+! CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_1]], %[[LOAD_0]] : i32
+! CHECK: hlfir.assign %[[ADDI_0]] to %[[DESIGNATE_3]] : i32, !fir.ref<i32>
! CHECK: }
! CHECK: acc.yield %[[VAL_0]] : !fir.ref<!fir.array<100xi32>>
! CHECK: }
@@ -431,13 +561,14 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_add_ref_box_ptr_i32 : !fir.ref<!fir.box<!fir.ptr<i32>>> reduction_operator <add> init {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.ptr<i32>>>):
! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : i32
-! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.box<!fir.ptr<i32>>
-! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.box<!fir.ptr<i32>>>) -> (!fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.ref<!fir.box<!fir.ptr<i32>>>)
-! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem i32
+! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.ptr<i32>>>
+! CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_0]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
+! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem i32 {bindc_name = "acc.reduction.init", uniq_name = ""}
+! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[ALLOCMEM_0]] temporary_lhs : i32, !fir.heap<i32>
! CHECK: %[[EMBOX_0:.*]] = fir.embox %[[ALLOCMEM_0]] : (!fir.heap<i32>) -> !fir.box<!fir.ptr<i32>>
-! CHECK: fir.store %[[EMBOX_0]] to %[[DECLARE_0]]#0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
-! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : i32, !fir.ref<!fir.box<!fir.ptr<i32>>>
-! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.box<!fir.ptr<i32>>
+! CHECK: fir.store %[[EMBOX_0]] to %[[ALLOCA_0]] : !fir.ref<!fir.box<!fir.ptr<i32>>>
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<!fir.box<!fir.ptr<i32>>>
! CHECK-LABEL: } combiner {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.ptr<i32>>>, %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.ptr<i32>>>):
@@ -463,13 +594,14 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_add_ref_box_heap_i32 : !fir.ref<!fir.box<!fir.heap<i32>>> reduction_operator <add> init {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.heap<i32>>>):
! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : i32
-! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.box<!fir.heap<i32>>
-! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.box<!fir.heap<i32>>>) -> (!fir.ref<!fir.box<!fir.heap<i32>>>, !fir.ref<!fir.box<!fir.heap<i32>>>)
-! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem i32
+! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.heap<i32>>>
+! CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_0]] : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
+! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem i32 {bindc_name = "acc.reduction.init", uniq_name = ""}
+! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[ALLOCMEM_0]] temporary_lhs : i32, !fir.heap<i32>
! CHECK: %[[EMBOX_0:.*]] = fir.embox %[[ALLOCMEM_0]] : (!fir.heap<i32>) -> !fir.box<!fir.heap<i32>>
-! CHECK: fir.store %[[EMBOX_0]] to %[[DECLARE_0]]#0 : !fir.ref<!fir.box<!fir.heap<i32>>>
-! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : i32, !fir.ref<!fir.box<!fir.heap<i32>>>
-! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref<!fir.box<!fir.heap<i32>>>
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.box<!fir.heap<i32>>
+! CHECK: fir.store %[[EMBOX_0]] to %[[ALLOCA_0]] : !fir.ref<!fir.box<!fir.heap<i32>>>
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<!fir.box<!fir.heap<i32>>>
! CHECK-LABEL: } combiner {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.heap<i32>>>, %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.heap<i32>>>):
@@ -493,15 +625,14 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_mul_ref_z32 : !fir.ref<complex<f32>> reduction_operator <mul> init {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<complex<f32>>):
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca complex<f32> {bindc_name = "acc.reduction.init"}
! CHECK: %[[CONSTANT_0:.*]] = arith.constant 1.000000e+00 : f32
! CHECK: %[[CONSTANT_1:.*]] = arith.constant 0.000000e+00 : f32
! CHECK: %[[UNDEFINED_0:.*]] = fir.undefined complex<f32>
! CHECK: %[[INSERT_VALUE_0:.*]] = fir.insert_value %[[UNDEFINED_0]], %[[CONSTANT_0]], [0 : index] : (complex<f32>, f32) -> complex<f32>
! CHECK: %[[INSERT_VALUE_1:.*]] = fir.insert_value %[[INSERT_VALUE_0]], %[[CONSTANT_1]], [1 : index] : (complex<f32>, f32) -> complex<f32>
-! CHECK: %[[ALLOCA_0:.*]] = fir.alloca complex<f32>
-! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref<complex<f32>>) -> (!fir.ref<complex<f32>>, !fir.ref<complex<f32>>)
-! CHECK: fir.store %[[INSERT_VALUE_1]] to %[[DECLARE_0]]#0 : !fir.ref<complex<f32>>
-! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref<complex<f32>>
+! CHECK: hlfir.assign %[[INSERT_VALUE_1]] to %[[ALLOCA_0]] temporary_lhs : complex<f32>, !fir.ref<complex<f32>>
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<complex<f32>>
! CHECK-LABEL: } combiner {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<complex<f32>>, %[[VAL_1:.*]]: !fir.ref<complex<f32>>):
@@ -514,15 +645,14 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_add_ref_z32 : !fir.ref<complex<f32>> reduction_operator <add> init {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<complex<f32>>):
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca complex<f32> {bindc_name = "acc.reduction.init"}
! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0.000000e+00 : f32
! CHECK: %[[CONSTANT_1:.*]] = arith.constant 0.000000e+00 : f32
! CHECK: %[[UNDEFINED_0:.*]] = fir.undefined complex<f32>
! CHECK: %[[INSERT_VALUE_0:.*]] = fir.insert_value %[[UNDEFINED_0]], %[[CONSTANT_0]], [0 : index] : (complex<f32>, f32) -> complex<f32>
! CHECK: %[[INSERT_VALUE_1:.*]] = fir.insert_value %[[INSERT_VALUE_0]], %[[CONSTANT_1]], [1 : index] : (complex<f32>, f32) -> complex<f32>
-! CHECK: %[[ALLOCA_0:.*]] = fir.alloca complex<f32>
-! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref<complex<f32>>) -> (!fir.ref<complex<f32>>, !fir.ref<complex<f32>>)
-! CHECK: fir.store %[[INSERT_VALUE_1]] to %[[DECLARE_0]]#0 : !fir.ref<complex<f32>>
-! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref<complex<f32>>
+! CHECK: hlfir.assign %[[INSERT_VALUE_1]] to %[[ALLOCA_0]] temporary_lhs : complex<f32>, !fir.ref<complex<f32>>
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<complex<f32>>
! CHECK-LABEL: } combiner {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<complex<f32>>, %[[VAL_1:.*]]: !fir.ref<complex<f32>>):
@@ -535,12 +665,10 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_neqv_ref_l32 : !fir.ref<!fir.logical<4>> reduction_operator <neqv> init {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.logical<4>>):
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.logical<4> {bindc_name = "acc.reduction.init"}
! CHECK: %[[CONSTANT_0:.*]] = arith.constant false
-! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.logical<4>
-! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.logical<4>>) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>)
-! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[CONSTANT_0]] : (i1) -> !fir.logical<4>
-! CHECK: fir.store %[[CONVERT_0]] to %[[DECLARE_0]]#0 : !fir.ref<!fir.logical<4>>
-! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref<!fir.logical<4>>
+! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[ALLOCA_0]] temporary_lhs : i1, !fir.ref<!fir.logical<4>>
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<!fir.logical<4>>
! CHECK-LABEL: } combiner {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.logical<4>>, %[[VAL_1:.*]]: !fir.ref<!fir.logical<4>>):
@@ -556,12 +684,10 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_eqv_ref_l32 : !fir.ref<!fir.logical<4>> reduction_operator <eqv> init {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.logical<4>>):
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.logical<4> {bindc_name = "acc.reduction.init"}
! CHECK: %[[CONSTANT_0:.*]] = arith.constant true
-! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.logical<4>
-! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.logical<4>>) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>)
-! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[CONSTANT_0]] : (i1) -> !fir.logical<4>
-! CHECK: fir.store %[[CONVERT_0]] to %[[DECLARE_0]]#0 : !fir.ref<!fir.logical<4>>
-! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref<!fir.logical<4>>
+! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[ALLOCA_0]] temporary_lhs : i1, !fir.ref<!fir.logical<4>>
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<!fir.logical<4>>
! CHECK-LABEL: } combiner {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.logical<4>>, %[[VAL_1:.*]]: !fir.ref<!fir.logical<4>>):
@@ -577,12 +703,10 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_lor_ref_l32 : !fir.ref<!fir.logical<4>> reduction_operator <lor> init {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.logical<4>>):
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.logical<4> {bindc_name = "acc.reduction.init"}
! CHECK: %[[CONSTANT_0:.*]] = arith.constant false
-! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.logical<4>
-! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.logical<4>>) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>)
-! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[CONSTANT_0]] : (i1) -> !fir.logical<4>
-! CHECK: fir.store %[[CONVERT_0]] to %[[DECLARE_0]]#0 : !fir.ref<!fir.logical<4>>
-! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref<!fir.logical<4>>
+! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[ALLOCA_0]] temporary_lhs : i1, !fir.ref<!fir.logical<4>>
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<!fir.logical<4>>
! CHECK-LABEL: } combiner {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.logical<4>>, %[[VAL_1:.*]]: !fir.ref<!fir.logical<4>>):
@@ -598,12 +722,10 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_land_ref_l32 : !fir.ref<!fir.logical<4>> reduction_operator <land> init {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.logical<4>>):
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.logical<4> {bindc_name = "acc.reduction.init"}
! CHECK: %[[CONSTANT_0:.*]] = arith.constant true
-! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.logical<4>
-! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.logical<4>>) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>)
-! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[CONSTANT_0]] : (i1) -> !fir.logical<4>
-! CHECK: fir.store %[[CONVERT_0]] to %[[DECLARE_0]]#0 : !fir.ref<!fir.logical<4>>
-! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref<!fir.logical<4>>
+! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[ALLOCA_0]] temporary_lhs : i1, !fir.ref<!fir.logical<4>>
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<!fir.logical<4>>
! CHECK-LABEL: } combiner {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.logical<4>>, %[[VAL_1:.*]]: !fir.ref<!fir.logical<4>>):
@@ -619,11 +741,10 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_xor_ref_i32 : !fir.ref<i32> reduction_operator <xor> init {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>):
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 {bindc_name = "acc.reduction.init"}
! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : i32
-! CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32
-! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
-! CHECK: fir.store %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : !fir.ref<i32>
-! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref<i32>
+! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[ALLOCA_0]] temporary_lhs : i32, !fir.ref<i32>
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<i32>
! CHECK-LABEL: } combiner {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>, %[[VAL_1:.*]]: !fir.ref<i32>):
@@ -636,11 +757,10 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_ior_ref_i32 : !fir.ref<i32> reduction_operator <ior> init {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>):
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 {bindc_name = "acc.reduction.init"}
! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : i32
-! CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32
-! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
-! CHECK: fir.store %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : !fir.ref<i32>
-! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref<i32>
+! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[ALLOCA_0]] temporary_lhs : i32, !fir.ref<i32>
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<i32>
! CHECK-LABEL: } combiner {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>, %[[VAL_1:.*]]: !fir.ref<i32>):
@@ -653,11 +773,10 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_iand_ref_i32 : !fir.ref<i32> reduction_operator <iand> init {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>):
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 {bindc_name = "acc.reduction.init"}
! CHECK: %[[CONSTANT_0:.*]] = arith.constant -1 : i32
-! CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32
-! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
-! CHECK: fir.store %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : !fir.ref<i32>
-! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref<i32>
+! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[ALLOCA_0]] temporary_lhs : i32, !fir.ref<i32>
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<i32>
! CHECK-LABEL: } combiner {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>, %[[VAL_1:.*]]: !fir.ref<i32>):
@@ -670,19 +789,19 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_max_ref_100xf32 : !fir.ref<!fir.array<100xf32>> reduction_operator <max> init {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.array<100xf32>>):
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<100xf32> {bindc_name = "acc.reduction.init"}
! CHECK: %[[CONSTANT_0:.*]] = arith.constant -1.401300e-45 : f32
! CHECK: %[[CONSTANT_1:.*]] = arith.constant 100 : index
! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_1]] : (index) -> !fir.shape<1>
-! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<100xf32>
-! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]](%[[SHAPE_0]]) {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<100xf32>>, !fir.ref<!fir.array<100xf32>>)
-! CHECK: %[[CONSTANT_2:.*]] = arith.constant 0 : index
-! CHECK: %[[CONSTANT_3:.*]] = arith.constant 99 : index
-! CHECK: %[[CONSTANT_4:.*]] = arith.constant 1 : index
-! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_2]] to %[[CONSTANT_3]] step %[[CONSTANT_4]] {
-! CHECK: %[[COORDINATE_OF_0:.*]] = fir.coordinate_of %[[DECLARE_0]]#0, %[[VAL_1]] : (!fir.ref<!fir.array<100xf32>>, index) -> !fir.ref<f32>
-! CHECK: fir.store %[[CONSTANT_0]] to %[[COORDINATE_OF_0]] : !fir.ref<f32>
+! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[CONSTANT_1]] : (index) -> !fir.shape<1>
+! CHECK: %[[CONSTANT_2:.*]] = arith.constant 100 : index
+! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[CONSTANT_2]] : (index) -> !fir.shape<1>
+! CHECK: %[[CONSTANT_3:.*]] = arith.constant 1 : index
+! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_3]] to %[[CONSTANT_2]] step %[[CONSTANT_3]] unordered {
+! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[ALLOCA_0]] (%[[VAL_1]]) : (!fir.ref<!fir.array<100xf32>>, index) -> !fir.ref<f32>
+! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_0]] temporary_lhs : f32, !fir.ref<f32>
! CHECK: }
-! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref<!fir.array<100xf32>>
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<!fir.array<100xf32>>
! CHECK-LABEL: } combiner {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.array<100xf32>>, %[[VAL_1:.*]]: !fir.ref<!fir.array<100xf32>>):
@@ -705,11 +824,10 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_max_ref_f32 : !fir.ref<f32> reduction_operator <max> init {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<f32>):
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca f32 {bindc_name = "acc.reduction.init"}
! CHECK: %[[CONSTANT_0:.*]] = arith.constant -1.401300e-45 : f32
-! CHECK: %[[ALLOCA_0:.*]] = fir.alloca f32
-! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
-! CHECK: fir.store %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : !fir.ref<f32>
-! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref<f32>
+! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[ALLOCA_0]] temporary_lhs : f32, !fir.ref<f32>
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<f32>
! CHECK-LABEL: } combiner {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<f32>, %[[VAL_1:.*]]: !fir.ref<f32>):
@@ -723,25 +841,23 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_max_ref_100x10xi32 : !fir.ref<!fir.array<100x10xi32>> reduction_operator <max> init {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.array<100x10xi32>>):
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<100x10xi32> {bindc_name = "acc.reduction.init"}
! CHECK: %[[CONSTANT_0:.*]] = arith.constant -2147483648 : i32
! CHECK: %[[CONSTANT_1:.*]] = arith.constant 100 : index
! CHECK: %[[CONSTANT_2:.*]] = arith.constant 10 : index
! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_1]], %[[CONSTANT_2]] : (index, index) -> !fir.shape<2>
-! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<100x10xi32>
-! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]](%[[SHAPE_0]]) {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.array<100x10xi32>>, !fir.shape<2>) -> (!fir.ref<!fir.array<100x10xi32>>, !fir.ref<!fir.array<100x10xi32>>)
-! CHECK: %[[CONSTANT_3:.*]] = arith.constant 0 : index
-! CHECK: %[[CONSTANT_4:.*]] = arith.constant 9 : index
+! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[CONSTANT_1]], %[[CONSTANT_2]] : (index, index) -> !fir.shape<2>
+! CHECK: %[[CONSTANT_3:.*]] = arith.constant 100 : index
+! CHECK: %[[CONSTANT_4:.*]] = arith.constant 10 : index
+! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[CONSTANT_3]], %[[CONSTANT_4]] : (index, index) -> !fir.shape<2>
! CHECK: %[[CONSTANT_5:.*]] = arith.constant 1 : index
-! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_3]] to %[[CONSTANT_4]] step %[[CONSTANT_5]] {
-! CHECK: %[[CONSTANT_6:.*]] = arith.constant 0 : index
-! CHECK: %[[CONSTANT_7:.*]] = arith.constant 99 : index
-! CHECK: %[[CONSTANT_8:.*]] = arith.constant 1 : index
-! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_6]] to %[[CONSTANT_7]] step %[[CONSTANT_8]] {
-! CHECK: %[[COORDINATE_OF_0:.*]] = fir.coordinate_of %[[DECLARE_0]]#0, %[[VAL_2]], %[[VAL_1]] : (!fir.ref<!fir.array<100x10xi32>>, index, index) -> !fir.ref<i32>
-! CHECK: fir.store %[[CONSTANT_0]] to %[[COORDINATE_OF_0]] : !fir.ref<i32>
+! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_5]] to %[[CONSTANT_4]] step %[[CONSTANT_5]] unordered {
+! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_5]] to %[[CONSTANT_3]] step %[[CONSTANT_5]] unordered {
+! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[ALLOCA_0]] (%[[VAL_2]], %[[VAL_1]]) : (!fir.ref<!fir.array<100x10xi32>>, index, index) -> !fir.ref<i32>
+! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_0]] temporary_lhs : i32, !fir.ref<i32>
! CHECK: }
! CHECK: }
-! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref<!fir.array<100x10xi32>>
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<!fir.array<100x10xi32>>
! CHECK-LABEL: } combiner {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.array<100x10xi32>>, %[[VAL_1:.*]]: !fir.ref<!fir.array<100x10xi32>>):
@@ -768,11 +884,10 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_max_ref_i32 : !fir.ref<i32> reduction_operator <max> init {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>):
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 {bindc_name = "acc.reduction.init"}
! CHECK: %[[CONSTANT_0:.*]] = arith.constant -2147483648 : i32
-! CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32
-! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
-! CHECK: fir.store %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : !fir.ref<i32>
-! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref<i32>
+! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[ALLOCA_0]] temporary_lhs : i32, !fir.ref<i32>
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<i32>
! CHECK-LABEL: } combiner {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>, %[[VAL_1:.*]]: !fir.ref<i32>):
@@ -786,25 +901,23 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_min_ref_100x10xf32 : !fir.ref<!fir.array<100x10xf32>> reduction_operator <min> init {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.array<100x10xf32>>):
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<100x10xf32> {bindc_name = "acc.reduction.init"}
! CHECK: %[[CONSTANT_0:.*]] = arith.constant 3.40282347E+38 : f32
! CHECK: %[[CONSTANT_1:.*]] = arith.constant 100 : index
! CHECK: %[[CONSTANT_2:.*]] = arith.constant 10 : index
! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_1]], %[[CONSTANT_2]] : (index, index) -> !fir.shape<2>
-! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<100x10xf32>
-! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]](%[[SHAPE_0]]) {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.array<100x10xf32>>, !fir.shape<2>) -> (!fir.ref<!fir.array<100x10xf32>>, !fir.ref<!fir.array<100x10xf32>>)
-! CHECK: %[[CONSTANT_3:.*]] = arith.constant 0 : index
-! CHECK: %[[CONSTANT_4:.*]] = arith.constant 9 : index
+! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[CONSTANT_1]], %[[CONSTANT_2]] : (index, index) -> !fir.shape<2>
+! CHECK: %[[CONSTANT_3:.*]] = arith.constant 100 : index
+! CHECK: %[[CONSTANT_4:.*]] = arith.constant 10 : index
+! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[CONSTANT_3]], %[[CONSTANT_4]] : (index, index) -> !fir.shape<2>
! CHECK: %[[CONSTANT_5:.*]] = arith.constant 1 : index
-! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_3]] to %[[CONSTANT_4]] step %[[CONSTANT_5]] {
-! CHECK: %[[CONSTANT_6:.*]] = arith.constant 0 : index
-! CHECK: %[[CONSTANT_7:.*]] = arith.constant 99 : index
-! CHECK: %[[CONSTANT_8:.*]] = arith.constant 1 : index
-! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_6]] to %[[CONSTANT_7]] step %[[CONSTANT_8]] {
-! CHECK: %[[COORDINATE_OF_0:.*]] = fir.coordinate_of %[[DECLARE_0]]#0, %[[VAL_2]], %[[VAL_1]] : (!fir.ref<!fir.array<100x10xf32>>, index, index) -> !fir.ref<f32>
-! CHECK: fir.store %[[CONSTANT_0]] to %[[COORDINATE_OF_0]] : !fir.ref<f32>
+! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_5]] to %[[CONSTANT_4]] step %[[CONSTANT_5]] unordered {
+! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_5]] to %[[CONSTANT_3]] step %[[CONSTANT_5]] unordered {
+! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[ALLOCA_0]] (%[[VAL_2]], %[[VAL_1]]) : (!fir.ref<!fir.array<100x10xf32>>, index, index) -> !fir.ref<f32>
+! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_0]] temporary_lhs : f32, !fir.ref<f32>
! CHECK: }
! CHECK: }
-! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref<!fir.array<100x10xf32>>
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<!fir.array<100x10xf32>>
! CHECK-LABEL: } combiner {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.array<100x10xf32>>, %[[VAL_1:.*]]: !fir.ref<!fir.array<100x10xf32>>):
@@ -831,11 +944,10 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_min_ref_f32 : !fir.ref<f32> reduction_operator <min> init {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<f32>):
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca f32 {bindc_name = "acc.reduction.init"}
! CHECK: %[[CONSTANT_0:.*]] = arith.constant 3.40282347E+38 : f32
-! CHECK: %[[ALLOCA_0:.*]] = fir.alloca f32
-! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
-! CHECK: fir.store %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : !fir.ref<f32>
-! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref<f32>
+! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[ALLOCA_0]] temporary_lhs : f32, !fir.ref<f32>
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<f32>
! CHECK-LABEL: } combiner {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<f32>, %[[VAL_1:.*]]: !fir.ref<f32>):
@@ -849,19 +961,19 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_min_ref_100xi32 : !fir.ref<!fir.array<100xi32>> reduction_operator <min> init {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.array<100xi32>>):
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<100xi32> {bindc_name = "acc.reduction.init"}
! CHECK: %[[CONSTANT_0:.*]] = arith.constant 2147483647 : i32
! CHECK: %[[CONSTANT_1:.*]] = arith.constant 100 : index
! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_1]] : (index) -> !fir.shape<1>
-! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<100xi32>
-! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]](%[[SHAPE_0]]) {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.array<100xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<100xi32>>, !fir.ref<!fir.array<100xi32>>)
-! CHECK: %[[CONSTANT_2:.*]] = arith.constant 0 : index
-! CHECK: %[[CONSTANT_3:.*]] = arith.constant 99 : index
-! CHECK: %[[CONSTANT_4:.*]] = arith.constant 1 : index
-! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_2]] to %[[CONSTANT_3]] step %[[CONSTANT_4]] {
-! CHECK: %[[COORDINATE_OF_0:.*]] = fir.coordinate_of %[[DECLARE_0]]#0, %[[VAL_1]] : (!fir.ref<!fir.array<100xi32>>, index) -> !fir.ref<i32>
-! CHECK: fir.store %[[CONSTANT_0]] to %[[COORDINATE_OF_0]] : !fir.ref<i32>
+! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[CONSTANT_1]] : (index) -> !fir.shape<1>
+! CHECK: %[[CONSTANT_2:.*]] = arith.constant 100 : index
+! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[CONSTANT_2]] : (index) -> !fir.shape<1>
+! CHECK: %[[CONSTANT_3:.*]] = arith.constant 1 : index
+! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_3]] to %[[CONSTANT_2]] step %[[CONSTANT_3]] unordered {
+! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[ALLOCA_0]] (%[[VAL_1]]) : (!fir.ref<!fir.array<100xi32>>, index) -> !fir.ref<i32>
+! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_0]] temporary_lhs : i32, !fir.ref<i32>
! CHECK: }
-! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref<!fir.array<100xi32>>
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<!fir.array<100xi32>>
! CHECK-LABEL: } combiner {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.array<100xi32>>, %[[VAL_1:.*]]: !fir.ref<!fir.array<100xi32>>):
@@ -884,11 +996,10 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_min_ref_i32 : !fir.ref<i32> reduction_operator <min> init {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>):
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 {bindc_name = "acc.reduction.init"}
! CHECK: %[[CONSTANT_0:.*]] = arith.constant 2147483647 : i32
-! CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32
-! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
-! CHECK: fir.store %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : !fir.ref<i32>
-! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref<i32>
+! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[ALLOCA_0]] temporary_lhs : i32, !fir.ref<i32>
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<i32>
! CHECK-LABEL: } combiner {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>, %[[VAL_1:.*]]: !fir.ref<i32>):
@@ -902,19 +1013,19 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_mul_ref_100xf32 : !fir.ref<!fir.array<100xf32>> reduction_operator <mul> init {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.array<100xf32>>):
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<100xf32> {bindc_name = "acc.reduction.init"}
! CHECK: %[[CONSTANT_0:.*]] = arith.constant 1.000000e+00 : f32
! CHECK: %[[CONSTANT_1:.*]] = arith.constant 100 : index
! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_1]] : (index) -> !fir.shape<1>
-! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<100xf32>
-! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]](%[[SHAPE_0]]) {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<100xf32>>, !fir.ref<!fir.array<100xf32>>)
-! CHECK: %[[CONSTANT_2:.*]] = arith.constant 0 : index
-! CHECK: %[[CONSTANT_3:.*]] = arith.constant 99 : index
-! CHECK: %[[CONSTANT_4:.*]] = arith.constant 1 : index
-! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_2]] to %[[CONSTANT_3]] step %[[CONSTANT_4]] {
-! CHECK: %[[COORDINATE_OF_0:.*]] = fir.coordinate_of %[[DECLARE_0]]#0, %[[VAL_1]] : (!fir.ref<!fir.array<100xf32>>, index) -> !fir.ref<f32>
-! CHECK: fir.store %[[CONSTANT_0]] to %[[COORDINATE_OF_0]] : !fir.ref<f32>
+! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[CONSTANT_1]] : (index) -> !fir.shape<1>
+! CHECK: %[[CONSTANT_2:.*]] = arith.constant 100 : index
+! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[CONSTANT_2]] : (index) -> !fir.shape<1>
+! CHECK: %[[CONSTANT_3:.*]] = arith.constant 1 : index
+! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_3]] to %[[CONSTANT_2]] step %[[CONSTANT_3]] unordered {
+! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[ALLOCA_0]] (%[[VAL_1]]) : (!fir.ref<!fir.array<100xf32>>, index) -> !fir.ref<f32>
+! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_0]] temporary_lhs : f32, !fir.ref<f32>
! CHECK: }
-! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref<!fir.array<100xf32>>
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<!fir.array<100xf32>>
! CHECK-LABEL: } combiner {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.array<100xf32>>, %[[VAL_1:.*]]: !fir.ref<!fir.array<100xf32>>):
@@ -936,11 +1047,10 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_mul_ref_f32 : !fir.ref<f32> reduction_operator <mul> init {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<f32>):
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca f32 {bindc_name = "acc.reduction.init"}
! CHECK: %[[CONSTANT_0:.*]] = arith.constant 1.000000e+00 : f32
-! CHECK: %[[ALLOCA_0:.*]] = fir.alloca f32
-! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
-! CHECK: fir.store %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : !fir.ref<f32>
-! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref<f32>
+! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[ALLOCA_0]] temporary_lhs : f32, !fir.ref<f32>
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<f32>
! CHECK-LABEL: } combiner {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<f32>, %[[VAL_1:.*]]: !fir.ref<f32>):
@@ -953,19 +1063,19 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_mul_ref_100xi32 : !fir.ref<!fir.array<100xi32>> reduction_operator <mul> init {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.array<100xi32>>):
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<100xi32> {bindc_name = "acc.reduction.init"}
! CHECK: %[[CONSTANT_0:.*]] = arith.constant 1 : i32
! CHECK: %[[CONSTANT_1:.*]] = arith.constant 100 : index
! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_1]] : (index) -> !fir.shape<1>
-! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<100xi32>
-! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]](%[[SHAPE_0]]) {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.array<100xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<100xi32>>, !fir.ref<!fir.array<100xi32>>)
-! CHECK: %[[CONSTANT_2:.*]] = arith.constant 0 : index
-! CHECK: %[[CONSTANT_3:.*]] = arith.constant 99 : index
-! CHECK: %[[CONSTANT_4:.*]] = arith.constant 1 : index
-! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_2]] to %[[CONSTANT_3]] step %[[CONSTANT_4]] {
-! CHECK: %[[COORDINATE_OF_0:.*]] = fir.coordinate_of %[[DECLARE_0]]#0, %[[VAL_1]] : (!fir.ref<!fir.array<100xi32>>, index) -> !fir.ref<i32>
-! CHECK: fir.store %[[CONSTANT_0]] to %[[COORDINATE_OF_0]] : !fir.ref<i32>
+! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[CONSTANT_1]] : (index) -> !fir.shape<1>
+! CHECK: %[[CONSTANT_2:.*]] = arith.constant 100 : index
+! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[CONSTANT_2]] : (index) -> !fir.shape<1>
+! CHECK: %[[CONSTANT_3:.*]] = arith.constant 1 : index
+! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_3]] to %[[CONSTANT_2]] step %[[CONSTANT_3]] unordered {
+! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[ALLOCA_0]] (%[[VAL_1]]) : (!fir.ref<!fir.array<100xi32>>, index) -> !fir.ref<i32>
+! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_0]] temporary_lhs : i32, !fir.ref<i32>
! CHECK: }
-! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref<!fir.array<100xi32>>
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<!fir.array<100xi32>>
! CHECK-LABEL: } combiner {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.array<100xi32>>, %[[VAL_1:.*]]: !fir.ref<!fir.array<100xi32>>):
@@ -987,11 +1097,10 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_mul_ref_i32 : !fir.ref<i32> reduction_operator <mul> init {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>):
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 {bindc_name = "acc.reduction.init"}
! CHECK: %[[CONSTANT_0:.*]] = arith.constant 1 : i32
-! CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32
-! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
-! CHECK: fir.store %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : !fir.ref<i32>
-! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref<i32>
+! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[ALLOCA_0]] temporary_lhs : i32, !fir.ref<i32>
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<i32>
! CHECK-LABEL: } combiner {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>, %[[VAL_1:.*]]: !fir.ref<i32>):
@@ -1004,19 +1113,19 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_add_ref_100xf32 : !fir.ref<!fir.array<100xf32>> reduction_operator <add> init {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.array<100xf32>>):
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<100xf32> {bindc_name = "acc.reduction.init"}
! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0.000000e+00 : f32
! CHECK: %[[CONSTANT_1:.*]] = arith.constant 100 : index
! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_1]] : (index) -> !fir.shape<1>
-! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<100xf32>
-! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]](%[[SHAPE_0]]) {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<100xf32>>, !fir.ref<!fir.array<100xf32>>)
-! CHECK: %[[CONSTANT_2:.*]] = arith.constant 0 : index
-! CHECK: %[[CONSTANT_3:.*]] = arith.constant 99 : index
-! CHECK: %[[CONSTANT_4:.*]] = arith.constant 1 : index
-! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_2]] to %[[CONSTANT_3]] step %[[CONSTANT_4]] {
-! CHECK: %[[COORDINATE_OF_0:.*]] = fir.coordinate_of %[[DECLARE_0]]#0, %[[VAL_1]] : (!fir.ref<!fir.array<100xf32>>, index) -> !fir.ref<f32>
-! CHECK: fir.store %[[CONSTANT_0]] to %[[COORDINATE_OF_0]] : !fir.ref<f32>
+! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[CONSTANT_1]] : (index) -> !fir.shape<1>
+! CHECK: %[[CONSTANT_2:.*]] = arith.constant 100 : index
+! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[CONSTANT_2]] : (index) -> !fir.shape<1>
+! CHECK: %[[CONSTANT_3:.*]] = arith.constant 1 : index
+! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_3]] to %[[CONSTANT_2]] step %[[CONSTANT_3]] unordered {
+! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[ALLOCA_0]] (%[[VAL_1]]) : (!fir.ref<!fir.array<100xf32>>, index) -> !fir.ref<f32>
+! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_0]] temporary_lhs : f32, !fir.ref<f32>
! CHECK: }
-! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref<!fir.array<100xf32>>
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<!fir.array<100xf32>>
! CHECK-LABEL: } combiner {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.array<100xf32>>, %[[VAL_1:.*]]: !fir.ref<!fir.array<100xf32>>):
@@ -1038,11 +1147,10 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_add_ref_f32 : !fir.ref<f32> reduction_operator <add> init {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<f32>):
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca f32 {bindc_name = "acc.reduction.init"}
! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0.000000e+00 : f32
-! CHECK: %[[ALLOCA_0:.*]] = fir.alloca f32
-! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
-! CHECK: fir.store %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : !fir.ref<f32>
-! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref<f32>
+! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[ALLOCA_0]] temporary_lhs : f32, !fir.ref<f32>
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<f32>
! CHECK-LABEL: } combiner {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<f32>, %[[VAL_1:.*]]: !fir.ref<f32>):
@@ -1055,31 +1163,27 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_add_ref_100x10x2xi32 : !fir.ref<!fir.array<100x10x2xi32>> reduction_operator <add> init {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.array<100x10x2xi32>>):
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<100x10x2xi32> {bindc_name = "acc.reduction.init"}
! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : i32
! CHECK: %[[CONSTANT_1:.*]] = arith.constant 100 : index
! CHECK: %[[CONSTANT_2:.*]] = arith.constant 10 : index
! CHECK: %[[CONSTANT_3:.*]] = arith.constant 2 : index
! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_1]], %[[CONSTANT_2]], %[[CONSTANT_3]] : (index, index, index) -> !fir.shape<3>
-! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<100x10x2xi32>
-! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]](%[[SHAPE_0]]) {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.array<100x10x2xi32>>, !fir.shape<3>) -> (!fir.ref<!fir.array<100x10x2xi32>>, !fir.ref<!fir.array<100x10x2xi32>>)
-! CHECK: %[[CONSTANT_4:.*]] = arith.constant 0 : index
-! CHECK: %[[CONSTANT_5:.*]] = arith.constant 1 : index
-! CHECK: %[[CONSTANT_6:.*]] = arith.constant 1 : index
-! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_4]] to %[[CONSTANT_5]] step %[[CONSTANT_6]] {
-! CHECK: %[[CONSTANT_7:.*]] = arith.constant 0 : index
-! CHECK: %[[CONSTANT_8:.*]] = arith.constant 9 : index
-! CHECK: %[[CONSTANT_9:.*]] = arith.constant 1 : index
-! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_7]] to %[[CONSTANT_8]] step %[[CONSTANT_9]] {
-! CHECK: %[[CONSTANT_10:.*]] = arith.constant 0 : index
-! CHECK: %[[CONSTANT_11:.*]] = arith.constant 99 : index
-! CHECK: %[[CONSTANT_12:.*]] = arith.constant 1 : index
-! CHECK: fir.do_loop %[[VAL_3:.*]] = %[[CONSTANT_10]] to %[[CONSTANT_11]] step %[[CONSTANT_12]] {
-! CHECK: %[[COORDINATE_OF_0:.*]] = fir.coordinate_of %[[DECLARE_0]]#0, %[[VAL_3]], %[[VAL_2]], %[[VAL_1]] : (!fir.ref<!fir.array<100x10x2xi32>>, index, index, index) -> !fir.ref<i32>
-! CHECK: fir.store %[[CONSTANT_0]] to %[[COORDINATE_OF_0]] : !fir.ref<i32>
+! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[CONSTANT_1]], %[[CONSTANT_2]], %[[CONSTANT_3]] : (index, index, index) -> !fir.shape<3>
+! CHECK: %[[CONSTANT_4:.*]] = arith.constant 100 : index
+! CHECK: %[[CONSTANT_5:.*]] = arith.constant 10 : index
+! CHECK: %[[CONSTANT_6:.*]] = arith.constant 2 : index
+! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[CONSTANT_4]], %[[CONSTANT_5]], %[[CONSTANT_6]] : (index, index, index) -> !fir.shape<3>
+! CHECK: %[[CONSTANT_7:.*]] = arith.constant 1 : index
+! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_7]] to %[[CONSTANT_6]] step %[[CONSTANT_7]] unordered {
+! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_7]] to %[[CONSTANT_5]] step %[[CONSTANT_7]] unordered {
+! CHECK: fir.do_loop %[[VAL_3:.*]] = %[[CONSTANT_7]] to %[[CONSTANT_4]] step %[[CONSTANT_7]] unordered {
+! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[ALLOCA_0]] (%[[VAL_3]], %[[VAL_2]], %[[VAL_1]]) : (!fir.ref<!fir.array<100x10x2xi32>>, index, index, index) -> !fir.ref<i32>
+! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_0]] temporary_lhs : i32, !fir.ref<i32>
! CHECK: }
! CHECK: }
! CHECK: }
-! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref<!fir.array<100x10x2xi32>>
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<!fir.array<100x10x2xi32>>
! CHECK-LABEL: } combiner {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.array<100x10x2xi32>>, %[[VAL_1:.*]]: !fir.ref<!fir.array<100x10x2xi32>>):
@@ -1109,25 +1213,23 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_add_ref_100x10xi32 : !fir.ref<!fir.array<100x10xi32>> reduction_operator <add> init {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.array<100x10xi32>>):
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<100x10xi32> {bindc_name = "acc.reduction.init"}
! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : i32
! CHECK: %[[CONSTANT_1:.*]] = arith.constant 100 : index
! CHECK: %[[CONSTANT_2:.*]] = arith.constant 10 : index
! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_1]], %[[CONSTANT_2]] : (index, index) -> !fir.shape<2>
-! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<100x10xi32>
-! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]](%[[SHAPE_0]]) {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.array<100x10xi32>>, !fir.shape<2>) -> (!fir.ref<!fir.array<100x10xi32>>, !fir.ref<!fir.array<100x10xi32>>)
-! CHECK: %[[CONSTANT_3:.*]] = arith.constant 0 : index
-! CHECK: %[[CONSTANT_4:.*]] = arith.constant 9 : index
+! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[CONSTANT_1]], %[[CONSTANT_2]] : (index, index) -> !fir.shape<2>
+! CHECK: %[[CONSTANT_3:.*]] = arith.constant 100 : index
+! CHECK: %[[CONSTANT_4:.*]] = arith.constant 10 : index
+! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[CONSTANT_3]], %[[CONSTANT_4]] : (index, index) -> !fir.shape<2>
! CHECK: %[[CONSTANT_5:.*]] = arith.constant 1 : index
-! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_3]] to %[[CONSTANT_4]] step %[[CONSTANT_5]] {
-! CHECK: %[[CONSTANT_6:.*]] = arith.constant 0 : index
-! CHECK: %[[CONSTANT_7:.*]] = arith.constant 99 : index
-! CHECK: %[[CONSTANT_8:.*]] = arith.constant 1 : index
-! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_6]] to %[[CONSTANT_7]] step %[[CONSTANT_8]] {
-! CHECK: %[[COORDINATE_OF_0:.*]] = fir.coordinate_of %[[DECLARE_0]]#0, %[[VAL_2]], %[[VAL_1]] : (!fir.ref<!fir.array<100x10xi32>>, index, index) -> !fir.ref<i32>
-! CHECK: fir.store %[[CONSTANT_0]] to %[[COORDINATE_OF_0]] : !fir.ref<i32>
+! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_5]] to %[[CONSTANT_4]] step %[[CONSTANT_5]] unordered {
+! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_5]] to %[[CONSTANT_3]] step %[[CONSTANT_5]] unordered {
+! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[ALLOCA_0]] (%[[VAL_2]], %[[VAL_1]]) : (!fir.ref<!fir.array<100x10xi32>>, index, index) -> !fir.ref<i32>
+! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_0]] temporary_lhs : i32, !fir.ref<i32>
! CHECK: }
! CHECK: }
-! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref<!fir.array<100x10xi32>>
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<!fir.array<100x10xi32>>
! CHECK-LABEL: } combiner {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.array<100x10xi32>>, %[[VAL_1:.*]]: !fir.ref<!fir.array<100x10xi32>>):
@@ -1153,19 +1255,19 @@
! CHECK-LABEL: acc.reduction.recipe @reduction_add_ref_100xi32 : !fir.ref<!fir.array<100xi32>> reduction_operator <add> init {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.array<100xi32>>):
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<100xi32> {bindc_name = "acc.reduction.init"}
! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : i32
! CHECK: %[[CONSTANT_1:.*]] = arith.constant 100 : index
! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_1]] : (index) -> !fir.shape<1>
-! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<100xi32>
-! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]](%[[SHAPE_0]]) {uniq_name = "acc.reduction.init"} : (!fir.ref<!fir.array<100xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<100xi32>>, !fir.ref<!fir.array<100xi32>>)
-! CHECK: %[[CONSTANT_2:.*]] = arith.constant 0 : index
-! CHECK: %[[CONSTANT_3:.*]] = arith.constant 99 : index
-! CHECK: %[[CONSTANT_4:.*]] = arith.constant 1 : index
-! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_2]] to %[[CONSTANT_3]] step %[[CONSTANT_4]] {
-! CHECK: %[[COORDINATE_OF_0:.*]] = fir.coordinate_of %[[DECLARE_0]]#0, %[[VAL_1]] : (!fir.ref<!fir.array<100xi32>>, index) -> !fir.ref<i32>
-! CHECK: fir.store %[[CONSTANT_0]] to %[[COORDINATE_OF_0]] : !fir.ref<i32>
+! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[CONSTANT_1]] : (index) -> !fir.shape<1>
+! CHECK: %[[CONSTANT_2:.*]] = arith.constant 100 : index
+! CHECK: %[[SHAPE_2:.*]] = fir.shape %[[CONSTANT_2]] : (index) -> !fir.shape<1>
+! CHECK: %[[CONSTANT_3:.*]] = arith.constant 1 : index
+! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_3]] to %[[CONSTANT_2]] step %[[CONSTANT_3]] unordered {
+! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[ALLOCA_0]] (%[[VAL_1]]) : (!fir.ref<!fir.array<100xi32>>, index) -> !fir.ref<i32>
+! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_0]] temporary_lhs : i32, !fir.ref<i32>
! CHECK: }
-! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref<!fir.array<100xi32>>
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<!fir.array<100xi32>>
! CHECK-LABEL: } combiner {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.array<100xi32>>, %[[VAL_1:.*]]: !fir.ref<!fir.array<100xi32>>):
@@ -1187,18 +1289,16 @@
! CHECK-LABEL: acc.private.recipe @privatization_ref_i32 : !fir.ref<i32> init {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>):
-! CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32
-! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.private.init"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
-! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref<i32>
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 {bindc_name = "acc.private.init"}
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<i32>
! CHECK: }
! CHECK-LABEL: acc.reduction.recipe @reduction_add_ref_i32 : !fir.ref<i32> reduction_operator <add> init {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>):
+! CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 {bindc_name = "acc.reduction.init"}
! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : i32
-! CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32
-! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
-! CHECK: fir.store %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : !fir.ref<i32>
-! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref<i32>
+! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[ALLOCA_0]] temporary_lhs : i32, !fir.ref<i32>
+! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref<i32>
! CHECK-LABEL: } combiner {
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<i32>, %[[VAL_1:.*]]: !fir.ref<i32>):
diff --git a/flang/test/Lower/OpenACC/acc-serial-loop.f90 b/flang/test/Lower/OpenACC/acc-serial-loop.f90
index b5bff6397edc7..de070262a52fb 100644
--- a/flang/test/Lower/OpenACC/acc-serial-loop.f90
+++ b/flang/test/Lower/OpenACC/acc-serial-loop.f90
@@ -4,18 +4,14 @@
! CHECK-LABEL: acc.private.recipe @privatization_ref_10xf32 : !fir.ref<!fir.array<10xf32>> init {
! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<10xf32>>):
-! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1>
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<10xf32>
-! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.private.init"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>)
-! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<10xf32>>
+! CHECK: acc.yield %[[ALLOCA]] : !fir.ref<!fir.array<10xf32>>
! CHECK: }
! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_10xf32 : !fir.ref<!fir.array<10xf32>> init {
! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<10xf32>>):
-! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1>
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<10xf32>
-! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.private.init"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>)
-! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<10xf32>>
+! CHECK: acc.yield %[[ALLOCA]] : !fir.ref<!fir.array<10xf32>>
! CHECK: } copy {
! CHECK: ^bb0(%arg0: !fir.ref<!fir.array<10xf32>>, %arg1: !fir.ref<!fir.array<10xf32>>):
! CHECK: acc.terminator
diff --git a/flang/test/Lower/OpenACC/acc-serial.f90 b/flang/test/Lower/OpenACC/acc-serial.f90
index a6d3528ee957c..e46e9a9281664 100644
--- a/flang/test/Lower/OpenACC/acc-serial.f90
+++ b/flang/test/Lower/OpenACC/acc-serial.f90
@@ -4,10 +4,8 @@
! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_10x10xf32 : !fir.ref<!fir.array<10x10xf32>> init {
! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<10x10xf32>>):
-! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2>
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<10x10xf32>
-! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.private.init"} : (!fir.ref<!fir.array<10x10xf32>>, !fir.shape<2>) -> (!fir.ref<!fir.array<10x10xf32>>, !fir.ref<!fir.array<10x10xf32>>)
-! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<10x10xf32>>
+! CHECK: acc.yield %[[ALLOCA]] : !fir.ref<!fir.array<10x10xf32>>
! CHECK: } copy {
! CHECK: ^bb0(%arg0: !fir.ref<!fir.array<10x10xf32>>, %arg1: !fir.ref<!fir.array<10x10xf32>>):
! CHECK: acc.terminator
@@ -15,9 +13,8 @@
! CHECK-LABEL: acc.private.recipe @privatization_ref_10x10xf32 : !fir.ref<!fir.array<10x10xf32>> init {
! CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.array<10x10xf32>>):
-! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2>
-! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.private.init"} : (!fir.ref<!fir.array<10x10xf32>>, !fir.shape<2>) -> (!fir.ref<!fir.array<10x10xf32>>, !fir.ref<!fir.array<10x10xf32>>)
-! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref<!fir.array<10x10xf32>>
+! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<10x10xf32>
+! CHECK: acc.yield %[[ALLOCA]] : !fir.ref<!fir.array<10x10xf32>>
! CHECK: }
! CHECK-LABEL: func.func @_QPacc_serial()
diff --git a/flang/test/Transforms/OpenACC/acc-implicit-firstprivate.fir b/flang/test/Transforms/OpenACC/acc-implicit-firstprivate.fir
index 3a3288a9cc2ee..d1033d1b580ff 100644
--- a/flang/test/Transforms/OpenACC/acc-implicit-firstprivate.fir
+++ b/flang/test/Transforms/OpenACC/acc-implicit-firstprivate.fir
@@ -8,8 +8,7 @@
// CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_i32 : !fir.ref<i32> init {
// CHECK: ^bb0(%{{.*}}: !fir.ref<i32>):
// CHECK: %[[ALLOC:.*]] = fir.alloca i32
-// CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOC]]
-// CHECK: acc.yield %[[DECL]]#0 : !fir.ref<i32>
+// CHECK: acc.yield %[[ALLOC]] : !fir.ref<i32>
// CHECK: } copy {
// CHECK: ^bb0(%[[SRC:.*]]: !fir.ref<i32>, %[[DST:.*]]: !fir.ref<i32>):
// CHECK: %[[LOADED:.*]] = fir.load %[[SRC]] : !fir.ref<i32>
@@ -35,8 +34,7 @@ func.func @test_i32_scalar_in_parallel() {
// CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_i64 : !fir.ref<i64> init {
// CHECK: ^bb0(%{{.*}}: !fir.ref<i64>):
// CHECK: %[[ALLOC:.*]] = fir.alloca i64
-// CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOC]]
-// CHECK: acc.yield %[[DECL]]#0 : !fir.ref<i64>
+// CHECK: acc.yield %[[ALLOC]] : !fir.ref<i64>
// CHECK: } copy {
// CHECK: ^bb0(%[[SRC:.*]]: !fir.ref<i64>, %[[DST:.*]]: !fir.ref<i64>):
// CHECK: %[[LOADED:.*]] = fir.load %[[SRC]] : !fir.ref<i64>
@@ -62,8 +60,7 @@ func.func @test_i64_scalar_in_parallel() {
// CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_f32 : !fir.ref<f32> init {
// CHECK: ^bb0(%{{.*}}: !fir.ref<f32>):
// CHECK: %[[ALLOC:.*]] = fir.alloca f32
-// CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOC]]
-// CHECK: acc.yield %[[DECL]]#0 : !fir.ref<f32>
+// CHECK: acc.yield %[[ALLOC]] : !fir.ref<f32>
// CHECK: } copy {
// CHECK: ^bb0(%[[SRC:.*]]: !fir.ref<f32>, %[[DST:.*]]: !fir.ref<f32>):
// CHECK: %[[LOADED:.*]] = fir.load %[[SRC]] : !fir.ref<f32>
@@ -89,8 +86,7 @@ func.func @test_f32_scalar_in_parallel() {
// CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_f64 : !fir.ref<f64> init {
// CHECK: ^bb0(%{{.*}}: !fir.ref<f64>):
// CHECK: %[[ALLOC:.*]] = fir.alloca f64
-// CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOC]]
-// CHECK: acc.yield %[[DECL]]#0 : !fir.ref<f64>
+// CHECK: acc.yield %[[ALLOC]] : !fir.ref<f64>
// CHECK: } copy {
// CHECK: ^bb0(%[[SRC:.*]]: !fir.ref<f64>, %[[DST:.*]]: !fir.ref<f64>):
// CHECK: %[[LOADED:.*]] = fir.load %[[SRC]] : !fir.ref<f64>
@@ -116,8 +112,7 @@ func.func @test_f64_scalar_in_parallel() {
// CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_l32 : !fir.ref<!fir.logical<4>> init {
// CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.logical<4>>):
// CHECK: %[[ALLOC:.*]] = fir.alloca !fir.logical<4>
-// CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOC]]
-// CHECK: acc.yield %[[DECL]]#0 : !fir.ref<!fir.logical<4>>
+// CHECK: acc.yield %[[ALLOC]] : !fir.ref<!fir.logical<4>>
// CHECK: } copy {
// CHECK: ^bb0(%[[SRC:.*]]: !fir.ref<!fir.logical<4>>, %[[DST:.*]]: !fir.ref<!fir.logical<4>>):
// CHECK: %[[LOADED:.*]] = fir.load %[[SRC]] : !fir.ref<!fir.logical<4>>
@@ -143,8 +138,7 @@ func.func @test_logical_scalar_in_parallel() {
// CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_z32 : !fir.ref<complex<f32>> init {
// CHECK: ^bb0(%{{.*}}: !fir.ref<complex<f32>>):
// CHECK: %[[ALLOC:.*]] = fir.alloca complex<f32>
-// CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOC]]
-// CHECK: acc.yield %[[DECL]]#0 : !fir.ref<complex<f32>>
+// CHECK: acc.yield %[[ALLOC]] : !fir.ref<complex<f32>>
// CHECK: } copy {
// CHECK: ^bb0(%[[SRC:.*]]: !fir.ref<complex<f32>>, %[[DST:.*]]: !fir.ref<complex<f32>>):
// CHECK: %[[LOADED:.*]] = fir.load %[[SRC]] : !fir.ref<complex<f32>>
@@ -170,8 +164,7 @@ func.func @test_complex_scalar_in_parallel() {
// CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_z64 : !fir.ref<complex<f64>> init {
// CHECK: ^bb0(%{{.*}}: !fir.ref<complex<f64>>):
// CHECK: %[[ALLOC:.*]] = fir.alloca complex<f64>
-// CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOC]]
-// CHECK: acc.yield %[[DECL]]#0 : !fir.ref<complex<f64>>
+// CHECK: acc.yield %[[ALLOC]] : !fir.ref<complex<f64>>
// CHECK: } copy {
// CHECK: ^bb0(%[[SRC:.*]]: !fir.ref<complex<f64>>, %[[DST:.*]]: !fir.ref<complex<f64>>):
// CHECK: %[[LOADED:.*]] = fir.load %[[SRC]] : !fir.ref<complex<f64>>
@@ -233,8 +226,7 @@ func.func @test_f64_scalar_in_serial() {
// CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_i8 : !fir.ref<i8> init {
// CHECK: ^bb0(%{{.*}}: !fir.ref<i8>):
// CHECK: %[[ALLOC:.*]] = fir.alloca i8
-// CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOC]]
-// CHECK: acc.yield %[[DECL]]#0 : !fir.ref<i8>
+// CHECK: acc.yield %[[ALLOC]] : !fir.ref<i8>
// CHECK: } copy {
// CHECK: ^bb0(%[[SRC:.*]]: !fir.ref<i8>, %[[DST:.*]]: !fir.ref<i8>):
// CHECK: %[[LOADED:.*]] = fir.load %[[SRC]] : !fir.ref<i8>
@@ -260,8 +252,7 @@ func.func @test_i8_scalar_in_parallel() {
// CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_i16 : !fir.ref<i16> init {
// CHECK: ^bb0(%{{.*}}: !fir.ref<i16>):
// CHECK: %[[ALLOC:.*]] = fir.alloca i16
-// CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOC]]
-// CHECK: acc.yield %[[DECL]]#0 : !fir.ref<i16>
+// CHECK: acc.yield %[[ALLOC]] : !fir.ref<i16>
// CHECK: } copy {
// CHECK: ^bb0(%[[SRC:.*]]: !fir.ref<i16>, %[[DST:.*]]: !fir.ref<i16>):
// CHECK: %[[LOADED:.*]] = fir.load %[[SRC]] : !fir.ref<i16>
diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCTypeInterfaces.td b/mlir/include/mlir/Dialect/OpenACC/OpenACCTypeInterfaces.td
index 3f11bf6fbfce3..1d55762e2f7d9 100644
--- a/mlir/include/mlir/Dialect/OpenACC/OpenACCTypeInterfaces.td
+++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCTypeInterfaces.td
@@ -342,7 +342,7 @@ def OpenACC_MappableTypeInterface : TypeInterface<"MappableType"> {
return ::mlir::acc::VariableTypeCategory::uncategorized;
}]
>,
- InterfaceMethod<
+ InterfaceMethod<
/*description=*/[{
Generates the operations that would be normally placed in a recipe's
init region. It inserts at the builder's current location.
@@ -381,6 +381,38 @@ def OpenACC_MappableTypeInterface : TypeInterface<"MappableType"> {
return {};
}]
>,
+ InterfaceMethod<
+ /*description=*/[{
+ }],
+ /*retTy=*/"bool",
+ /*methodName=*/"generateCopy",
+ /*args=*/(ins "::mlir::OpBuilder &":$builder,
+ "::mlir::Location":$loc,
+ "::mlir::TypedValue<::mlir::acc::MappableType>":$from,
+ "::mlir::TypedValue<::mlir::acc::MappableType>":$to,
+ "::mlir::ValueRange":$bounds),
+ /*methodBody=*/"",
+ /*defaultImplementation=*/[{
+ return false;
+ }]
+ >,
+ InterfaceMethod<
+ /*description=*/[{
+ }],
+ /*retTy=*/"bool",
+ /*methodName=*/"generateCombiner",
+ /*args=*/(ins "::mlir::OpBuilder &":$builder,
+ "::mlir::Location":$loc,
+ "::mlir::TypedValue<::mlir::acc::MappableType>":$dest,
+ "::mlir::TypedValue<::mlir::acc::MappableType>":$source,
+ "::mlir::ValueRange":$bounds,
+ "::mlir::acc::ReductionOperator":$op,
+ "::mlir::Attribute":$fastmathFlags),
+ /*methodBody=*/"",
+ /*defaultImplementation=*/[{
+ return false;
+ }]
+ >,
InterfaceMethod<
/*description=*/[{
Generates destruction operations for a privatized value previously
@@ -393,6 +425,9 @@ def OpenACC_MappableTypeInterface : TypeInterface<"MappableType"> {
cleanup required for the given type. If no destruction is required,
this function should be a no-op and return `true`.
+ The `bounds` must be passed when only a section of the variable was
+ privatized.
+
Returns true if destruction was successfully generated or deemed not
necessary, false otherwise.
}],
@@ -400,7 +435,8 @@ def OpenACC_MappableTypeInterface : TypeInterface<"MappableType"> {
/*methodName=*/"generatePrivateDestroy",
/*args=*/(ins "::mlir::OpBuilder &":$builder,
"::mlir::Location":$loc,
- "::mlir::Value":$privatized),
+ "::mlir::Value":$privatized,
+ "::mlir::ValueRange":$extents),
/*methodBody=*/"",
/*defaultImplementation=*/[{
return true;
diff --git a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
index bb643d6d1466b..d0c1e5e14bb6b 100644
--- a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
+++ b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
@@ -1438,7 +1438,7 @@ static LogicalResult createDestroyRegion(OpBuilder &builder, Location loc,
cast<TypedValue<PointerLikeType>>(destroyBlock->getArgument(1));
if (isa<MappableType>(varType)) {
auto mappableTy = cast<MappableType>(varType);
- if (!mappableTy.generatePrivateDestroy(builder, loc, varToFree))
+ if (!mappableTy.generatePrivateDestroy(builder, loc, varToFree, bounds))
return failure();
} else {
assert(isa<PointerLikeType>(varType) && "Expected PointerLikeType");
More information about the Mlir-commits
mailing list