From b0b1ab8a40f2b91041ad102aa28fec2e84f9b76e Mon Sep 17 00:00:00 2001 From: jeanPerier Date: Thu, 15 Jan 2026 09:32:13 +0100 Subject: [PATCH] [flang][openacc] support array section privatization in lowering (#175184) Add support array section in private, firstprivate, and reduction. Key changes: - Change the related data operation result type to return the same type as the array base (same type as the acc variable input in the operation), while it was the type of the section before. This allows remapping the base the to result value (to use the data operation result as the base when generating addressing inside the compute region). - The generatePrivateInit implementation of FIROpenACCTypeInterfaces is modified to allocate storage only for the section, and to return the mock base address (that is the address of the allocation minus the offset/lower bound of the privatized section). - The code generating the copy and combiner region is moved from OpenACC.cpp to FIROpenACCTypeInterfaces.cpp via the addition of new generateCopy and generateCombiner interface in the MappableTypeInterface. This allows sharing all the addressing helper with generatePrivateInit, and will allow late generation of all recipes with Fortran. - Update generatePrivateDestroy to deallocate the beginning of the section if any. In the process, the generatePrivateInit implementation is modified so that it is more uniform to make it easier to deal with the section. This also allowed removing runtime calls when initializing the private for array reduction. --- flang/include/flang/Lower/OpenACC.h | 16 +- .../flang/Optimizer/Builder/FIRBuilder.h | 2 +- .../Support/FIROpenACCTypeInterfaces.h | 17 +- flang/lib/Lower/OpenACC.cpp | 511 ++++-------- flang/lib/Optimizer/Builder/FIRBuilder.cpp | 33 +- flang/lib/Optimizer/Builder/HLFIRTools.cpp | 13 +- .../Support/FIROpenACCTypeInterfaces.cpp | 633 +++++++++++---- .../OpenACC/Support/FIROpenACCUtils.cpp | 12 +- .../OpenACC/recipe-populate-firstprivate.mlir | 26 +- .../Fir/OpenACC/recipe-populate-private.mlir | 47 +- ...firstprivate-derived-pointer-component.f90 | 71 +- .../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 | 569 ++++++++----- 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, 1560 insertions(+), 1245 deletions(-) diff --git a/flang/include/flang/Lower/OpenACC.h b/flang/include/flang/Lower/OpenACC.h index 69f1f5be753e..c2a950f36c5a 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 &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 &); + llvm::SmallVector &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::acc::FirstprivateRecipeOp createOrGetFirstprivateRecipe( + fir::FirOpBuilder &, llvm::StringRef, mlir::Location, mlir::Type, + llvm::SmallVector &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 48a72d73c03b..c6531ac3d055 100644 --- a/flang/include/flang/Optimizer/Builder/FIRBuilder.h +++ b/flang/include/flang/Optimizer/Builder/FIRBuilder.h @@ -576,7 +576,7 @@ public: /// 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 0f133623475f..9db67afeda5e 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 source, + mlir::TypedValue dest, + mlir::ValueRange bounds) const; + + bool generateCombiner(mlir::Type type, mlir::OpBuilder &mlirBuilder, + mlir::Location loc, + mlir::TypedValue dest, + mlir::TypedValue 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 cfbcf06c4b39..8a7cb3e5d50d 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" @@ -646,54 +649,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 &bounds, - mlir::Type ty) { - auto seqTy = - mlir::dyn_cast_or_null(fir::unwrapRefType(ty)); - if (!bounds.empty() && seqTy) { - llvm::SmallVector shape; - for (auto b : bounds) { - auto boundsOp = - mlir::dyn_cast(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(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 &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: { @@ -791,6 +759,9 @@ genDataOperandOperations(const Fortran::parser::AccObjectList &objectList, dataRef->u); } + bool isPrivate = std::is_same_v || + std::is_same_v; + fir::factory::AddrAndBoundsInfo info = Fortran::lower::gatherDataOperandAddrAndBounds< mlir::acc::DataBoundsOp, mlir::acc::DataBoundsType>( @@ -807,8 +778,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 || - std::is_same_v; mlir::Value baseAddr = (!isPrivate && (fir::unwrapRefType(info.addr.getType()) != fir::unwrapRefType(info.rawInput.getType())) && @@ -816,17 +785,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( 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()); @@ -844,7 +805,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); @@ -1084,16 +1045,6 @@ genDataExitOperations(fir::FirOpBuilder &builder, } } -fir::ShapeOp genShapeOp(mlir::OpBuilder &builder, fir::SequenceType seqTy, - mlir::Location loc) { - llvm::SmallVector 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 static R getReductionInitValue(mlir::acc::ReductionOperator op, mlir::Type ty) { @@ -1207,10 +1158,71 @@ static mlir::Value getReductionInitValue(fir::FirOpBuilder &builder, llvm::report_fatal_error("Unsupported OpenACC reduction type"); } +static llvm::SmallVector +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 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( + 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 lb = + fir::getIntIfConstant(dataBound.getLowerbound()); + std::optional 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 &bounds, + bool allConstantBound, + llvm::SmallVector &argsTy, + llvm::SmallVector &argsLoc) { + if (!allConstantBound) { + for (mlir::Value bound : llvm::reverse(bounds)) { + auto dataBound = + mlir::dyn_cast(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; + template static RecipeOp genRecipeOp( fir::FirOpBuilder &builder, mlir::ModuleOp mod, llvm::StringRef recipeName, mlir::Location loc, mlir::Type ty, + llvm::SmallVector &dataOperationBounds, bool allConstantBound, mlir::acc::ReductionOperator op = mlir::acc::ReductionOperator::AccNone) { mlir::OpBuilder modBuilder(mod.getBodyRegion()); RecipeOp recipe; @@ -1221,20 +1233,13 @@ static RecipeOp genRecipeOp( recipe = RecipeOp::create(modBuilder, loc, recipeName, ty); } + assert(hlfir::isFortranVariableType(ty) && "expect Fortran variable type"); + llvm::SmallVector argsTy{ty}; llvm::SmallVector argsLoc{loc}; - if (auto refTy = mlir::dyn_cast_or_null(ty)) { - if (auto seqTy = - mlir::dyn_cast_or_null(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()); @@ -1256,15 +1261,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>( - 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 initBounds = + getRecipeBounds(builder, loc, dataOperationBounds, + initBlock->getArguments().drop_front(1)); + mlir::Value retVal = mappableTy.generatePrivateInit( + builder, loc, mlir::cast(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 destroyArgsTy; @@ -1280,189 +1283,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 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 &bounds) { mlir::ModuleOp mod = builder.getBlock()->getParent()->getParentOfType(); if (auto recipe = mod.lookupSymbol(recipeName)) return recipe; auto ip = builder.saveInsertionPoint(); - auto recipe = genRecipeOp(builder, mod, - recipeName, loc, ty); + bool allConstantBound = fir::acc::areAllBoundsConstant(bounds); + auto recipe = genRecipeOp( + 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 -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 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 &accBounds, - hlfir::Entity entity) { - assert(entity.getRank() * 3 == static_cast(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(loc, accBounds[i], lb); - mlir::Value sliceUB = - builder.createOrFold(loc, accBounds[i + 1], lb); - triplets.emplace_back( - hlfir::DesignateOp::Triplet{sliceLB, sliceUB, accBounds[i + 2]}); - } - return triplets; -} - -static std::pair -genArraySectionsInRecipe(fir::FirOpBuilder &builder, mlir::Location loc, - llvm::SmallVector &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 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(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(bounds.size()) && - "must get lb,ub,step for each dimension"); - llvm::SmallVector 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 +static std::pair genRecipeCombinerOrCopyRegion(fir::FirOpBuilder &builder, mlir::Location loc, mlir::Type ty, mlir::Region ®ion, llvm::SmallVector &bounds, bool allConstantBound) { llvm::SmallVector argsTy{ty, ty}; llvm::SmallVector argsLoc{loc, loc}; - if (!allConstantBound) { - for (mlir::Value bound : llvm::reverse(bounds)) { - auto dataBound = - mlir::dyn_cast(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(block->getArgument(0)); + auto secondArg = mlir::cast(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 &bounds) { + mlir::Type ty, llvm::SmallVector &dataBoundOps) { mlir::ModuleOp mod = builder.getBlock()->getParent()->getParentOfType(); if (auto recipe = @@ -1470,38 +1343,21 @@ mlir::acc::FirstprivateRecipeOp Fortran::lower::createOrGetFirstprivateRecipe( return recipe; mlir::OpBuilder::InsertionGuard guard(builder); + bool allConstantBound = fir::acc::areAllBoundsConstant(dataBoundOps); auto recipe = genRecipeOp( - 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); + builder, loc, ty, recipe.getCopyRegion(), dataBoundOps, allConstantBound); + llvm::SmallVector copyBounds = + getRecipeBounds(builder, loc, dataBoundOps, + recipe.getCopyRegion().getArguments().drop_front(2)); - fir::FirOpBuilder firBuilder{builder, recipe.getOperation()}; - - source = hlfir::derefPointersAndAllocatables(loc, builder, source); - destination = hlfir::derefPointersAndAllocatables(loc, builder, destination); - - 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(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; } @@ -1537,124 +1393,37 @@ getReductionOperator(const Fortran::parser::ReductionOperator &op) { llvm_unreachable("unexpected reduction operator"); } -template -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(ty)) - return mlir::arith::AddFOp::create(builder, loc, value1, value2); - if (auto cmplxTy = mlir::dyn_cast_or_null(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(ty)) - return mlir::arith::MulFOp::create(builder, loc, value1, value2); - if (mlir::isa(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(builder, loc, value1, - value2); - - if (op == mlir::acc::ReductionOperator::AccLor) - return genLogicalCombiner(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 &bounds) { + llvm::SmallVector &dataBoundOps) { mlir::ModuleOp mod = builder.getBlock()->getParent()->getParentOfType(); if (auto recipe = mod.lookupSymbol(recipeName)) return recipe; mlir::OpBuilder::InsertionGuard guard(builder); + bool allConstantBound = fir::acc::areAllBoundsConstant(dataBoundOps); auto recipe = genRecipeOp( - 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); + auto [dest, source] = genRecipeCombinerOrCopyRegion( + builder, loc, ty, recipe.getCombinerRegion(), dataBoundOps, + allConstantBound); + llvm::SmallVector combinerBounds = + getRecipeBounds(builder, loc, dataBoundOps, + recipe.getCombinerRegion().getArguments().drop_front(2)); - 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 mappableTy = mlir::dyn_cast(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; } @@ -1729,10 +1498,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 c704ac79ae5f..fcceb3a5b32c 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 +static mlir::Value createAndMaybeFold(bool fold, fir::FirOpBuilder &builder, + mlir::Location loc, Args &&...args) { + if (fold) + return builder.createOrFold(loc, std::forward(args)...); + return OpTy::create(builder, loc, std::forward(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(fold, *this, loc, ub, lb); + auto add = + createAndMaybeFold(fold, *this, loc, diff, step); + auto div = + createAndMaybeFold(fold, *this, loc, add, step); + auto cmp = createAndMaybeFold( + fold, *this, loc, mlir::arith::CmpIPredicate::sgt, div, zero); + return createAndMaybeFold(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 a345dcb86e3d..894b920c38fe 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 lhsExtents = - hlfir::getIndexExtents(loc, builder, lhsShape); - mlir::Value rhsShape = hlfir::genShape(loc, builder, rhs); - llvm::SmallVector rhsExtents = - hlfir::getIndexExtents(loc, builder, rhsShape); llvm::SmallVector extents = - fir::factory::deduceOptimalExtents(lhsExtents, rhsExtents); + hlfir::getIndexExtents(loc, builder, lhsShape); + if (rhs.isArray()) { + mlir::Value rhsShape = hlfir::genShape(loc, builder, rhs); + llvm::SmallVector 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 9fcc7d3681c3..2997428b7b5d 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::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 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 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(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 &accBounds, + hlfir::Entity entity) { + assert(entity.getRank() * 3 == static_cast(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(loc, accBounds[i], lb); + mlir::Value sliceUB = + builder.createOrFold(loc, accBounds[i + 1], lb); + triplets.emplace_back( + hlfir::DesignateOp::Triplet{sliceLB, sliceUB, accBounds[i + 2]}); + } + return triplets; +} + +static std::pair> +computeSectionShapeAndExtents(fir::FirOpBuilder &builder, mlir::Location loc, + mlir::ValueRange bounds) { llvm::SmallVector 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 +genArraySectionsInRecipe(fir::FirOpBuilder &builder, mlir::Location loc, + mlir::ValueRange bounds, hlfir::Entity lhs, + hlfir::Entity rhs) { + assert(lhs.getRank() * 3 == static_cast(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 mlir::Value OpenACCMappableModel::generatePrivateInit( - mlir::Type type, mlir::OpBuilder &builder, mlir::Location loc, + mlir::Type type, mlir::OpBuilder &mlirBuilder, mlir::Location loc, mlir::TypedValue 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(); + assert(mod && "failed to retrieve ModuleOp"); + fir::FirOpBuilder builder(mlirBuilder, mod); - if (auto recType = llvm::dyn_cast( - fir::getFortranElementType(unwrappedTy))) { + hlfir::Entity inputVar = hlfir::Entity{var}; + if (inputVar.isPolymorphic()) + TODO(loc, "OpenACC: polymorphic variable privatization"); + if (auto recType = + llvm::dyn_cast(inputVar.getFortranElementType())) { // Need to make deep copies of allocatable components. if (fir::isRecordWithAllocatableMember(recType)) TODO(loc, @@ -597,117 +709,161 @@ mlir::Value OpenACCMappableModel::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 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 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 initial 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 (auto seqTy = mlir::dyn_cast_or_null(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 (inputVar.getType() == alloc.getType() && !allocateSection) + return alloc; - if (initVal) { - mlir::Type idxTy = firBuilder.getIndexType(); - mlir::Type refTy = fir::ReferenceType::get(seqTy.getEleTy()); - llvm::SmallVector loops; - llvm::SmallVector 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(); + // 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 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)); } - } else if (auto boxTy = - mlir::dyn_cast_or_null(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(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`, it will create instead a - // `fir.box`. 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 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 lowerBounds; + llvm::SmallVector zeros; + for (unsigned i = 0; i < bounds.size(); i += 3) { + lowerBounds.push_back(bounds[i]); + zeros.push_back(zero); + } + 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(unwrappedTy)) { - TODO(loc, "Character type for OpenACC private-like recipe"); - } else { - assert((fir::isa_trivial(unwrappedTy) || - llvm::isa(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::generatePrivateInit( mlir::TypedValue var, llvm::StringRef varName, mlir::ValueRange extents, mlir::Value initVal, bool &needsDestroy) const; +template +bool OpenACCMappableModel::generateCopy( + mlir::Type type, mlir::OpBuilder &mlirBuilder, mlir::Location loc, + mlir::TypedValue src, + mlir::TypedValue dest, + mlir::ValueRange bounds) const { + mlir::ModuleOp mod = + mlirBuilder.getBlock()->getParent()->getParentOfType(); + 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::generateCopy( + mlir::Type, mlir::OpBuilder &, mlir::Location, + mlir::TypedValue, + mlir::TypedValue, mlir::ValueRange) const; +template bool OpenACCMappableModel::generateCopy( + mlir::Type, mlir::OpBuilder &, mlir::Location, + mlir::TypedValue, + mlir::TypedValue, mlir::ValueRange) const; +template bool OpenACCMappableModel::generateCopy( + mlir::Type, mlir::OpBuilder &, mlir::Location, + mlir::TypedValue, + mlir::TypedValue, mlir::ValueRange) const; +template bool OpenACCMappableModel::generateCopy( + mlir::Type, mlir::OpBuilder &, mlir::Location, + mlir::TypedValue, + mlir::TypedValue, mlir::ValueRange) const; + +template +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(ty)) + return mlir::arith::AddFOp::create(builder, loc, value1, value2); + if (auto cmplxTy = mlir::dyn_cast_or_null(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(ty)) + return mlir::arith::MulFOp::create(builder, loc, value1, value2); + if (mlir::isa(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(builder, loc, value1, + value2); + + if (op == mlir::acc::ReductionOperator::AccLor) + return genLogicalCombiner(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 +bool OpenACCMappableModel::generateCombiner( + mlir::Type type, mlir::OpBuilder &mlirBuilder, mlir::Location loc, + mlir::TypedValue dest, + mlir::TypedValue source, mlir::ValueRange bounds, + mlir::acc::ReductionOperator op, mlir::Attribute fastmathFlags) const { + mlir::ModuleOp mod = + mlirBuilder.getBlock()->getParent()->getParentOfType(); + assert(mod && "failed to retrieve parent module"); + fir::FirOpBuilder builder(mlirBuilder, mod); + if (fastmathFlags) + if (auto fastMathAttr = + mlir::dyn_cast(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::generateCombiner( + mlir::Type, mlir::OpBuilder &, mlir::Location, + mlir::TypedValue, + mlir::TypedValue, mlir::ValueRange, + mlir::acc::ReductionOperator op, mlir::Attribute) const; +template bool OpenACCMappableModel::generateCombiner( + mlir::Type, mlir::OpBuilder &, mlir::Location, + mlir::TypedValue, + mlir::TypedValue, mlir::ValueRange, + mlir::acc::ReductionOperator op, mlir::Attribute) const; +template bool OpenACCMappableModel::generateCombiner( + mlir::Type, mlir::OpBuilder &, mlir::Location, + mlir::TypedValue, + mlir::TypedValue, mlir::ValueRange, + mlir::acc::ReductionOperator op, mlir::Attribute) const; +template bool OpenACCMappableModel::generateCombiner( + mlir::Type, mlir::OpBuilder &, mlir::Location, + mlir::TypedValue, + mlir::TypedValue, mlir::ValueRange, + mlir::acc::ReductionOperator op, mlir::Attribute) const; + template bool OpenACCMappableModel::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(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(); + 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::generatePrivateDestroy( mlir::Type type, mlir::OpBuilder &builder, mlir::Location loc, - mlir::Value privatized) const; + mlir::Value privatized, mlir::ValueRange bounds) const; template bool OpenACCMappableModel::generatePrivateDestroy( mlir::Type type, mlir::OpBuilder &builder, mlir::Location loc, - mlir::Value privatized) const; + mlir::Value privatized, mlir::ValueRange bounds) const; template bool OpenACCMappableModel::generatePrivateDestroy( mlir::Type type, mlir::OpBuilder &builder, mlir::Location loc, - mlir::Value privatized) const; + mlir::Value privatized, mlir::ValueRange bounds) const; template bool OpenACCMappableModel::generatePrivateDestroy( mlir::Type type, mlir::OpBuilder &builder, mlir::Location loc, - mlir::Value privatized) const; + mlir::Value privatized, mlir::ValueRange bounds) const; template mlir::Value OpenACCPointerLikeModel::genAllocate( diff --git a/flang/lib/Optimizer/OpenACC/Support/FIROpenACCUtils.cpp b/flang/lib/Optimizer/OpenACC/Support/FIROpenACCUtils.cpp index e5b8123305c6..b88936426657 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 0c3f3fea13fa..a033734d2ff0 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 init { // CHECK: ^bb0(%{{.*}}: !fir.ref): // CHECK: %[[ALLOC:.*]] = fir.alloca f32 -// CHECK: %{{.*}}:2 = hlfir.declare %[[ALLOC]] {uniq_name = "scalar"} : (!fir.ref) -> (!fir.ref, !fir.ref) -// CHECK: acc.yield %{{.*}}#0 : !fir.ref +// CHECK: acc.yield %[[ALLOC]] : !fir.ref // CHECK: } copy { // CHECK: ^bb0(%[[SRC:.*]]: !fir.ref, %[[DST:.*]]: !fir.ref): // CHECK: %[[LOAD:.*]] = fir.load %[[SRC]] : !fir.ref @@ -31,8 +30,7 @@ func.func @test_scalar() { // CHECK: acc.firstprivate.recipe @firstprivate_int : !fir.ref init { // CHECK: ^bb0(%{{.*}}: !fir.ref): // CHECK: %[[ALLOC:.*]] = fir.alloca i32 -// CHECK: %{{.*}}:2 = hlfir.declare %[[ALLOC]] {uniq_name = "int"} : (!fir.ref) -> (!fir.ref, !fir.ref) -// CHECK: acc.yield %{{.*}}#0 : !fir.ref +// CHECK: acc.yield %[[ALLOC]] : !fir.ref // CHECK: } copy { // CHECK: ^bb0(%[[SRC:.*]]: !fir.ref, %[[DST:.*]]: !fir.ref): // CHECK: %[[LOAD:.*]] = fir.load %[[SRC]] : !fir.ref @@ -54,8 +52,7 @@ func.func @test_int() { // CHECK: acc.firstprivate.recipe @firstprivate_logical : !fir.ref> init { // CHECK: ^bb0(%{{.*}}: !fir.ref>): // CHECK: %[[ALLOC:.*]] = fir.alloca !fir.logical<4> -// CHECK: %{{.*}}:2 = hlfir.declare %[[ALLOC]] {uniq_name = "logical"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) -// CHECK: acc.yield %{{.*}}#0 : !fir.ref> +// CHECK: acc.yield %[[ALLOC]] : !fir.ref> // CHECK: } copy { // CHECK: ^bb0(%[[SRC:.*]]: !fir.ref>, %[[DST:.*]]: !fir.ref>): // CHECK: %[[LOAD:.*]] = fir.load %[[SRC]] : !fir.ref> @@ -77,8 +74,7 @@ func.func @test_logical() { // CHECK: acc.firstprivate.recipe @firstprivate_complex : !fir.ref> init { // CHECK: ^bb0(%{{.*}}: !fir.ref>): // CHECK: %[[ALLOC:.*]] = fir.alloca complex -// CHECK: %{{.*}}:2 = hlfir.declare %[[ALLOC]] {uniq_name = "complex"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) -// CHECK: acc.yield %{{.*}}#0 : !fir.ref> +// CHECK: acc.yield %[[ALLOC]] : !fir.ref> // CHECK: } copy { // CHECK: ^bb0(%[[SRC:.*]]: !fir.ref>, %[[DST:.*]]: !fir.ref>): // CHECK: %[[LOAD:.*]] = fir.load %[[SRC]] : !fir.ref> @@ -99,11 +95,8 @@ func.func @test_complex() { // Test 1D static array // CHECK: acc.firstprivate.recipe @firstprivate_array_1d : !fir.ref> init { // CHECK: ^bb0(%{{.*}}: !fir.ref>): -// 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.shape<1>) -> (!fir.ref>, !fir.ref>) -// CHECK: acc.yield %{{.*}}#0 : !fir.ref> +// CHECK: acc.yield %[[ALLOC]] : !fir.ref> // CHECK: } copy { // CHECK: ^bb0(%[[SRC:.*]]: !fir.ref>, %[[DST:.*]]: !fir.ref>): // CHECK: hlfir.assign %[[SRC]] to %[[DST]] : !fir.ref>, !fir.ref> @@ -123,12 +116,8 @@ func.func @test_array_1d() { // Test 2D static array // CHECK: acc.firstprivate.recipe @firstprivate_array_2d : !fir.ref> init { // CHECK: ^bb0(%{{.*}}: !fir.ref>): -// 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.shape<2>) -> (!fir.ref>, !fir.ref>) -// CHECK: acc.yield %{{.*}}#0 : !fir.ref> +// CHECK: acc.yield %[[ALLOC]] : !fir.ref> // CHECK: } copy { // CHECK: ^bb0(%[[SRC:.*]]: !fir.ref>, %[[DST:.*]]: !fir.ref>): // CHECK: hlfir.assign %[[SRC]] to %[[DST]] : !fir.ref>, !fir.ref> @@ -149,8 +138,7 @@ func.func @test_array_2d() { // CHECK: acc.firstprivate.recipe @firstprivate_derived : !fir.ref> init { // CHECK: ^bb0(%{{.*}}: !fir.ref>): // CHECK: %[[ALLOC:.*]] = fir.alloca !fir.type<_QTpoint{x:f32,y:f32,z:f32}> -// CHECK: %{{.*}}:2 = hlfir.declare %[[ALLOC]] {uniq_name = "derived"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) -// CHECK: acc.yield %{{.*}}#0 : !fir.ref> +// CHECK: acc.yield %[[ALLOC]] : !fir.ref> // CHECK: } copy { // CHECK: ^bb0(%[[SRC:.*]]: !fir.ref>, %[[DST:.*]]: !fir.ref>): // CHECK: hlfir.assign %[[SRC]] to %[[DST]] : !fir.ref>, !fir.ref> diff --git a/flang/test/Fir/OpenACC/recipe-populate-private.mlir b/flang/test/Fir/OpenACC/recipe-populate-private.mlir index aeb60d6b4a37..f5200f70a3ba 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 init { // CHECK: ^bb0(%{{.*}}: !fir.ref): // CHECK: %[[ALLOC:.*]] = fir.alloca f32 -// CHECK: %{{.*}}:2 = hlfir.declare %[[ALLOC]] {uniq_name = "scalar"} : (!fir.ref) -> (!fir.ref, !fir.ref) -// CHECK: acc.yield %{{.*}}#0 : !fir.ref +// CHECK: acc.yield %[[ALLOC]] : !fir.ref // CHECK: } // CHECK-NOT: destroy @@ -26,8 +25,7 @@ func.func @test_scalar() { // CHECK: acc.private.recipe @private_logical : !fir.ref> init { // CHECK: ^bb0(%{{.*}}: !fir.ref>): // CHECK: %[[ALLOC:.*]] = fir.alloca !fir.logical<4> -// CHECK: %{{.*}}:2 = hlfir.declare %[[ALLOC]] {uniq_name = "logical"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) -// CHECK: acc.yield %{{.*}}#0 : !fir.ref> +// CHECK: acc.yield %[[ALLOC]] : !fir.ref> // CHECK: } // CHECK-NOT: destroy @@ -44,8 +42,7 @@ func.func @test_logical() { // CHECK: acc.private.recipe @private_complex : !fir.ref> init { // CHECK: ^bb0(%{{.*}}: !fir.ref>): // CHECK: %[[ALLOC:.*]] = fir.alloca complex -// CHECK: %{{.*}}:2 = hlfir.declare %[[ALLOC]] {uniq_name = "complex"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) -// CHECK: acc.yield %{{.*}}#0 : !fir.ref> +// CHECK: acc.yield %[[ALLOC]] : !fir.ref> // 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> init { // CHECK: ^bb0(%{{.*}}: !fir.ref>): -// 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.shape<1>) -> (!fir.ref>, !fir.ref>) -// CHECK: acc.yield %{{.*}}#0 : !fir.ref> +// CHECK: acc.yield %[[ALLOC]] : !fir.ref> // 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> init { // CHECK: ^bb0(%{{.*}}: !fir.ref>): -// 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.shape<3>) -> (!fir.ref>, !fir.ref>) -// CHECK: acc.yield %{{.*}}#0 : !fir.ref> +// CHECK: acc.yield %[[ALLOC]] : !fir.ref> // CHECK: } // CHECK-NOT: destroy @@ -104,8 +93,7 @@ func.func @test_array_3d() { // CHECK: acc.private.recipe @private_derived : !fir.ref> init { // CHECK: ^bb0(%{{.*}}: !fir.ref>): // CHECK: %[[ALLOC:.*]] = fir.alloca !fir.type<_QTpoint{x:f32,y:f32,z:f32}> -// CHECK: %{{.*}}:2 = hlfir.declare %[[ALLOC]] {uniq_name = "derived"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) -// CHECK: acc.yield %{{.*}}#0 : !fir.ref> +// CHECK: acc.yield %[[ALLOC]] : !fir.ref> // 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>> init { // CHECK: ^bb0(%{{.*}}: !fir.ref>>): -// CHECK: %[[BOXALLOC:.*]] = fir.alloca !fir.box> -// CHECK: %{{.*}}:2 = hlfir.declare %[[BOXALLOC]] {uniq_name = "box_heap_scalar"} : (!fir.ref>>) -> (!fir.ref>>, !fir.ref>>) // CHECK: %[[SCALAR:.*]] = fir.allocmem f64 // CHECK: %[[EMBOX:.*]] = fir.embox %[[SCALAR]] : (!fir.heap) -> !fir.box> -// CHECK: fir.store %[[EMBOX]] to %{{.*}}#0 : !fir.ref>> -// CHECK: acc.yield %{{.*}}#0 : !fir.ref>> +// CHECK: %[[BOXALLOC:.*]] = fir.alloca !fir.box> +// CHECK: fir.store %[[EMBOX]] to %[[BOXALLOC]] : !fir.ref>> +// CHECK: acc.yield %[[BOXALLOC]] : !fir.ref>> // CHECK: } destroy { // CHECK: ^bb0(%{{.*}}: !fir.ref>>, %{{.*}}: !fir.ref>>): // 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>> init { // CHECK: ^bb0(%{{.*}}: !fir.ref>>): -// CHECK: %[[BOXALLOC:.*]] = fir.alloca !fir.box> -// CHECK: %{{.*}}:2 = hlfir.declare %[[BOXALLOC]] {uniq_name = "box_ptr_scalar"} : (!fir.ref>>) -> (!fir.ref>>, !fir.ref>>) // CHECK: %[[SCALAR:.*]] = fir.allocmem i32 // CHECK: %[[EMBOX:.*]] = fir.embox %[[SCALAR]] : (!fir.heap) -> !fir.box> -// CHECK: fir.store %[[EMBOX]] to %{{.*}}#0 : !fir.ref>> -// CHECK: acc.yield %{{.*}}#0 : !fir.ref>> +// CHECK: %[[BOXALLOC:.*]] = fir.alloca !fir.box> +// CHECK: fir.store %[[EMBOX]] to %[[BOXALLOC]] : !fir.ref>> +// CHECK: acc.yield %[[BOXALLOC]] : !fir.ref>> // CHECK: } destroy { // CHECK: ^bb0(%{{.*}}: !fir.ref>>, %{{.*}}: !fir.ref>>): // CHECK: acc.terminator @@ -168,8 +154,7 @@ func.func @test_box_ptr_scalar() { // CHECK: acc.private.recipe @private_box_heap_array_1d : !fir.ref>>> init { // CHECK: ^bb0(%{{.*}}: !fir.ref>>>): // CHECK: %[[BOXALLOC:.*]] = fir.alloca !fir.box>> -// CHECK: %{{.*}}:2 = hlfir.declare %[[BOXALLOC]] {uniq_name = "box_heap_array_1d"} : (!fir.ref>>>) -> (!fir.ref>>>, !fir.ref>>>) -// CHECK: acc.yield %{{.*}}#0 : !fir.ref>>> +// CHECK: acc.yield %[[BOXALLOC]] : !fir.ref>>> // CHECK: } destroy { // CHECK: ^bb0(%{{.*}}: !fir.ref>>>, %{{.*}}: !fir.ref>>>): // 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>>> init { // CHECK: ^bb0(%{{.*}}: !fir.ref>>>): // CHECK: %[[BOXALLOC:.*]] = fir.alloca !fir.box>> -// CHECK: %{{.*}}:2 = hlfir.declare %[[BOXALLOC]] {uniq_name = "box_heap_array_2d"} : (!fir.ref>>>) -> (!fir.ref>>>, !fir.ref>>>) -// CHECK: acc.yield %{{.*}}#0 : !fir.ref>>> +// CHECK: acc.yield %[[BOXALLOC]] : !fir.ref>>> // CHECK: } destroy { // CHECK: ^bb0(%{{.*}}: !fir.ref>>>, %{{.*}}: !fir.ref>>>): // CHECK: acc.terminator @@ -208,8 +192,7 @@ func.func @test_box_heap_array_2d() { // CHECK: acc.private.recipe @private_box_ptr_array : !fir.ref>>> init { // CHECK: ^bb0(%{{.*}}: !fir.ref>>>): // CHECK: %[[BOXALLOC:.*]] = fir.alloca !fir.box>> -// CHECK: %{{.*}}:2 = hlfir.declare %[[BOXALLOC]] {uniq_name = "box_ptr_array"} : (!fir.ref>>>) -> (!fir.ref>>>, !fir.ref>>>) -// CHECK: acc.yield %{{.*}}#0 : !fir.ref>>> +// CHECK: acc.yield %[[BOXALLOC]] : !fir.ref>>> // CHECK: } destroy { // CHECK: ^bb0(%{{.*}}: !fir.ref>>>, %{{.*}}: !fir.ref>>>): // 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 61f3d0237d66..eefec65f4d93 100644 --- a/flang/test/Lower/OpenACC/acc-firstprivate-derived-pointer-component.f90 +++ b/flang/test/Lower/OpenACC/acc-firstprivate-derived-pointer-component.f90 @@ -1,8 +1,11 @@ ! Test lowering of firstprivate on derived type with pointer components. ! No deep copy must be done. -! RUN: bbc -fopenacc -emit-hlfir %s -o - | FileCheck %s -! RUN: bbc -fopenacc -emit-fir %s -o - | FileCheck %s --check-prefix=FIR-CHECK +! TODO: ensure pointer components are initialized to NULL for private. + +! RUN: not bbc -fopenacc -emit-hlfir %s -o - 2>&1 | FileCheck %s + +! CHECK: not yet implemented: OpenACC: privatizing derived type with pointer components module m_firstprivate_derived_ptr_comp type point @@ -17,66 +20,4 @@ module m_firstprivate_derived_ptr_comp a%x(10) = 1 enddo end - end module - -! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_rec__QMm_firstprivate_derived_ptr_compTpoint : !fir.ref>>}>> init { -! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>>}>>): -! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.type<_QMm_firstprivate_derived_ptr_compTpoint{x:!fir.box>>}> -! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_1]] {uniq_name = "acc.private.init"} : (!fir.ref>>}>>) -> (!fir.ref>>}>>, !fir.ref>>}>>) -! CHECK: acc.yield %[[VAL_2]]#0 : !fir.ref>>}>> -! -! CHECK: } copy { -! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>>}>>, %[[VAL_1:.*]]: !fir.ref>>}>>): -! CHECK: hlfir.assign %[[VAL_0]] to %[[VAL_1]] temporary_lhs : !fir.ref>>}>>, !fir.ref>>}>> -! CHECK: acc.terminator -! CHECK: } -! -! CHECK-LABEL: func.func @_QMm_firstprivate_derived_ptr_compPtest( -! CHECK-SAME: %[[ARG0:.*]]: !fir.ref>>}>> {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.dscope) -> (!fir.ref>>}>>, !fir.ref>>}>>) -! 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) -> (!fir.ref, !fir.ref) -! 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) -> (!fir.ref, !fir.ref) -! CHECK: %[[VAL_6:.*]] = acc.firstprivate varPtr(%[[VAL_1]]#0 : !fir.ref>>}>>) recipe(@firstprivatization_ref_rec__QMm_firstprivate_derived_ptr_compTpoint) -> !fir.ref>>}>> {name = "a"} -! CHECK: acc.parallel combined(loop) firstprivate(%[[VAL_6]] : !fir.ref>>}>>) { -! 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.dscope) -> (!fir.ref>>}>>, !fir.ref>>}>>) -! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i32 -! CHECK: %[[VAL_10:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref -! CHECK: %[[VAL_11:.*]] = arith.constant 1 : i32 -! CHECK: %[[VAL_12:.*]] = acc.private varPtr(%[[VAL_3]]#0 : !fir.ref) recipe(@privatization_ref_i32) -> !fir.ref {implicit = true, name = "i"} -! CHECK: acc.loop combined(parallel) private(%[[VAL_12]] : !fir.ref) 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) -> (!fir.ref, !fir.ref) -! CHECK: fir.store %[[VAL_14]] to %[[VAL_13]]#0 : !fir.ref -! CHECK: %[[VAL_15:.*]] = arith.constant 1.000000e+00 : f32 -! CHECK: %[[VAL_16:.*]] = hlfir.designate %[[VAL_8]]#0{"x"} {fortran_attrs = #fir.var_attrs} : (!fir.ref>>}>>) -> !fir.ref>>> -! CHECK: %[[VAL_17:.*]] = fir.load %[[VAL_16]] : !fir.ref>>> -! CHECK: %[[VAL_18:.*]] = arith.constant 10 : index -! CHECK: %[[VAL_19:.*]] = hlfir.designate %[[VAL_17]] (%[[VAL_18]]) : (!fir.box>>, index) -> !fir.ref -! CHECK: hlfir.assign %[[VAL_15]] to %[[VAL_19]] : f32, !fir.ref -! CHECK: acc.yield -! CHECK: } attributes {inclusiveUpperbound = array, independent = [#acc.device_type]} -! CHECK: acc.yield -! CHECK: } -! CHECK: return -! CHECK: } - - -! FIR-CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_rec__QMm_firstprivate_derived_ptr_compTpoint : !fir.ref>>}>> init { -! FIR-CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>>}>>): -! FIR-CHECK: %[[VAL_1:.*]] = fir.alloca !fir.type<_QMm_firstprivate_derived_ptr_compTpoint{x:!fir.box>>}> -! FIR-CHECK: %[[VAL_2:.*]] = fir.declare %[[VAL_1]] {uniq_name = "acc.private.init"} : (!fir.ref>>}>>) -> !fir.ref>>}>> -! FIR-CHECK: acc.yield %[[VAL_2]] : !fir.ref>>}>> -! -! FIR-CHECK-LABEL: } copy { -! FIR-CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>>}>>, %[[VAL_1:.*]]: !fir.ref>>}>>): -! FIR-CHECK: %[[VAL_2:.*]] = fir.field_index x, !fir.type<_QMm_firstprivate_derived_ptr_compTpoint{x:!fir.box>>}> -! FIR-CHECK: %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_0]], x : (!fir.ref>>}>>) -> !fir.ref>>> -! FIR-CHECK: %[[VAL_4:.*]] = fir.field_index x, !fir.type<_QMm_firstprivate_derived_ptr_compTpoint{x:!fir.box>>}> -! FIR-CHECK: %[[VAL_5:.*]] = fir.coordinate_of %[[VAL_1]], x : (!fir.ref>>}>>) -> !fir.ref>>> -! FIR-CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_3]] : !fir.ref>>> -! FIR-CHECK: fir.store %[[VAL_6]] to %[[VAL_5]] : !fir.ref>>> -! FIR-CHECK: acc.terminator -! FIR-CHECK: } +end module 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 9ada6d360edd..98ae36f1eef2 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 @@ module m_firstprivate_derived_user_def ! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_rec__QMm_firstprivate_derived_user_defTpoint : !fir.ref> init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): ! 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.ref>, !fir.ref>) -! CHECK: acc.yield %[[VAL_2]]#0 : !fir.ref> +! CHECK: acc.yield %[[VAL_1]] : !fir.ref> ! ! CHECK: } copy { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): @@ -77,8 +76,7 @@ module m_firstprivate_derived_user_def ! FIR-CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_rec__QMm_firstprivate_derived_user_defTpoint : !fir.ref> init { ! FIR-CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): ! 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.ref> -! FIR-CHECK: acc.yield %[[VAL_2]] : !fir.ref> +! FIR-CHECK: acc.yield %[[VAL_1]] : !fir.ref> ! FIR-CHECK: } copy { ! FIR-CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): ! 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 6260f753aa90..3b59a0353b19 100644 --- a/flang/test/Lower/OpenACC/acc-firstprivate-derived.f90 +++ b/flang/test/Lower/OpenACC/acc-firstprivate-derived.f90 @@ -22,8 +22,7 @@ module m_firstprivate_derived ! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_rec__QMm_firstprivate_derivedTpoint : !fir.ref> init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): ! 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.ref>, !fir.ref>) -! CHECK: acc.yield %[[VAL_2]]#0 : !fir.ref> +! CHECK: acc.yield %[[VAL_1]] : !fir.ref> ! ! CHECK: } copy { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): @@ -63,8 +62,7 @@ module m_firstprivate_derived ! FIR-CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_rec__QMm_firstprivate_derivedTpoint : !fir.ref> init { ! FIR-CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): ! 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.ref> -! FIR-CHECK: acc.yield %[[VAL_2]] : !fir.ref> +! FIR-CHECK: acc.yield %[[VAL_1]] : !fir.ref> ! FIR-CHECK: } copy { ! FIR-CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): ! 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 103dec203daa..6d6cc9c623ce 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> init { ! CHECK: ^bb0(%{{.*}}: !fir.ref>): -! 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.shape<2>) -> (!fir.ref>, !fir.ref>) -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref> +! CHECK: acc.yield %[[ALLOCA]] : !fir.ref> ! CHECK: } copy { ! CHECK: ^bb0(%arg0: !fir.ref>, %arg1: !fir.ref>): ! CHECK: acc.terminator @@ -15,9 +13,8 @@ ! CHECK-LABEL: acc.private.recipe @privatization_ref_10x10xf32 : !fir.ref> init { ! CHECK: ^bb0(%{{.*}}: !fir.ref>): -! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2> -! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.private.init"} : (!fir.ref>, !fir.shape<2>) -> (!fir.ref>, !fir.ref>) -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref> +! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<10x10xf32> +! CHECK: acc.yield %[[ALLOCA]] : !fir.ref> ! 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 c62e918b12c1..494267b26fed 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> init { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ptr>): -! 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.shape<1>) -> (!fir.ref>, !fir.ref>) -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref> -! CHECK: } -! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_box_UxUx2xi32 : !fir.box> init { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box>): -! CHECK: %[[DIM0:.*]]:3 = fir.box_dims %arg0, %c0{{.*}} : (!fir.box>, index) -> (index, index, index) -! CHECK: %[[DIM1:.*]]:3 = fir.box_dims %arg0, %c1{{.*}} : (!fir.box>, 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, %[[DIM0]]#1, %[[DIM1]]#1 {bindc_name = ".tmp", uniq_name = ""} -! CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[TEMP]](%[[SHAPE]]) {uniq_name = ".tmp"} : (!fir.heap>, !fir.shape<3>) -> (!fir.box>, !fir.heap>) -! CHECK: acc.yield %[[DECL]]#0 : !fir.box> -! CHECK: } copy { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box>, %[[ARG1:.*]]: !fir.box>): -! CHECK: hlfir.assign %[[ARG0]] to %[[ARG1]] temporary_lhs : !fir.box>, !fir.box> -! CHECK: acc.terminator -! CHECK: } destroy { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box>, %[[ARG1:.*]]: !fir.box>): -! CHECK: %[[ADDR:.*]] = fir.box_addr %[[ARG1]] : (!fir.box>) -> !fir.ref> -! CHECK: %[[CAST:.*]] = fir.convert %[[ADDR]] : (!fir.ref>) -> !fir.heap> -! CHECK: fir.freemem %[[CAST]] : !fir.heap> -! CHECK: acc.terminator -! CHECK: } +! CHECK-LABEL: acc.private.recipe @privatization_ptr_10xf32 : !fir.ptr> init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ptr>): +! 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> +! CHECK: } -! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_section_lb4.ub9_box_Uxi32 : !fir.box> init { -! CHECK: ^bb0(%{{.*}}: !fir.box>): -! CHECK: } copy { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box>, %[[ARG1:.*]]: !fir.box>): -! CHECK: hlfir.assign {{.*}} to {{.*}} temporary_lhs : !fir.box>, !fir.box> -! CHECK: acc.terminator -! CHECK: } destroy { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box>, %[[ARG1:.*]]: !fir.box>): -! CHECK: %[[ADDR:.*]] = fir.box_addr %[[ARG1]] : (!fir.box>) -> !fir.ref> -! CHECK: %[[CAST:.*]] = fir.convert %[[ADDR]] : (!fir.ref>) -> !fir.heap> -! CHECK: fir.freemem %[[CAST]] : !fir.heap> -! CHECK: acc.terminator -! CHECK: } +! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_box_UxUx2xi32 : !fir.box> init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_0]] : (!fir.box>, 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>, 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, %[[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>, 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>, 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>, 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>, 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>, 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.shapeshift<3>) -> !fir.box> +! CHECK: acc.yield %[[EMBOX_0]] : !fir.box> -! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_box_Uxi32 : !fir.box> init { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box>): -! CHECK: %[[C0:.*]] = arith.constant 0 : index -! CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[ARG0]], %c0 : (!fir.box>, index) -> (index, index, index) -! CHECK: %[[SHAPE:.*]] = fir.shape %[[BOX_DIMS]]#1 : (index) -> !fir.shape<1> -! CHECK: %[[TEMP:.*]] = fir.allocmem !fir.array, %[[BOX_DIMS]]#1 {bindc_name = ".tmp", uniq_name = ""} -! CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[TEMP]](%[[SHAPE]]) {uniq_name = ".tmp"} : (!fir.heap>, !fir.shape<1>) -> (!fir.box>, !fir.heap>) -! CHECK: acc.yield %[[DECL]]#0 : !fir.box> -! CHECK: } copy { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box>, %[[ARG1:.*]]: !fir.box>): -! CHECK: hlfir.assign %[[ARG0]] to %[[ARG1]] temporary_lhs : !fir.box>, !fir.box> -! CHECK: acc.terminator -! CHECK: } destroy { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box>, %[[ARG1:.*]]: !fir.box>): -! CHECK: %[[ADDR:.*]] = fir.box_addr %[[ARG1]] : (!fir.box>) -> !fir.ref> -! CHECK: %[[CAST:.*]] = fir.convert %[[ADDR]] : (!fir.ref>) -> !fir.heap> -! CHECK: fir.freemem %[[CAST]] : !fir.heap> -! CHECK: acc.terminator -! CHECK: } +! CHECK-LABEL: } copy { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box>, %[[VAL_1:.*]]: !fir.box>): +! CHECK: hlfir.assign %[[VAL_0]] to %[[VAL_1]] temporary_lhs : !fir.box>, !fir.box> +! CHECK: acc.terminator -! CHECK-LABEL: acc.private.recipe @privatization_box_UxUx2xi32 : !fir.box> init { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box>): -! CHECK: %[[DIM0:.*]]:3 = fir.box_dims %arg0, %c0{{.*}} : (!fir.box>, index) -> (index, index, index) -! CHECK: %[[DIM1:.*]]:3 = fir.box_dims %arg0, %c1{{.*}} : (!fir.box>, 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, %[[DIM0]]#1, %[[DIM1]]#1 {bindc_name = ".tmp", uniq_name = ""} -! CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[TEMP]](%[[SHAPE]]) {uniq_name = ".tmp"} : (!fir.heap>, !fir.shape<3>) -> (!fir.box>, !fir.heap>) -! CHECK: acc.yield %[[DECL]]#0 : !fir.box> -! CHECK: } destroy { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box>, %[[ARG1:.*]]: !fir.box>): -! CHECK: %[[ADDR:.*]] = fir.box_addr %[[ARG1]] : (!fir.box>) -> !fir.ref> -! CHECK: %[[CAST:.*]] = fir.convert %[[ADDR]] : (!fir.ref>) -> !fir.heap> -! CHECK: fir.freemem %[[CAST]] : !fir.heap> -! CHECK: acc.terminator -! CHECK: } +! CHECK-LABEL: } destroy { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box>, %[[VAL_1:.*]]: !fir.box>): +! CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>) -> !fir.ref> +! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[BOX_ADDR_0]] : (!fir.ref>) -> !fir.heap> +! CHECK: fir.freemem %[[CONVERT_0]] : !fir.heap> +! CHECK: acc.terminator +! CHECK: } -! CHECK-LABEL: acc.private.recipe @privatization_ref_box_ptr_Uxi32 : !fir.ref>>> init { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref>>>): -! CHECK: %[[LOADBOX:.*]] = fir.load %[[ARG0]] : !fir.ref>>> -! CHECK: %[[C0:.*]] = arith.constant 0 : index -! CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[LOADBOX]], %c0 : (!fir.box>>, index) -> (index, index, index) -! CHECK: %[[SHAPE:.*]] = fir.shape %[[BOX_DIMS]]#1 : (index) -> !fir.shape<1> -! CHECK: %[[TEMP:.*]] = fir.allocmem !fir.array, %[[BOX_DIMS]]#1 {bindc_name = ".tmp", uniq_name = ""} -! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[TEMP]](%[[SHAPE]]) {uniq_name = ".tmp"} : (!fir.heap>, !fir.shape<1>) -> (!fir.box>, !fir.heap>) -! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.box>> -! CHECK: %[[DECLAREBOX:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.private.init"} : (!fir.ref>>>) -> (!fir.ref>>>, !fir.ref>>>) -! CHECK: %[[CONV:.*]] = fir.convert %[[DECLAREBOX]]#0 : (!fir.ref>>>) -> !fir.ref>> -! CHECK: fir.store %[[DECLARE]]#0 to %[[CONV]] : !fir.ref>> -! CHECK: acc.yield %[[DECLAREBOX]]#0 : !fir.ref>>> -! CHECK: } destroy { -! CHECK: ^bb0(%arg0: !fir.ref>>>, %arg1: !fir.ref>>>): -! CHECK: %[[LOAD:.*]] = fir.load %arg1 : !fir.ref>>> -! CHECK: %[[ADDR:.*]] = fir.box_addr %[[LOAD]] : (!fir.box>>) -> !fir.ptr> -! CHECK: %[[CAST:.*]] = fir.convert %[[ADDR]] : (!fir.ptr>) -> !fir.heap> -! CHECK: fir.freemem %[[CAST]] : !fir.heap> -! CHECK: acc.terminator -! CHECK: } +! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_section_lb4.ub9_box_Uxi32 : !fir.box> init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box>): +! 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>, 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>, index, index, index, !fir.shape<1>) -> !fir.box> +! CHECK: %[[CONSTANT_8:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_1:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_8]] : (!fir.box>, 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>, index) -> (index, index, index) +! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[ALLOCA_0]] : (!fir.ref>) -> !fir.ref> +! 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.shapeshift<1>, index) -> !fir.ref +! CHECK: %[[CONVERT_1:.*]] = fir.convert %[[ARRAY_COOR_0]] : (!fir.ref) -> !fir.ref> +! 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.shapeshift<1>) -> !fir.box> +! CHECK: acc.yield %[[EMBOX_0]] : !fir.box> -! CHECK-LABEL: @privatization_ref_box_heap_i32 : !fir.ref>> init { -! CHECK: ^bb0(%arg0: !fir.ref>>): -! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.box> -! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.private.init"} : (!fir.ref>>) -> (!fir.ref>>, !fir.ref>>) -! CHECK: %[[ALLOCMEM:.*]] = fir.allocmem i32 -! CHECK: %[[BOX:.*]] = fir.embox %[[ALLOCMEM]] : (!fir.heap) -> !fir.box> -! CHECK: fir.store %[[BOX]] to %[[DECLARE]]#0 : !fir.ref>> -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref>> -! CHECK: } destroy { -! CHECK: ^bb0(%arg0: !fir.ref>>, %arg1: !fir.ref>>): -! CHECK: %[[LOAD:.*]] = fir.load %arg1 : !fir.ref>> -! CHECK: %[[ADDR:.*]] = fir.box_addr %[[LOAD]] : (!fir.box>) -> !fir.heap -! CHECK: fir.freemem %[[ADDR]] : !fir.heap -! CHECK: acc.terminator -! CHECK: } +! CHECK-LABEL: } copy { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box>, %[[VAL_1:.*]]: !fir.box>): +! 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>, 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>, 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>, index, index, index, !fir.shape<1>) -> !fir.box> +! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_1]] (%[[ADDI_0]]:%[[ADDI_1]]:%[[CONSTANT_0]]) shape %[[SHAPE_0]] : (!fir.box>, index, index, index, !fir.shape<1>) -> !fir.box> +! CHECK: hlfir.assign %[[DESIGNATE_0]] to %[[DESIGNATE_1]] temporary_lhs : !fir.box>, !fir.box> +! CHECK: acc.terminator +! CHECK: } -! CHECK-LABEL: acc.private.recipe @privatization_ref_box_heap_Uxi32 : !fir.ref>>> init { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref>>>): -! CHECK: %[[LOADBOX:.*]] = fir.load %[[ARG0]] : !fir.ref>>> -! CHECK: %[[C0:.*]] = arith.constant 0 : index -! CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[LOADBOX]], %[[C0]] : (!fir.box>>, index) -> (index, index, index) -! CHECK: %[[SHAPE:.*]] = fir.shape %[[BOX_DIMS]]#1 : (index) -> !fir.shape<1> -! CHECK: %[[TEMP:.*]] = fir.allocmem !fir.array, %[[BOX_DIMS]]#1 {bindc_name = ".tmp", uniq_name = ""} -! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[TEMP]](%[[SHAPE]]) {uniq_name = ".tmp"} : (!fir.heap>, !fir.shape<1>) -> (!fir.box>, !fir.heap>) -! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.box>> -! CHECK: %[[DECLAREBOX:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.private.init"} : (!fir.ref>>>) -> (!fir.ref>>>, !fir.ref>>>) -! CHECK: %[[CONV:.*]] = fir.convert %[[DECLAREBOX]]#0 : (!fir.ref>>>) -> !fir.ref>> -! CHECK: fir.store %[[DECLARE]]#0 to %[[CONV]] : !fir.ref>> -! CHECK: acc.yield %[[DECLAREBOX]]#0 : !fir.ref>>> -! CHECK: } destroy { -! CHECK: ^bb0(%arg0: !fir.ref>>>, %arg1: !fir.ref>>>): -! CHECK: %[[LOAD:.*]] = fir.load %arg1 : !fir.ref>>> -! CHECK: %[[ADDR:.*]] = fir.box_addr %[[LOAD]] : (!fir.box>>) -> !fir.heap> -! CHECK: fir.freemem %[[ADDR]] : !fir.heap> -! CHECK: acc.terminator -! CHECK: } +! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_box_Uxi32 : !fir.box> init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_0]] : (!fir.box>, 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, %[[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>, 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>, 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.shapeshift<1>) -> !fir.box> +! CHECK: acc.yield %[[EMBOX_0]] : !fir.box> -! CHECK-LABEL: acc.private.recipe @privatization_box_Uxi32 : !fir.box> init { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box>): -! CHECK: %[[C0:.*]] = arith.constant 0 : index -! CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[ARG0]], %[[C0]] : (!fir.box>, index) -> (index, index, index) -! CHECK: %[[SHAPE:.*]] = fir.shape %[[BOX_DIMS]]#1 : (index) -> !fir.shape<1> -! CHECK: %[[TEMP:.*]] = fir.allocmem !fir.array, %0#1 {bindc_name = ".tmp", uniq_name = ""} -! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[TEMP]](%[[SHAPE]]) {uniq_name = ".tmp"} : (!fir.heap>, !fir.shape<1>) -> (!fir.box>, !fir.heap>) -! CHECK: acc.yield %[[DECLARE:.*]]#0 : !fir.box> -! CHECK: } destroy { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box>, %[[ARG1:.*]]: !fir.box>): -! CHECK: %[[ADDR:.*]] = fir.box_addr %[[ARG1]] : (!fir.box>) -> !fir.ref> -! CHECK: %[[CAST:.*]] = fir.convert %[[ADDR]] : (!fir.ref>) -> !fir.heap> -! CHECK: fir.freemem %[[CAST]] : !fir.heap> -! CHECK: acc.terminator -! CHECK: } +! CHECK-LABEL: } copy { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box>, %[[VAL_1:.*]]: !fir.box>): +! CHECK: hlfir.assign %[[VAL_0]] to %[[VAL_1]] temporary_lhs : !fir.box>, !fir.box> +! CHECK: acc.terminator -! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_section_lb50.ub99_ref_50xf32 : !fir.ref> init { -! CHECK: ^bb0(%{{.*}}: !fir.ref>): -! 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.shape<1>) -> (!fir.ref>, !fir.ref>) -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref> -! CHECK: } copy { -! CHECK: ^bb0(%[[SRC:.*]]: !fir.ref>, %[[DST:.*]]: !fir.ref>): -! 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>, index, index, index, !fir.shape<1>) -> !fir.ref> -! CHECK: %[[SEC_DST:.*]] = hlfir.designate %[[DST]] (%c51{{.*}}:%c100{{.*}}:%c1{{.*}}) shape %[[SH]] : (!fir.ref>, index, index, index, !fir.shape<1>) -> !fir.ref> -! CHECK: hlfir.assign %[[SEC_SRC]] to %[[SEC_DST]] temporary_lhs : !fir.ref>, !fir.ref> -! CHECK: acc.terminator -! CHECK: } +! CHECK-LABEL: } destroy { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box>, %[[VAL_1:.*]]: !fir.box>): +! CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>) -> !fir.ref> +! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[BOX_ADDR_0]] : (!fir.ref>) -> !fir.heap> +! CHECK: fir.freemem %[[CONVERT_0]] : !fir.heap> +! CHECK: acc.terminator +! CHECK: } -! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_100xf32 : !fir.ref> init { -! CHECK: ^bb0(%{{.*}}: !fir.ref>): -! 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.shape<1>) -> (!fir.ref>, !fir.ref>) -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref> -! CHECK: } copy { -! CHECK: ^bb0(%[[SRC:.*]]: !fir.ref>, %[[DST:.*]]: !fir.ref>): -! CHECK: hlfir.assign %[[SRC]] to %[[DST]] temporary_lhs : !fir.ref>, !fir.ref> -! CHECK: acc.terminator -! CHECK: } +! CHECK-LABEL: acc.private.recipe @privatization_box_UxUx2xi32 : !fir.box> init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_0]] : (!fir.box>, 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>, 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, %[[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>, 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>, 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>, 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>, 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>, 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.shapeshift<3>) -> !fir.box> +! CHECK: acc.yield %[[EMBOX_0]] : !fir.box> -! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_i32 : !fir.ref init { -! CHECK: ^bb0(%{{.*}}: !fir.ref): -! CHECK: %[[ALLOCA:.*]] = fir.alloca i32 -! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.private.init"} : (!fir.ref) -> (!fir.ref, !fir.ref) -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref -! CHECK: } copy { -! CHECK: ^bb0(%[[SRC:.*]]: !fir.ref, %[[DST:.*]]: !fir.ref): -! CHECK: %[[VALUE:.*]] = fir.load %[[SRC]] : !fir.ref -! CHECK: fir.assign %[[VALUE]] to %[[DST]] temporary_lhs : i32, !fir.ref -! CHECK: acc.terminator -! CHECK: } +! CHECK-LABEL: } destroy { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box>, %[[VAL_1:.*]]: !fir.box>): +! CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>) -> !fir.ref> +! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[BOX_ADDR_0]] : (!fir.ref>) -> !fir.heap> +! CHECK: fir.freemem %[[CONVERT_0]] : !fir.heap> +! CHECK: acc.terminator +! CHECK: } -! CHECK-LABEL: acc.private.recipe @privatization_ref_50xf32 : !fir.ref> init { -! CHECK: ^bb0(%{{.*}}: !fir.ref>): -! 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.shape<1>) -> (!fir.ref>, !fir.ref>) -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref> -! CHECK: } +! CHECK-LABEL: acc.private.recipe @privatization_ref_box_ptr_Uxi32 : !fir.ref>>> init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>>>): +! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_0]] : !fir.ref>>> +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[LOAD_0]], %[[CONSTANT_0]] : (!fir.box>>, 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, %[[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>>, 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>>, 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.shapeshift<1>) -> !fir.box>> +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.box>> +! CHECK: fir.store %[[EMBOX_0]] to %[[ALLOCA_0]] : !fir.ref>>> +! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref>>> -! CHECK-LABEL: acc.private.recipe @privatization_ref_100xf32 : !fir.ref> init { -! CHECK: ^bb0(%{{.*}}: !fir.ref>): -! 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.shape<1>) -> (!fir.ref>, !fir.ref>) -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref> -! CHECK: } +! CHECK-LABEL: } destroy { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>>>, %[[VAL_1:.*]]: !fir.ref>>>): +! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref>>> +! CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_0]] : (!fir.box>>) -> !fir.ptr> +! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[BOX_ADDR_0]] : (!fir.ptr>) -> !fir.heap> +! CHECK: fir.freemem %[[CONVERT_0]] : !fir.heap> +! CHECK: acc.terminator +! CHECK: } -! CHECK-LABEL: acc.private.recipe @privatization_ref_i32 : !fir.ref init { -! CHECK: ^bb0(%{{.*}}: !fir.ref): -! CHECK: %[[ALLOCA:.*]] = fir.alloca i32 -! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.private.init"} : (!fir.ref) -> (!fir.ref, !fir.ref) -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref -! CHECK: } +! CHECK-LABEL: acc.private.recipe @privatization_ref_box_heap_i32 : !fir.ref>> init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>>): +! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_0]] : !fir.ref>> +! CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_0]] : (!fir.box>) -> !fir.heap +! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem i32 {bindc_name = "acc.private.init", uniq_name = ""} +! CHECK: %[[EMBOX_0:.*]] = fir.embox %[[ALLOCMEM_0]] : (!fir.heap) -> !fir.box> +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.box> +! CHECK: fir.store %[[EMBOX_0]] to %[[ALLOCA_0]] : !fir.ref>> +! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref>> + +! CHECK-LABEL: } destroy { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>>, %[[VAL_1:.*]]: !fir.ref>>): +! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref>> +! CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_0]] : (!fir.box>) -> !fir.heap +! CHECK: fir.freemem %[[BOX_ADDR_0]] : !fir.heap +! CHECK: acc.terminator +! CHECK: } + +! CHECK-LABEL: acc.private.recipe @privatization_ref_box_heap_Uxi32 : !fir.ref>>> init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>>>): +! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_0]] : !fir.ref>>> +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[LOAD_0]], %[[CONSTANT_0]] : (!fir.box>>, 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, %[[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>>, 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>>, 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.shapeshift<1>) -> !fir.box>> +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.box>> +! CHECK: fir.store %[[EMBOX_0]] to %[[ALLOCA_0]] : !fir.ref>>> +! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref>>> + +! CHECK-LABEL: } destroy { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>>>, %[[VAL_1:.*]]: !fir.ref>>>): +! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref>>> +! CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_0]] : (!fir.box>>) -> !fir.heap> +! CHECK: fir.freemem %[[BOX_ADDR_0]] : !fir.heap> +! CHECK: acc.terminator +! CHECK: } + +! CHECK-LABEL: acc.private.recipe @privatization_box_Uxi32 : !fir.box> init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_0]] : (!fir.box>, 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, %[[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>, 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>, 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.shapeshift<1>) -> !fir.box> +! CHECK: acc.yield %[[EMBOX_0]] : !fir.box> + +! CHECK-LABEL: } destroy { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box>, %[[VAL_1:.*]]: !fir.box>): +! CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>) -> !fir.ref> +! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[BOX_ADDR_0]] : (!fir.ref>) -> !fir.heap> +! CHECK: fir.freemem %[[CONVERT_0]] : !fir.heap> +! CHECK: acc.terminator +! CHECK: } + +! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_section_lb50.ub99_ref_100xf32 : !fir.ref> init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! 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>, index, index, index, !fir.shape<1>) -> !fir.ref> +! CHECK: %[[CONSTANT_10:.*]] = arith.constant 1 : index +! CHECK: %[[CONSTANT_11:.*]] = arith.constant 100 : index +! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[ALLOCA_0]] : (!fir.ref>) -> !fir.ref> +! 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.shapeshift<1>, index) -> !fir.ref +! CHECK: %[[CONVERT_1:.*]] = fir.convert %[[ARRAY_COOR_0]] : (!fir.ref) -> !fir.ref> +! CHECK: acc.yield %[[CONVERT_1]] : !fir.ref> + +! CHECK-LABEL: } copy { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): +! 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>, index, index, index, !fir.shape<1>) -> !fir.ref> +! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_1]] (%[[CONSTANT_8]]:%[[CONSTANT_9]]:%[[CONSTANT_0]]) shape %[[SHAPE_0]] : (!fir.ref>, index, index, index, !fir.shape<1>) -> !fir.ref> +! CHECK: hlfir.assign %[[DESIGNATE_0]] to %[[DESIGNATE_1]] temporary_lhs : !fir.ref>, !fir.ref> +! CHECK: acc.terminator +! CHECK: } + +! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_100xf32 : !fir.ref> init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! 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> + +! CHECK-LABEL: } copy { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): +! CHECK: hlfir.assign %[[VAL_0]] to %[[VAL_1]] temporary_lhs : !fir.ref>, !fir.ref> +! CHECK: acc.terminator +! CHECK: } + +! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_i32 : !fir.ref init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref): +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 {bindc_name = "acc.private.init"} +! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref + +! CHECK-LABEL: } copy { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref, %[[VAL_1:.*]]: !fir.ref): +! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_0]] : !fir.ref +! CHECK: hlfir.assign %[[LOAD_0]] to %[[VAL_1]] temporary_lhs : i32, !fir.ref +! CHECK: acc.terminator +! CHECK: } + +! CHECK-LABEL: acc.private.recipe @privatization_section_lb0.ub49_ref_100xf32 : !fir.ref> init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! 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>, index, index, index, !fir.shape<1>) -> !fir.ref> +! CHECK: %[[CONSTANT_9:.*]] = arith.constant 1 : index +! CHECK: %[[CONSTANT_10:.*]] = arith.constant 100 : index +! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[ALLOCA_0]] : (!fir.ref>) -> !fir.ref> +! 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.shapeshift<1>, index) -> !fir.ref +! CHECK: %[[CONVERT_1:.*]] = fir.convert %[[ARRAY_COOR_0]] : (!fir.ref) -> !fir.ref> +! CHECK: acc.yield %[[CONVERT_1]] : !fir.ref> +! CHECK: } + +! CHECK-LABEL: acc.private.recipe @privatization_ref_100xf32 : !fir.ref> init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! 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> +! CHECK: } + +! CHECK-LABEL: acc.private.recipe @privatization_ref_i32 : !fir.ref init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref): +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 {bindc_name = "acc.private.init"} +! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref +! 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>) bounds(%[[BOUND]]) recipe(@privatization_ref_50xf32) -> !fir.ref> {name = "b(1:50)"} -! CHECK: acc.loop private(%[[B_PRIVATE]]{{.*}} : !fir.ref>{{.*}}) +! CHECK: %[[B_PRIVATE:.*]] = acc.private varPtr(%[[DECLB]]#0 : !fir.ref>) bounds(%[[BOUND]]) recipe(@privatization_section_lb0.ub49_ref_100xf32) -> !fir.ref> {name = "b(1:50)"} +! CHECK: acc.loop private(%[[B_PRIVATE]]{{.*}} : !fir.ref>{{.*}}) !$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>) bounds(%[[BOUND]]) recipe(@firstprivatization_section_lb50.ub99_ref_50xf32) -> !fir.ref> {name = "b(51:100)"} -! CHECK: acc.parallel {{.*}} firstprivate(%[[FP_B]] : !fir.ref>) +! CHECK: %[[FP_B:.*]] = acc.firstprivate varPtr(%[[DECLB]]#0 : !fir.ref>) bounds(%[[BOUND]]) recipe(@firstprivatization_section_lb50.ub99_ref_100xf32) -> !fir.ref> {name = "b(51:100)"} +! CHECK: acc.parallel {{.*}} firstprivate(%[[FP_B]] : !fir.ref>) end program diff --git a/flang/test/Lower/OpenACC/acc-reduction.f90 b/flang/test/Lower/OpenACC/acc-reduction.f90 index 940332b96e3f..1981b01aa45d 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>, 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, %[[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.shape<2>) -> (!fir.box>, !fir.heap>) -! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : f32, !fir.box> -! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.box> +! 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, %[[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.shape<2>) -> !fir.box> +! CHECK: %[[CONSTANT_3:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_2:.*]]:3 = fir.box_dims %[[EMBOX_0]], %[[CONSTANT_3]] : (!fir.box>, 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>, 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>, index, index) -> !fir.ref +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_0]] temporary_lhs : f32, !fir.ref +! CHECK: } +! CHECK: } +! CHECK: %[[CONSTANT_6:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_4:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_6]] : (!fir.box>, 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>, 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>, 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>, 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.shapeshift<2>) -> !fir.box> +! CHECK: acc.yield %[[EMBOX_1]] : !fir.box> ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box>, %[[VAL_1:.*]]: !fir.box>): @@ -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>>, index) -> (index, index, index) ! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[BOX_DIMS_0]]#1 : (index) -> !fir.shape<1> -! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array, %[[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.shape<1>) -> (!fir.box>, !fir.heap>) +! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[BOX_DIMS_0]]#1 : (index) -> !fir.shape<1> +! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array, %[[BOX_DIMS_0]]#1 {bindc_name = "acc.reduction.init", uniq_name = ""} +! CHECK: %[[EMBOX_0:.*]] = fir.embox %[[ALLOCMEM_0]](%[[SHAPE_1]]) : (!fir.heap>, !fir.shape<1>) -> !fir.box> +! CHECK: %[[CONSTANT_2:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_1:.*]]:3 = fir.box_dims %[[EMBOX_0]], %[[CONSTANT_2]] : (!fir.box>, 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>, index) -> !fir.ref +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_0]] temporary_lhs : f32, !fir.ref +! CHECK: } +! CHECK: %[[CONSTANT_4:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_2:.*]]:3 = fir.box_dims %[[LOAD_0]], %[[CONSTANT_4]] : (!fir.box>>, 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>>, 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.shapeshift<1>) -> !fir.box>> ! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.box>> -! CHECK: %[[DECLARE_1:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref>>>) -> (!fir.ref>>>, !fir.ref>>>) -! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[DECLARE_1]]#0 : (!fir.ref>>>) -> !fir.ref>> -! CHECK: fir.store %[[DECLARE_0]]#0 to %[[CONVERT_0]] : !fir.ref>> -! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DECLARE_1]]#0 : f32, !fir.ref>>> -! CHECK: acc.yield %[[DECLARE_1]]#0 : !fir.ref>>> +! CHECK: fir.store %[[EMBOX_1]] to %[[ALLOCA_0]] : !fir.ref>>> +! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref>>> ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>>>, %[[VAL_1:.*]]: !fir.ref>>>): @@ -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>>, index) -> (index, index, index) ! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[BOX_DIMS_0]]#1 : (index) -> !fir.shape<1> -! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array, %[[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.shape<1>) -> (!fir.box>, !fir.heap>) +! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[BOX_DIMS_0]]#1 : (index) -> !fir.shape<1> +! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array, %[[BOX_DIMS_0]]#1 {bindc_name = "acc.reduction.init", uniq_name = ""} +! CHECK: %[[EMBOX_0:.*]] = fir.embox %[[ALLOCMEM_0]](%[[SHAPE_1]]) : (!fir.heap>, !fir.shape<1>) -> !fir.box> +! CHECK: %[[CONSTANT_2:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_1:.*]]:3 = fir.box_dims %[[EMBOX_0]], %[[CONSTANT_2]] : (!fir.box>, 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>, index) -> !fir.ref +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_0]] temporary_lhs : f32, !fir.ref +! CHECK: } +! CHECK: %[[CONSTANT_4:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_2:.*]]:3 = fir.box_dims %[[LOAD_0]], %[[CONSTANT_4]] : (!fir.box>>, 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>>, 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.shapeshift<1>) -> !fir.box>> ! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.box>> -! CHECK: %[[DECLARE_1:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref>>>) -> (!fir.ref>>>, !fir.ref>>>) -! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[DECLARE_1]]#0 : (!fir.ref>>>) -> !fir.ref>> -! CHECK: fir.store %[[DECLARE_0]]#0 to %[[CONVERT_0]] : !fir.ref>> -! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DECLARE_1]]#0 : f32, !fir.ref>>> -! CHECK: acc.yield %[[DECLARE_1]]#0 : !fir.ref>>> +! CHECK: fir.store %[[EMBOX_1]] to %[[ALLOCA_0]] : !fir.ref>>> +! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref>>> ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>>>, %[[VAL_1:.*]]: !fir.ref>>>): @@ -182,52 +228,71 @@ ! CHECK-LABEL: acc.reduction.recipe @reduction_add_section_lb1.ub3_box_Uxi32 : !fir.box> reduction_operator init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box>): +! 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>, index) -> (index, index, index) -! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[BOX_DIMS_0]]#1 : (index) -> !fir.shape<1> -! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array, %[[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.shape<1>) -> (!fir.box>, !fir.heap>) -! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : i32, !fir.box> -! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.box> +! 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>, 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>, index, index, index, !fir.shape<1>) -> !fir.box> +! 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>, index) -> !fir.ref +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_1]] temporary_lhs : i32, !fir.ref +! CHECK: } +! CHECK: %[[CONSTANT_11:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_1:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_11]] : (!fir.box>, 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>, index) -> (index, index, index) +! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[ALLOCA_0]] : (!fir.ref>) -> !fir.ref> +! 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.shapeshift<1>, index) -> !fir.ref +! CHECK: %[[CONVERT_1:.*]] = fir.convert %[[ARRAY_COOR_0]] : (!fir.ref) -> !fir.ref> +! 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.shapeshift<1>) -> !fir.box> +! CHECK: acc.yield %[[EMBOX_0]] : !fir.box> ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box>, %[[VAL_1:.*]]: !fir.box>): ! 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>, 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>, 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>, index, index, index, !fir.shape<1>) -> !fir.box> -! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%[[LB_LHS]]:%[[UB_LHS]]:%c1{{.*}}) shape %[[SHAPE_0]] : (!fir.box>, index, index, index, !fir.shape<1>) -> !fir.box> -! 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>, index) -> !fir.ref +! 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>, 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>, 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>, index, index, index, !fir.shape<1>) -> !fir.box> +! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%[[ADDI_0]]:%[[ADDI_1]]:%[[CONSTANT_0]]) shape %[[SHAPE_0]] : (!fir.box>, index, index, index, !fir.shape<1>) -> !fir.box> +! 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>, index) -> !fir.ref ! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_2]] : !fir.ref -! CHECK: %[[DESIGNATE_3:.*]] = hlfir.designate %[[DESIGNATE_1]] (%[[VAL_2]]) : (!fir.box>, index) -> !fir.ref +! CHECK: %[[DESIGNATE_3:.*]] = hlfir.designate %[[DESIGNATE_1]] (%[[VAL_2]]) : (!fir.box>, index) -> !fir.ref ! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_3]] : !fir.ref -! CHECK: %[[ADDI_1:.*]] = arith.addi %[[LOAD_1]], %[[LOAD_0]] : i32 -! CHECK: hlfir.assign %[[ADDI_1]] to %[[DESIGNATE_3]] : i32, !fir.ref +! CHECK: %[[ADDI_4:.*]] = arith.addi %[[LOAD_1]], %[[LOAD_0]] : i32 +! CHECK: hlfir.assign %[[ADDI_4]] to %[[DESIGNATE_3]] : i32, !fir.ref ! CHECK: } ! CHECK: acc.yield %[[VAL_0]] : !fir.box> - -! CHECK-LABEL: } destroy { -! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box>, %[[VAL_1:.*]]: !fir.box>): -! CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>) -> !fir.ref> -! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[BOX_ADDR_0]] : (!fir.ref>) -> !fir.heap> -! CHECK: fir.freemem %[[CONVERT_0]] : !fir.heap> -! CHECK: acc.terminator ! CHECK: } ! CHECK-LABEL: acc.reduction.recipe @reduction_max_box_Uxf32 : !fir.box> reduction_operator 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>, index) -> (index, index, index) ! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[BOX_DIMS_0]]#1 : (index) -> !fir.shape<1> -! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array, %[[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.shape<1>) -> (!fir.box>, !fir.heap>) -! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : f32, !fir.box> -! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.box> +! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[BOX_DIMS_0]]#1 : (index) -> !fir.shape<1> +! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array, %[[BOX_DIMS_0]]#1 {bindc_name = "acc.reduction.init", uniq_name = ""} +! CHECK: %[[EMBOX_0:.*]] = fir.embox %[[ALLOCMEM_0]](%[[SHAPE_1]]) : (!fir.heap>, !fir.shape<1>) -> !fir.box> +! CHECK: %[[CONSTANT_2:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_1:.*]]:3 = fir.box_dims %[[EMBOX_0]], %[[CONSTANT_2]] : (!fir.box>, 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>, index) -> !fir.ref +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_0]] temporary_lhs : f32, !fir.ref +! CHECK: } +! CHECK: %[[CONSTANT_4:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_2:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_4]] : (!fir.box>, 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>, 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.shapeshift<1>) -> !fir.box> +! CHECK: acc.yield %[[EMBOX_1]] : !fir.box> ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box>, %[[VAL_1:.*]]: !fir.box>): @@ -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>, index) -> (index, index, index) ! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[BOX_DIMS_0]]#1 : (index) -> !fir.shape<1> -! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array, %[[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.shape<1>) -> (!fir.box>, !fir.heap>) -! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : i32, !fir.box> -! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.box> +! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[BOX_DIMS_0]]#1 : (index) -> !fir.shape<1> +! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array, %[[BOX_DIMS_0]]#1 {bindc_name = "acc.reduction.init", uniq_name = ""} +! CHECK: %[[EMBOX_0:.*]] = fir.embox %[[ALLOCMEM_0]](%[[SHAPE_1]]) : (!fir.heap>, !fir.shape<1>) -> !fir.box> +! CHECK: %[[CONSTANT_2:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_1:.*]]:3 = fir.box_dims %[[EMBOX_0]], %[[CONSTANT_2]] : (!fir.box>, 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>, index) -> !fir.ref +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_0]] temporary_lhs : i32, !fir.ref +! CHECK: } +! CHECK: %[[CONSTANT_4:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_2:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_4]] : (!fir.box>, 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>, 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.shapeshift<1>) -> !fir.box> +! CHECK: acc.yield %[[EMBOX_1]] : !fir.box> ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box>, %[[VAL_1:.*]]: !fir.box>): @@ -329,58 +422,78 @@ ! CHECK-LABEL: acc.reduction.recipe @reduction_add_section_lb0.ub9xlb0.ub19_ref_10x20xi32 : !fir.ref> reduction_operator init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! 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.shape<2>) -> (!fir.ref>, !fir.ref>) -! 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>, index, index) -> !fir.ref -! CHECK: fir.store %[[CONSTANT_0]] to %[[COORDINATE_OF_0]] : !fir.ref +! 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>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.ref> +! 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>, index, index) -> !fir.ref +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_1]] temporary_lhs : i32, !fir.ref ! CHECK: } ! CHECK: } -! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref> +! 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.shapeshift<2>, index, index) -> !fir.ref +! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[ARRAY_COOR_0]] : (!fir.ref) -> !fir.ref> +! CHECK: acc.yield %[[CONVERT_0]] : !fir.ref> ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): -! 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>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.ref> -! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%c1{{.*}}:%c10{{.*}}:%c1{{.*}}, %c1{{.*}}:%c20{{.*}}:%c1{{.*}}) shape %[[SHAPE_0]] : (!fir.ref>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.ref> -! 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>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.ref> +! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%[[CONSTANT_12]]:%[[CONSTANT_13]]:%[[CONSTANT_0]], %[[CONSTANT_15]]:%[[CONSTANT_16]]:%[[CONSTANT_0]]) shape %[[SHAPE_0]] : (!fir.ref>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.ref> +! 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>, index, index) -> !fir.ref ! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_2]] : !fir.ref ! CHECK: %[[DESIGNATE_3:.*]] = hlfir.designate %[[DESIGNATE_1]] (%[[VAL_3]], %[[VAL_2]]) : (!fir.ref>, index, index) -> !fir.ref ! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_3]] : !fir.ref -! CHECK: %[[ADDI_2:.*]] = arith.addi %[[LOAD_1]], %[[LOAD_0]] : i32 -! CHECK: hlfir.assign %[[ADDI_2]] to %[[DESIGNATE_3]] : i32, !fir.ref +! CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_1]], %[[LOAD_0]] : i32 +! CHECK: hlfir.assign %[[ADDI_0]] to %[[DESIGNATE_3]] : i32, !fir.ref ! CHECK: } ! CHECK: } ! CHECK: acc.yield %[[VAL_0]] : !fir.ref> @@ -388,42 +501,59 @@ ! CHECK-LABEL: acc.reduction.recipe @reduction_add_section_lb10.ub19_ref_100xi32 : !fir.ref> reduction_operator init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! 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.shape<1>) -> (!fir.ref>, !fir.ref>) -! 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>, index) -> !fir.ref -! CHECK: fir.store %[[CONSTANT_0]] to %[[COORDINATE_OF_0]] : !fir.ref +! 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>, index, index, index, !fir.shape<1>) -> !fir.ref> +! 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>, index) -> !fir.ref +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_1]] temporary_lhs : i32, !fir.ref ! CHECK: } -! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref> +! CHECK: %[[CONSTANT_13:.*]] = arith.constant 1 : index +! CHECK: %[[CONSTANT_14:.*]] = arith.constant 100 : index +! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[ALLOCA_0]] : (!fir.ref>) -> !fir.ref> +! 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.shapeshift<1>, index) -> !fir.ref +! CHECK: %[[CONVERT_1:.*]] = fir.convert %[[ARRAY_COOR_0]] : (!fir.ref) -> !fir.ref> +! CHECK: acc.yield %[[CONVERT_1]] : !fir.ref> ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): -! 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>, index, index, index, !fir.shape<1>) -> !fir.ref> -! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%c11{{.*}}:%c20{{.*}}:%c1{{.*}}) shape %[[SHAPE_0]] : (!fir.ref>, index, index, index, !fir.shape<1>) -> !fir.ref> -! 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>, index) -> !fir.ref +! 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>, index, index, index, !fir.shape<1>) -> !fir.ref> +! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%[[CONSTANT_8]]:%[[CONSTANT_9]]:%[[CONSTANT_0]]) shape %[[SHAPE_0]] : (!fir.ref>, index, index, index, !fir.shape<1>) -> !fir.ref> +! 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>, index) -> !fir.ref ! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_2]] : !fir.ref -! CHECK: %[[DESIGNATE_3:.*]] = hlfir.designate %[[DESIGNATE_1]] (%[[VAL_2]]) : (!fir.ref>, index) -> !fir.ref +! CHECK: %[[DESIGNATE_3:.*]] = hlfir.designate %[[DESIGNATE_1]] (%[[VAL_2]]) : (!fir.ref>, index) -> !fir.ref ! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_3]] : !fir.ref -! CHECK: %[[ADDI_1:.*]] = arith.addi %[[LOAD_1]], %[[LOAD_0]] : i32 -! CHECK: hlfir.assign %[[ADDI_1]] to %[[DESIGNATE_3]] : i32, !fir.ref +! CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_1]], %[[LOAD_0]] : i32 +! CHECK: hlfir.assign %[[ADDI_0]] to %[[DESIGNATE_3]] : i32, !fir.ref ! CHECK: } ! CHECK: acc.yield %[[VAL_0]] : !fir.ref> ! CHECK: } @@ -431,13 +561,14 @@ ! CHECK-LABEL: acc.reduction.recipe @reduction_add_ref_box_ptr_i32 : !fir.ref>> reduction_operator init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>>): ! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : i32 -! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.box> -! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref>>) -> (!fir.ref>>, !fir.ref>>) -! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem i32 +! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_0]] : !fir.ref>> +! CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_0]] : (!fir.box>) -> !fir.ptr +! 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 ! CHECK: %[[EMBOX_0:.*]] = fir.embox %[[ALLOCMEM_0]] : (!fir.heap) -> !fir.box> -! CHECK: fir.store %[[EMBOX_0]] to %[[DECLARE_0]]#0 : !fir.ref>> -! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : i32, !fir.ref>> -! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref>> +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.box> +! CHECK: fir.store %[[EMBOX_0]] to %[[ALLOCA_0]] : !fir.ref>> +! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref>> ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>>, %[[VAL_1:.*]]: !fir.ref>>): @@ -463,13 +594,14 @@ ! CHECK-LABEL: acc.reduction.recipe @reduction_add_ref_box_heap_i32 : !fir.ref>> reduction_operator init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>>): ! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : i32 -! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.box> -! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref>>) -> (!fir.ref>>, !fir.ref>>) -! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem i32 +! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_0]] : !fir.ref>> +! CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_0]] : (!fir.box>) -> !fir.heap +! 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 ! CHECK: %[[EMBOX_0:.*]] = fir.embox %[[ALLOCMEM_0]] : (!fir.heap) -> !fir.box> -! CHECK: fir.store %[[EMBOX_0]] to %[[DECLARE_0]]#0 : !fir.ref>> -! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : i32, !fir.ref>> -! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref>> +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.box> +! CHECK: fir.store %[[EMBOX_0]] to %[[ALLOCA_0]] : !fir.ref>> +! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref>> ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>>, %[[VAL_1:.*]]: !fir.ref>>): @@ -493,15 +625,14 @@ ! CHECK-LABEL: acc.reduction.recipe @reduction_mul_ref_z32 : !fir.ref> reduction_operator init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca complex {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 ! CHECK: %[[INSERT_VALUE_0:.*]] = fir.insert_value %[[UNDEFINED_0]], %[[CONSTANT_0]], [0 : index] : (complex, f32) -> complex ! CHECK: %[[INSERT_VALUE_1:.*]] = fir.insert_value %[[INSERT_VALUE_0]], %[[CONSTANT_1]], [1 : index] : (complex, f32) -> complex -! CHECK: %[[ALLOCA_0:.*]] = fir.alloca complex -! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) -! CHECK: fir.store %[[INSERT_VALUE_1]] to %[[DECLARE_0]]#0 : !fir.ref> -! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref> +! CHECK: hlfir.assign %[[INSERT_VALUE_1]] to %[[ALLOCA_0]] temporary_lhs : complex, !fir.ref> +! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref> ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): @@ -514,15 +645,14 @@ ! CHECK-LABEL: acc.reduction.recipe @reduction_add_ref_z32 : !fir.ref> reduction_operator init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca complex {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 ! CHECK: %[[INSERT_VALUE_0:.*]] = fir.insert_value %[[UNDEFINED_0]], %[[CONSTANT_0]], [0 : index] : (complex, f32) -> complex ! CHECK: %[[INSERT_VALUE_1:.*]] = fir.insert_value %[[INSERT_VALUE_0]], %[[CONSTANT_1]], [1 : index] : (complex, f32) -> complex -! CHECK: %[[ALLOCA_0:.*]] = fir.alloca complex -! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) -! CHECK: fir.store %[[INSERT_VALUE_1]] to %[[DECLARE_0]]#0 : !fir.ref> -! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref> +! CHECK: hlfir.assign %[[INSERT_VALUE_1]] to %[[ALLOCA_0]] temporary_lhs : complex, !fir.ref> +! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref> ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): @@ -535,12 +665,10 @@ ! CHECK-LABEL: acc.reduction.recipe @reduction_neqv_ref_l32 : !fir.ref> reduction_operator init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! 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.ref>, !fir.ref>) -! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[CONSTANT_0]] : (i1) -> !fir.logical<4> -! CHECK: fir.store %[[CONVERT_0]] to %[[DECLARE_0]]#0 : !fir.ref> -! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref> +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[ALLOCA_0]] temporary_lhs : i1, !fir.ref> +! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref> ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): @@ -556,12 +684,10 @@ ! CHECK-LABEL: acc.reduction.recipe @reduction_eqv_ref_l32 : !fir.ref> reduction_operator init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! 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.ref>, !fir.ref>) -! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[CONSTANT_0]] : (i1) -> !fir.logical<4> -! CHECK: fir.store %[[CONVERT_0]] to %[[DECLARE_0]]#0 : !fir.ref> -! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref> +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[ALLOCA_0]] temporary_lhs : i1, !fir.ref> +! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref> ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): @@ -577,12 +703,10 @@ ! CHECK-LABEL: acc.reduction.recipe @reduction_lor_ref_l32 : !fir.ref> reduction_operator init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! 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.ref>, !fir.ref>) -! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[CONSTANT_0]] : (i1) -> !fir.logical<4> -! CHECK: fir.store %[[CONVERT_0]] to %[[DECLARE_0]]#0 : !fir.ref> -! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref> +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[ALLOCA_0]] temporary_lhs : i1, !fir.ref> +! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref> ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): @@ -598,12 +722,10 @@ ! CHECK-LABEL: acc.reduction.recipe @reduction_land_ref_l32 : !fir.ref> reduction_operator init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! 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.ref>, !fir.ref>) -! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[CONSTANT_0]] : (i1) -> !fir.logical<4> -! CHECK: fir.store %[[CONVERT_0]] to %[[DECLARE_0]]#0 : !fir.ref> -! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref> +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[ALLOCA_0]] temporary_lhs : i1, !fir.ref> +! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref> ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): @@ -619,11 +741,10 @@ ! CHECK-LABEL: acc.reduction.recipe @reduction_xor_ref_i32 : !fir.ref reduction_operator init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref): +! 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) -> (!fir.ref, !fir.ref) -! CHECK: fir.store %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : !fir.ref -! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[ALLOCA_0]] temporary_lhs : i32, !fir.ref +! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref, %[[VAL_1:.*]]: !fir.ref): @@ -636,11 +757,10 @@ ! CHECK-LABEL: acc.reduction.recipe @reduction_ior_ref_i32 : !fir.ref reduction_operator init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref): +! 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) -> (!fir.ref, !fir.ref) -! CHECK: fir.store %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : !fir.ref -! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[ALLOCA_0]] temporary_lhs : i32, !fir.ref +! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref, %[[VAL_1:.*]]: !fir.ref): @@ -653,11 +773,10 @@ ! CHECK-LABEL: acc.reduction.recipe @reduction_iand_ref_i32 : !fir.ref reduction_operator init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref): +! 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) -> (!fir.ref, !fir.ref) -! CHECK: fir.store %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : !fir.ref -! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[ALLOCA_0]] temporary_lhs : i32, !fir.ref +! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref, %[[VAL_1:.*]]: !fir.ref): @@ -670,19 +789,19 @@ ! CHECK-LABEL: acc.reduction.recipe @reduction_max_ref_100xf32 : !fir.ref> reduction_operator init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! 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.shape<1>) -> (!fir.ref>, !fir.ref>) -! 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>, index) -> !fir.ref -! CHECK: fir.store %[[CONSTANT_0]] to %[[COORDINATE_OF_0]] : !fir.ref +! 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>, index) -> !fir.ref +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_0]] temporary_lhs : f32, !fir.ref ! CHECK: } -! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref> +! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref> ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): @@ -705,11 +824,10 @@ ! CHECK-LABEL: acc.reduction.recipe @reduction_max_ref_f32 : !fir.ref reduction_operator init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref): +! 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) -> (!fir.ref, !fir.ref) -! CHECK: fir.store %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : !fir.ref -! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[ALLOCA_0]] temporary_lhs : f32, !fir.ref +! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref, %[[VAL_1:.*]]: !fir.ref): @@ -723,25 +841,23 @@ ! CHECK-LABEL: acc.reduction.recipe @reduction_max_ref_100x10xi32 : !fir.ref> reduction_operator init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! 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.shape<2>) -> (!fir.ref>, !fir.ref>) -! 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>, index, index) -> !fir.ref -! CHECK: fir.store %[[CONSTANT_0]] to %[[COORDINATE_OF_0]] : !fir.ref +! 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>, index, index) -> !fir.ref +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_0]] temporary_lhs : i32, !fir.ref ! CHECK: } ! CHECK: } -! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref> +! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref> ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): @@ -768,11 +884,10 @@ ! CHECK-LABEL: acc.reduction.recipe @reduction_max_ref_i32 : !fir.ref reduction_operator init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref): +! 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) -> (!fir.ref, !fir.ref) -! CHECK: fir.store %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : !fir.ref -! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[ALLOCA_0]] temporary_lhs : i32, !fir.ref +! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref, %[[VAL_1:.*]]: !fir.ref): @@ -786,25 +901,23 @@ ! CHECK-LABEL: acc.reduction.recipe @reduction_min_ref_100x10xf32 : !fir.ref> reduction_operator init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! 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.shape<2>) -> (!fir.ref>, !fir.ref>) -! 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>, index, index) -> !fir.ref -! CHECK: fir.store %[[CONSTANT_0]] to %[[COORDINATE_OF_0]] : !fir.ref +! 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>, index, index) -> !fir.ref +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_0]] temporary_lhs : f32, !fir.ref ! CHECK: } ! CHECK: } -! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref> +! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref> ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): @@ -831,11 +944,10 @@ ! CHECK-LABEL: acc.reduction.recipe @reduction_min_ref_f32 : !fir.ref reduction_operator init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref): +! 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) -> (!fir.ref, !fir.ref) -! CHECK: fir.store %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : !fir.ref -! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[ALLOCA_0]] temporary_lhs : f32, !fir.ref +! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref, %[[VAL_1:.*]]: !fir.ref): @@ -849,19 +961,19 @@ ! CHECK-LABEL: acc.reduction.recipe @reduction_min_ref_100xi32 : !fir.ref> reduction_operator init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! 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.shape<1>) -> (!fir.ref>, !fir.ref>) -! 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>, index) -> !fir.ref -! CHECK: fir.store %[[CONSTANT_0]] to %[[COORDINATE_OF_0]] : !fir.ref +! 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>, index) -> !fir.ref +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_0]] temporary_lhs : i32, !fir.ref ! CHECK: } -! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref> +! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref> ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): @@ -884,11 +996,10 @@ ! CHECK-LABEL: acc.reduction.recipe @reduction_min_ref_i32 : !fir.ref reduction_operator init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref): +! 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) -> (!fir.ref, !fir.ref) -! CHECK: fir.store %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : !fir.ref -! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[ALLOCA_0]] temporary_lhs : i32, !fir.ref +! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref, %[[VAL_1:.*]]: !fir.ref): @@ -902,19 +1013,19 @@ ! CHECK-LABEL: acc.reduction.recipe @reduction_mul_ref_100xf32 : !fir.ref> reduction_operator init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! 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.shape<1>) -> (!fir.ref>, !fir.ref>) -! 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>, index) -> !fir.ref -! CHECK: fir.store %[[CONSTANT_0]] to %[[COORDINATE_OF_0]] : !fir.ref +! 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>, index) -> !fir.ref +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_0]] temporary_lhs : f32, !fir.ref ! CHECK: } -! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref> +! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref> ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): @@ -936,11 +1047,10 @@ ! CHECK-LABEL: acc.reduction.recipe @reduction_mul_ref_f32 : !fir.ref reduction_operator init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref): +! 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) -> (!fir.ref, !fir.ref) -! CHECK: fir.store %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : !fir.ref -! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[ALLOCA_0]] temporary_lhs : f32, !fir.ref +! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref, %[[VAL_1:.*]]: !fir.ref): @@ -953,19 +1063,19 @@ ! CHECK-LABEL: acc.reduction.recipe @reduction_mul_ref_100xi32 : !fir.ref> reduction_operator init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! 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.shape<1>) -> (!fir.ref>, !fir.ref>) -! 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>, index) -> !fir.ref -! CHECK: fir.store %[[CONSTANT_0]] to %[[COORDINATE_OF_0]] : !fir.ref +! 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>, index) -> !fir.ref +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_0]] temporary_lhs : i32, !fir.ref ! CHECK: } -! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref> +! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref> ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): @@ -987,11 +1097,10 @@ ! CHECK-LABEL: acc.reduction.recipe @reduction_mul_ref_i32 : !fir.ref reduction_operator init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref): +! 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) -> (!fir.ref, !fir.ref) -! CHECK: fir.store %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : !fir.ref -! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[ALLOCA_0]] temporary_lhs : i32, !fir.ref +! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref, %[[VAL_1:.*]]: !fir.ref): @@ -1004,19 +1113,19 @@ ! CHECK-LABEL: acc.reduction.recipe @reduction_add_ref_100xf32 : !fir.ref> reduction_operator init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! 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.shape<1>) -> (!fir.ref>, !fir.ref>) -! 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>, index) -> !fir.ref -! CHECK: fir.store %[[CONSTANT_0]] to %[[COORDINATE_OF_0]] : !fir.ref +! 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>, index) -> !fir.ref +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_0]] temporary_lhs : f32, !fir.ref ! CHECK: } -! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref> +! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref> ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): @@ -1038,11 +1147,10 @@ ! CHECK-LABEL: acc.reduction.recipe @reduction_add_ref_f32 : !fir.ref reduction_operator init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref): +! 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) -> (!fir.ref, !fir.ref) -! CHECK: fir.store %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : !fir.ref -! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[ALLOCA_0]] temporary_lhs : f32, !fir.ref +! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref, %[[VAL_1:.*]]: !fir.ref): @@ -1055,31 +1163,27 @@ ! CHECK-LABEL: acc.reduction.recipe @reduction_add_ref_100x10x2xi32 : !fir.ref> reduction_operator init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! 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.shape<3>) -> (!fir.ref>, !fir.ref>) -! 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>, index, index, index) -> !fir.ref -! CHECK: fir.store %[[CONSTANT_0]] to %[[COORDINATE_OF_0]] : !fir.ref +! 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>, index, index, index) -> !fir.ref +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_0]] temporary_lhs : i32, !fir.ref ! CHECK: } ! CHECK: } ! CHECK: } -! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref> +! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref> ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): @@ -1109,25 +1213,23 @@ ! CHECK-LABEL: acc.reduction.recipe @reduction_add_ref_100x10xi32 : !fir.ref> reduction_operator init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! 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.shape<2>) -> (!fir.ref>, !fir.ref>) -! 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>, index, index) -> !fir.ref -! CHECK: fir.store %[[CONSTANT_0]] to %[[COORDINATE_OF_0]] : !fir.ref +! 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>, index, index) -> !fir.ref +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_0]] temporary_lhs : i32, !fir.ref ! CHECK: } ! CHECK: } -! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref> +! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref> ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): @@ -1153,19 +1255,19 @@ ! CHECK-LABEL: acc.reduction.recipe @reduction_add_ref_100xi32 : !fir.ref> reduction_operator init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! 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.shape<1>) -> (!fir.ref>, !fir.ref>) -! 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>, index) -> !fir.ref -! CHECK: fir.store %[[CONSTANT_0]] to %[[COORDINATE_OF_0]] : !fir.ref +! 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>, index) -> !fir.ref +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_0]] temporary_lhs : i32, !fir.ref ! CHECK: } -! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref> +! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref> ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): @@ -1187,18 +1289,16 @@ ! CHECK-LABEL: acc.private.recipe @privatization_ref_i32 : !fir.ref init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref): -! CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 -! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.private.init"} : (!fir.ref) -> (!fir.ref, !fir.ref) -! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 {bindc_name = "acc.private.init"} +! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref ! CHECK: } ! CHECK-LABEL: acc.reduction.recipe @reduction_add_ref_i32 : !fir.ref reduction_operator init { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref): +! 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) -> (!fir.ref, !fir.ref) -! CHECK: fir.store %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : !fir.ref -! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[ALLOCA_0]] temporary_lhs : i32, !fir.ref +! CHECK: acc.yield %[[ALLOCA_0]] : !fir.ref ! CHECK-LABEL: } combiner { ! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref, %[[VAL_1:.*]]: !fir.ref): diff --git a/flang/test/Lower/OpenACC/acc-serial-loop.f90 b/flang/test/Lower/OpenACC/acc-serial-loop.f90 index b5bff6397edc..de070262a52f 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> init { ! CHECK: ^bb0(%{{.*}}: !fir.ref>): -! 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.shape<1>) -> (!fir.ref>, !fir.ref>) -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref> +! CHECK: acc.yield %[[ALLOCA]] : !fir.ref> ! CHECK: } ! CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_10xf32 : !fir.ref> init { ! CHECK: ^bb0(%{{.*}}: !fir.ref>): -! 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.shape<1>) -> (!fir.ref>, !fir.ref>) -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref> +! CHECK: acc.yield %[[ALLOCA]] : !fir.ref> ! CHECK: } copy { ! CHECK: ^bb0(%arg0: !fir.ref>, %arg1: !fir.ref>): ! CHECK: acc.terminator diff --git a/flang/test/Lower/OpenACC/acc-serial.f90 b/flang/test/Lower/OpenACC/acc-serial.f90 index a6d3528ee957..e46e9a928166 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> init { ! CHECK: ^bb0(%{{.*}}: !fir.ref>): -! 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.shape<2>) -> (!fir.ref>, !fir.ref>) -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref> +! CHECK: acc.yield %[[ALLOCA]] : !fir.ref> ! CHECK: } copy { ! CHECK: ^bb0(%arg0: !fir.ref>, %arg1: !fir.ref>): ! CHECK: acc.terminator @@ -15,9 +13,8 @@ ! CHECK-LABEL: acc.private.recipe @privatization_ref_10x10xf32 : !fir.ref> init { ! CHECK: ^bb0(%{{.*}}: !fir.ref>): -! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2> -! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.private.init"} : (!fir.ref>, !fir.shape<2>) -> (!fir.ref>, !fir.ref>) -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref> +! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<10x10xf32> +! CHECK: acc.yield %[[ALLOCA]] : !fir.ref> ! 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 3a3288a9cc2e..d1033d1b580f 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 init { // CHECK: ^bb0(%{{.*}}: !fir.ref): // CHECK: %[[ALLOC:.*]] = fir.alloca i32 -// CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOC]] -// CHECK: acc.yield %[[DECL]]#0 : !fir.ref +// CHECK: acc.yield %[[ALLOC]] : !fir.ref // CHECK: } copy { // CHECK: ^bb0(%[[SRC:.*]]: !fir.ref, %[[DST:.*]]: !fir.ref): // CHECK: %[[LOADED:.*]] = fir.load %[[SRC]] : !fir.ref @@ -35,8 +34,7 @@ func.func @test_i32_scalar_in_parallel() { // CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_i64 : !fir.ref init { // CHECK: ^bb0(%{{.*}}: !fir.ref): // CHECK: %[[ALLOC:.*]] = fir.alloca i64 -// CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOC]] -// CHECK: acc.yield %[[DECL]]#0 : !fir.ref +// CHECK: acc.yield %[[ALLOC]] : !fir.ref // CHECK: } copy { // CHECK: ^bb0(%[[SRC:.*]]: !fir.ref, %[[DST:.*]]: !fir.ref): // CHECK: %[[LOADED:.*]] = fir.load %[[SRC]] : !fir.ref @@ -62,8 +60,7 @@ func.func @test_i64_scalar_in_parallel() { // CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_f32 : !fir.ref init { // CHECK: ^bb0(%{{.*}}: !fir.ref): // CHECK: %[[ALLOC:.*]] = fir.alloca f32 -// CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOC]] -// CHECK: acc.yield %[[DECL]]#0 : !fir.ref +// CHECK: acc.yield %[[ALLOC]] : !fir.ref // CHECK: } copy { // CHECK: ^bb0(%[[SRC:.*]]: !fir.ref, %[[DST:.*]]: !fir.ref): // CHECK: %[[LOADED:.*]] = fir.load %[[SRC]] : !fir.ref @@ -89,8 +86,7 @@ func.func @test_f32_scalar_in_parallel() { // CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_f64 : !fir.ref init { // CHECK: ^bb0(%{{.*}}: !fir.ref): // CHECK: %[[ALLOC:.*]] = fir.alloca f64 -// CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOC]] -// CHECK: acc.yield %[[DECL]]#0 : !fir.ref +// CHECK: acc.yield %[[ALLOC]] : !fir.ref // CHECK: } copy { // CHECK: ^bb0(%[[SRC:.*]]: !fir.ref, %[[DST:.*]]: !fir.ref): // CHECK: %[[LOADED:.*]] = fir.load %[[SRC]] : !fir.ref @@ -116,8 +112,7 @@ func.func @test_f64_scalar_in_parallel() { // CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_l32 : !fir.ref> init { // CHECK: ^bb0(%{{.*}}: !fir.ref>): // CHECK: %[[ALLOC:.*]] = fir.alloca !fir.logical<4> -// CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOC]] -// CHECK: acc.yield %[[DECL]]#0 : !fir.ref> +// CHECK: acc.yield %[[ALLOC]] : !fir.ref> // CHECK: } copy { // CHECK: ^bb0(%[[SRC:.*]]: !fir.ref>, %[[DST:.*]]: !fir.ref>): // CHECK: %[[LOADED:.*]] = fir.load %[[SRC]] : !fir.ref> @@ -143,8 +138,7 @@ func.func @test_logical_scalar_in_parallel() { // CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_z32 : !fir.ref> init { // CHECK: ^bb0(%{{.*}}: !fir.ref>): // CHECK: %[[ALLOC:.*]] = fir.alloca complex -// CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOC]] -// CHECK: acc.yield %[[DECL]]#0 : !fir.ref> +// CHECK: acc.yield %[[ALLOC]] : !fir.ref> // CHECK: } copy { // CHECK: ^bb0(%[[SRC:.*]]: !fir.ref>, %[[DST:.*]]: !fir.ref>): // CHECK: %[[LOADED:.*]] = fir.load %[[SRC]] : !fir.ref> @@ -170,8 +164,7 @@ func.func @test_complex_scalar_in_parallel() { // CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_z64 : !fir.ref> init { // CHECK: ^bb0(%{{.*}}: !fir.ref>): // CHECK: %[[ALLOC:.*]] = fir.alloca complex -// CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOC]] -// CHECK: acc.yield %[[DECL]]#0 : !fir.ref> +// CHECK: acc.yield %[[ALLOC]] : !fir.ref> // CHECK: } copy { // CHECK: ^bb0(%[[SRC:.*]]: !fir.ref>, %[[DST:.*]]: !fir.ref>): // CHECK: %[[LOADED:.*]] = fir.load %[[SRC]] : !fir.ref> @@ -233,8 +226,7 @@ func.func @test_f64_scalar_in_serial() { // CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_i8 : !fir.ref init { // CHECK: ^bb0(%{{.*}}: !fir.ref): // CHECK: %[[ALLOC:.*]] = fir.alloca i8 -// CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOC]] -// CHECK: acc.yield %[[DECL]]#0 : !fir.ref +// CHECK: acc.yield %[[ALLOC]] : !fir.ref // CHECK: } copy { // CHECK: ^bb0(%[[SRC:.*]]: !fir.ref, %[[DST:.*]]: !fir.ref): // CHECK: %[[LOADED:.*]] = fir.load %[[SRC]] : !fir.ref @@ -260,8 +252,7 @@ func.func @test_i8_scalar_in_parallel() { // CHECK-LABEL: acc.firstprivate.recipe @firstprivatization_ref_i16 : !fir.ref init { // CHECK: ^bb0(%{{.*}}: !fir.ref): // CHECK: %[[ALLOC:.*]] = fir.alloca i16 -// CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOC]] -// CHECK: acc.yield %[[DECL]]#0 : !fir.ref +// CHECK: acc.yield %[[ALLOC]] : !fir.ref // CHECK: } copy { // CHECK: ^bb0(%[[SRC:.*]]: !fir.ref, %[[DST:.*]]: !fir.ref): // CHECK: %[[LOADED:.*]] = fir.load %[[SRC]] : !fir.ref diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCTypeInterfaces.td b/mlir/include/mlir/Dialect/OpenACC/OpenACCTypeInterfaces.td index 3f11bf6fbfce..1d55762e2f7d 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 66cba7f07adb..6872aa9d26e2 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>(destroyBlock->getArgument(1)); if (isa(varType)) { auto mappableTy = cast(varType); - if (!mappableTy.generatePrivateDestroy(builder, loc, varToFree)) + if (!mappableTy.generatePrivateDestroy(builder, loc, varToFree, bounds)) return failure(); } else { assert(isa(varType) && "Expected PointerLikeType");