[Mlir-commits] [flang] [mlir] [flang][openacc] support array section privatization in lowering (PR #175184)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Wed Jan 14 07:29:58 PST 2026
https://github.com/jeanPerier updated https://github.com/llvm/llvm-project/pull/175184
>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 1/2] [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");
>From b4ff61a941eae0c51ce9e2fc59cb4332d118cb7a Mon Sep 17 00:00:00 2001
From: Jean Perier <jperier at nvidia.com>
Date: Wed, 14 Jan 2026 07:28:54 -0800
Subject: [PATCH 2/2] typo in comment and turn XFAIL into TODO test
---
.../Support/FIROpenACCTypeInterfaces.cpp | 2 +-
...firstprivate-derived-pointer-component.f90 | 71 ++-----------------
2 files changed, 5 insertions(+), 68 deletions(-)
diff --git a/flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp b/flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp
index fb0ecac81f951..2997428b7b5d2 100644
--- a/flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp
+++ b/flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp
@@ -771,7 +771,7 @@ mlir::Value OpenACCMappableModel<Ty>::generatePrivateInit(
alloc = builder.createTemporary(loc, baseType, varName, tempExtents,
typeParams);
}
- // Step3: Assign the inital value to the privatized part if any.
+ // Step3: Assign the initial value to the privatized part if any.
if (initVal) {
mlir::Value tempEntity = alloc;
if (fir::hasDynamicSize(baseType))
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 e5083e58da493..5bd30882b02d7 100644
--- a/flang/test/Lower/OpenACC/acc-firstprivate-derived-pointer-component.f90
+++ b/flang/test/Lower/OpenACC/acc-firstprivate-derived-pointer-component.f90
@@ -1,14 +1,11 @@
! 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.
+! TODO: ensure pointer components are initialized to NULL for private.
-! XFAIL: *
+! RUN: not bbc -fopenacc -emit-hlfir %s -o - | FileCheck %s
-! RUN: bbc -fopenacc -emit-hlfir %s -o - | FileCheck %s
-! RUN: bbc -fopenacc -emit-fir %s -o - | FileCheck %s --check-prefix=FIR-CHECK
+! CHECK: not yet implemented: OpenACC: privatizing derived type with pointer components
module m_firstprivate_derived_ptr_comp
type point
@@ -23,64 +20,4 @@ subroutine test(a)
a%x(10) = 1
enddo
end
- end module
-
-! 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: 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>>>}>>):
-! CHECK: hlfir.assign %[[VAL_0]] to %[[VAL_1]] temporary_lhs : !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.terminator
-! CHECK: }
-!
-! CHECK-LABEL: func.func @_QMm_firstprivate_derived_ptr_compPtest(
-! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.type<_QMm_firstprivate_derived_ptr_compTpoint{x:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>> {fir.bindc_name = "a"}) {
-! CHECK: %[[VAL_0:.*]] = fir.dummy_scope : !fir.dscope
-! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[ARG0]] dummy_scope %[[VAL_0]] arg {{[0-9]+}} {uniq_name = "_QMm_firstprivate_derived_ptr_compFtestEa"} : (!fir.ref<!fir.type<_QMm_firstprivate_derived_ptr_compTpoint{x:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>, !fir.dscope) -> (!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: %[[VAL_2:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QMm_firstprivate_derived_ptr_compFtestEi"}
-! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_2]] {uniq_name = "_QMm_firstprivate_derived_ptr_compFtestEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
-! CHECK: %[[VAL_4:.*]] = fir.alloca i32 {bindc_name = "n", uniq_name = "_QMm_firstprivate_derived_ptr_compFtestEn"}
-! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_4]] {uniq_name = "_QMm_firstprivate_derived_ptr_compFtestEn"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
-! CHECK: %[[VAL_6:.*]] = acc.firstprivate varPtr(%[[VAL_1]]#0 : !fir.ref<!fir.type<_QMm_firstprivate_derived_ptr_compTpoint{x:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>) 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>>>}>> {name = "a"}
-! CHECK: acc.parallel combined(loop) firstprivate(%[[VAL_6]] : !fir.ref<!fir.type<_QMm_firstprivate_derived_ptr_compTpoint{x:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>) {
-! CHECK: %[[VAL_7:.*]] = fir.dummy_scope : !fir.dscope
-! CHECK: %[[VAL_8:.*]]:2 = hlfir.declare %[[VAL_6]] dummy_scope %[[VAL_7]] {{.*}} {uniq_name = "_QMm_firstprivate_derived_ptr_compFtestEa"} : (!fir.ref<!fir.type<_QMm_firstprivate_derived_ptr_compTpoint{x:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>, !fir.dscope) -> (!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: %[[VAL_9:.*]] = arith.constant 1 : i32
-! CHECK: %[[VAL_10:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<i32>
-! CHECK: %[[VAL_11:.*]] = arith.constant 1 : i32
-! CHECK: %[[VAL_12:.*]] = acc.private varPtr(%[[VAL_3]]#0 : !fir.ref<i32>) recipe(@privatization_ref_i32) -> !fir.ref<i32> {implicit = true, name = "i"}
-! CHECK: acc.loop combined(parallel) private(%[[VAL_12]] : !fir.ref<i32>) control(%[[VAL_14:.*]] : i32) = (%[[VAL_9]] : i32) to (%[[VAL_10]] : i32) step (%[[VAL_11]] : i32) {
-! CHECK: %[[VAL_13:.*]]:2 = hlfir.declare %[[VAL_12]] {uniq_name = "_QMm_firstprivate_derived_ptr_compFtestEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
-! CHECK: fir.store %[[VAL_14]] to %[[VAL_13]]#0 : !fir.ref<i32>
-! CHECK: %[[VAL_15:.*]] = arith.constant 1.000000e+00 : f32
-! CHECK: %[[VAL_16:.*]] = hlfir.designate %[[VAL_8]]#0{"x"} {fortran_attrs = #fir.var_attrs<pointer>} : (!fir.ref<!fir.type<_QMm_firstprivate_derived_ptr_compTpoint{x:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
-! CHECK: %[[VAL_17:.*]] = fir.load %[[VAL_16]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
-! CHECK: %[[VAL_18:.*]] = arith.constant 10 : index
-! CHECK: %[[VAL_19:.*]] = hlfir.designate %[[VAL_17]] (%[[VAL_18]]) : (!fir.box<!fir.ptr<!fir.array<?xf32>>>, index) -> !fir.ref<f32>
-! CHECK: hlfir.assign %[[VAL_15]] to %[[VAL_19]] : f32, !fir.ref<f32>
-! CHECK: acc.yield
-! CHECK: } attributes {inclusiveUpperbound = array<i1: true>, independent = [#acc.device_type<none>]}
-! CHECK: acc.yield
-! CHECK: }
-! CHECK: return
-! CHECK: }
-
-
-! 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: 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>>>}>>):
-! FIR-CHECK: %[[VAL_2:.*]] = fir.field_index x, !fir.type<_QMm_firstprivate_derived_ptr_compTpoint{x:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>
-! FIR-CHECK: %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_0]], x : (!fir.ref<!fir.type<_QMm_firstprivate_derived_ptr_compTpoint{x:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
-! FIR-CHECK: %[[VAL_4:.*]] = fir.field_index x, !fir.type<_QMm_firstprivate_derived_ptr_compTpoint{x:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>
-! FIR-CHECK: %[[VAL_5:.*]] = fir.coordinate_of %[[VAL_1]], x : (!fir.ref<!fir.type<_QMm_firstprivate_derived_ptr_compTpoint{x:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
-! FIR-CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_3]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
-! FIR-CHECK: fir.store %[[VAL_6]] to %[[VAL_5]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
-! FIR-CHECK: acc.terminator
-! FIR-CHECK: }
+end module
More information about the Mlir-commits
mailing list