diff --git a/flang/include/flang/Lower/AbstractConverter.h b/flang/include/flang/Lower/AbstractConverter.h index 0ffe27ea038e8..f8322a50effc4 100644 --- a/flang/include/flang/Lower/AbstractConverter.h +++ b/flang/include/flang/Lower/AbstractConverter.h @@ -123,6 +123,10 @@ class AbstractConverter { virtual Fortran::lower::SymMap::StorageDesc getSymbolStorage(SymbolRef sym) = 0; + /// Return the Symbol Map used to map semantics::Symbol to their SSA + /// values in the generated MLIR. + virtual Fortran::lower::SymMap &getSymbolMap() = 0; + /// Override lowering of expression with pre-lowered values. /// Associate mlir::Value to evaluate::Expr. All subsequent call to /// genExprXXX() will replace any occurrence of an overridden diff --git a/flang/include/flang/Optimizer/HLFIR/HLFIROps.td b/flang/include/flang/Optimizer/HLFIR/HLFIROps.td index 218435a44c24f..b7563a2f752f0 100644 --- a/flang/include/flang/Optimizer/HLFIR/HLFIROps.td +++ b/flang/include/flang/Optimizer/HLFIR/HLFIROps.td @@ -73,6 +73,10 @@ def hlfir_DeclareOp local lower bound values. It is intended to be used when generating FIR from HLFIR in order to avoid descriptor creation for simple entities. + The attribute skip_rebox can be set to indicate that the second and first + result are known to be the same descriptors (the input descriptor is known + to already have the correct attributes and lower bounds). + Example: CHARACTER(n) :: c(10:n, 20:n) @@ -98,7 +102,8 @@ def hlfir_DeclareOp DefaultValuedAttr:$storage_offset, Builtin_StringAttr:$uniq_name, OptionalAttr:$fortran_attrs, - OptionalAttr:$data_attr); + OptionalAttr:$data_attr, + OptionalAttr:$skip_rebox); let results = (outs AnyFortranVariable, AnyRefOrBoxLike); @@ -106,6 +111,7 @@ def hlfir_DeclareOp $memref (`(` $shape^ `)`)? (`typeparams` $typeparams^)? (`dummy_scope` $dummy_scope^)? (`storage` `(` $storage^ `[` $storage_offset `]` `)`)? + (`skip_rebox` $skip_rebox^)? attr-dict `:` functional-type(operands, results) }]; diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp index 780d56f085f69..3a022e188bbdd 100644 --- a/flang/lib/Lower/Bridge.cpp +++ b/flang/lib/Lower/Bridge.cpp @@ -643,6 +643,8 @@ class FirConverter : public Fortran::lower::AbstractConverter { return localSymbols.lookupStorage(sym); } + Fortran::lower::SymMap &getSymbolMap() override final { return localSymbols; } + void overrideExprValues(const Fortran::lower::ExprToValueMap *map) override final { exprValueOverrides = map; diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp index 4a9e49435a907..742f58f3645bf 100644 --- a/flang/lib/Lower/OpenACC.cpp +++ b/flang/lib/Lower/OpenACC.cpp @@ -20,6 +20,7 @@ #include "flang/Lower/PFTBuilder.h" #include "flang/Lower/StatementContext.h" #include "flang/Lower/Support/Utils.h" +#include "flang/Lower/SymbolMap.h" #include "flang/Optimizer/Builder/BoxValue.h" #include "flang/Optimizer/Builder/Complex.h" #include "flang/Optimizer/Builder/FIRBuilder.h" @@ -33,6 +34,7 @@ #include "flang/Semantics/scope.h" #include "flang/Semantics/tools.h" #include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.h" +#include "mlir/IR/IRMapping.h" #include "mlir/IR/MLIRContext.h" #include "mlir/Support/LLVM.h" #include "llvm/ADT/STLExtras.h" @@ -60,6 +62,16 @@ static llvm::cl::opt lowerDoLoopToAccLoop( llvm::cl::desc("Whether to lower do loops as `acc.loop` operations."), llvm::cl::init(true)); +static llvm::cl::opt enableSymbolRemapping( + "openacc-remap-symbols", + llvm::cl::desc("Whether to remap symbols that appears in data clauses."), + llvm::cl::init(true)); + +static llvm::cl::opt enableDevicePtrRemap( + "openacc-remap-device-ptr-symbols", + llvm::cl::desc("sub-option of openacc-remap-symbols for deviceptr clause"), + llvm::cl::init(false)); + // Special value for * passed in device_type or gang clauses. static constexpr std::int64_t starCst = -1; @@ -624,17 +636,19 @@ void genAtomicCapture(Fortran::lower::AbstractConverter &converter, } template -static void -genDataOperandOperations(const Fortran::parser::AccObjectList &objectList, - Fortran::lower::AbstractConverter &converter, - Fortran::semantics::SemanticsContext &semanticsContext, - Fortran::lower::StatementContext &stmtCtx, - llvm::SmallVectorImpl &dataOperands, - mlir::acc::DataClause dataClause, bool structured, - bool implicit, llvm::ArrayRef async, - llvm::ArrayRef asyncDeviceTypes, - llvm::ArrayRef asyncOnlyDeviceTypes, - bool setDeclareAttr = false) { +static void genDataOperandOperations( + const Fortran::parser::AccObjectList &objectList, + Fortran::lower::AbstractConverter &converter, + Fortran::semantics::SemanticsContext &semanticsContext, + Fortran::lower::StatementContext &stmtCtx, + llvm::SmallVectorImpl &dataOperands, + mlir::acc::DataClause dataClause, bool structured, bool implicit, + llvm::ArrayRef async, + llvm::ArrayRef asyncDeviceTypes, + llvm::ArrayRef asyncOnlyDeviceTypes, + bool setDeclareAttr = false, + llvm::SmallVectorImpl> + *symbolPairs = nullptr) { fir::FirOpBuilder &builder = converter.getFirOpBuilder(); Fortran::evaluate::ExpressionAnalyzer ea{semanticsContext}; const bool unwrapBoxAddr = true; @@ -655,6 +669,9 @@ genDataOperandOperations(const Fortran::parser::AccObjectList &objectList, /*strideIncludeLowerExtent=*/strideIncludeLowerExtent); LLVM_DEBUG(llvm::dbgs() << __func__ << "\n"; info.dump(llvm::dbgs())); + bool isWholeSymbol = + !designator || Fortran::evaluate::UnwrapWholeSymbolDataRef(*designator); + // If the input value is optional and is not a descriptor, we use the // rawInput directly. mlir::Value baseAddr = ((fir::unwrapRefType(info.addr.getType()) != @@ -668,6 +685,11 @@ genDataOperandOperations(const Fortran::parser::AccObjectList &objectList, asyncOnlyDeviceTypes, unwrapBoxAddr, info.isPresent); dataOperands.push_back(op.getAccVar()); + // Track the symbol and its corresponding mlir::Value if requested + if (symbolPairs && isWholeSymbol) + symbolPairs->emplace_back(op.getAccVar(), + Fortran::semantics::SymbolRef(symbol)); + // For UseDeviceOp, if operand is one of a pair resulting from a // declare operation, create a UseDeviceOp for the other operand as well. if constexpr (std::is_same_v) { @@ -681,6 +703,8 @@ genDataOperandOperations(const Fortran::parser::AccObjectList &objectList, asyncDeviceTypes, asyncOnlyDeviceTypes, unwrapBoxAddr, info.isPresent); dataOperands.push_back(op.getAccVar()); + // Not adding this to symbolPairs because it only make sense to + // map the symbol to a single value. } } } @@ -1264,7 +1288,9 @@ static void genPrivatizationRecipes( llvm::SmallVector &privatizationRecipes, llvm::ArrayRef async, llvm::ArrayRef asyncDeviceTypes, - llvm::ArrayRef asyncOnlyDeviceTypes) { + llvm::ArrayRef asyncOnlyDeviceTypes, + llvm::SmallVectorImpl> + *symbolPairs = nullptr) { fir::FirOpBuilder &builder = converter.getFirOpBuilder(); Fortran::evaluate::ExpressionAnalyzer ea{semanticsContext}; for (const auto &accObject : objectList.v) { @@ -1284,6 +1310,9 @@ static void genPrivatizationRecipes( /*strideIncludeLowerExtent=*/strideIncludeLowerExtent); LLVM_DEBUG(llvm::dbgs() << __func__ << "\n"; info.dump(llvm::dbgs())); + bool isWholeSymbol = + !designator || Fortran::evaluate::UnwrapWholeSymbolDataRef(*designator); + RecipeOp recipe; mlir::Type retTy = getTypeFromBounds(bounds, info.addr.getType()); if constexpr (std::is_same_v) { @@ -1297,6 +1326,11 @@ static void genPrivatizationRecipes( /*implicit=*/false, mlir::acc::DataClause::acc_private, retTy, async, asyncDeviceTypes, asyncOnlyDeviceTypes, /*unwrapBoxAddr=*/true); dataOperands.push_back(op.getAccVar()); + + // Track the symbol and its corresponding mlir::Value if requested + if (symbolPairs && isWholeSymbol) + symbolPairs->emplace_back(op.getAccVar(), + Fortran::semantics::SymbolRef(symbol)); } else { std::string suffix = areAllBoundConstant(bounds) ? getBoundsString(bounds) : ""; @@ -1310,6 +1344,11 @@ static void genPrivatizationRecipes( async, asyncDeviceTypes, asyncOnlyDeviceTypes, /*unwrapBoxAddr=*/true); dataOperands.push_back(op.getAccVar()); + + // Track the symbol and its corresponding mlir::Value if requested + if (symbolPairs && isWholeSymbol) + symbolPairs->emplace_back(op.getAccVar(), + Fortran::semantics::SymbolRef(symbol)); } privatizationRecipes.push_back(mlir::SymbolRefAttr::get( builder.getContext(), recipe.getSymName().str())); @@ -1949,15 +1988,16 @@ mlir::Type getTypeFromIvTypeSize(fir::FirOpBuilder &builder, return builder.getIntegerType(ivTypeSize * 8); } -static void -privatizeIv(Fortran::lower::AbstractConverter &converter, - const Fortran::semantics::Symbol &sym, mlir::Location loc, - llvm::SmallVector &ivTypes, - llvm::SmallVector &ivLocs, - llvm::SmallVector &privateOperands, - llvm::SmallVector &ivPrivate, - llvm::SmallVector &privatizationRecipes, - bool isDoConcurrent = false) { +static void privatizeIv( + Fortran::lower::AbstractConverter &converter, + const Fortran::semantics::Symbol &sym, mlir::Location loc, + llvm::SmallVector &ivTypes, + llvm::SmallVector &ivLocs, + llvm::SmallVector &privateOperands, + llvm::SmallVector> + &ivPrivate, + llvm::SmallVector &privatizationRecipes, + bool isDoConcurrent = false) { fir::FirOpBuilder &builder = converter.getFirOpBuilder(); mlir::Type ivTy = getTypeFromIvTypeSize(builder, sym); @@ -2001,15 +2041,8 @@ privatizeIv(Fortran::lower::AbstractConverter &converter, builder.getContext(), recipe.getSymName().str())); } - // Map the new private iv to its symbol for the scope of the loop. bindSymbol - // might create a hlfir.declare op, if so, we map its result in order to - // use the sym value in the scope. - converter.bindSymbol(sym, mlir::acc::getAccVar(privateOp)); - auto privateValue = converter.getSymbolAddress(sym); - if (auto declareOp = - mlir::dyn_cast(privateValue.getDefiningOp())) - privateValue = declareOp.getResults()[0]; - ivPrivate.push_back(privateValue); + ivPrivate.emplace_back(mlir::acc::getAccVar(privateOp), + Fortran::semantics::SymbolRef(sym)); } static void determineDefaultLoopParMode( @@ -2088,7 +2121,8 @@ static void processDoLoopBounds( llvm::SmallVector &upperbounds, llvm::SmallVector &steps, llvm::SmallVector &privateOperands, - llvm::SmallVector &ivPrivate, + llvm::SmallVector> + &ivPrivate, llvm::SmallVector &privatizationRecipes, llvm::SmallVector &ivTypes, llvm::SmallVector &ivLocs, @@ -2178,26 +2212,122 @@ static void processDoLoopBounds( } } -static mlir::acc::LoopOp -buildACCLoopOp(Fortran::lower::AbstractConverter &converter, - mlir::Location currentLocation, - Fortran::semantics::SemanticsContext &semanticsContext, - Fortran::lower::StatementContext &stmtCtx, - const Fortran::parser::DoConstruct &outerDoConstruct, - Fortran::lower::pft::Evaluation &eval, - llvm::SmallVector &privateOperands, - llvm::SmallVector &privatizationRecipes, - llvm::SmallVector &gangOperands, - llvm::SmallVector &workerNumOperands, - llvm::SmallVector &vectorOperands, - llvm::SmallVector &tileOperands, - llvm::SmallVector &cacheOperands, - llvm::SmallVector &reductionOperands, - llvm::SmallVector &retTy, mlir::Value yieldValue, - uint64_t loopsToProcess) { +/// Remap symbols that appeared in OpenACC data clauses to use the results of +/// the corresponding data operations. This allows isolating symbol accesses +/// inside the OpenACC region from accesses in the host and other regions while +/// preserving Fortran information about the symbols for optimizations. +template +static void remapDataOperandSymbols( + Fortran::lower::AbstractConverter &converter, fir::FirOpBuilder &builder, + RegionOp ®ionOp, + const llvm::SmallVector< + std::pair> + &dataOperandSymbolPairs) { + if (!enableSymbolRemapping || dataOperandSymbolPairs.empty()) + return; + + // Map Symbols that appeared inside data clauses to a new hlfir.declare whose + // input is the acc data operation result. + // This allows isolating all the symbol accesses inside the compute region + // from accesses in the host and other regions while preserving the Fortran + // information about the symbols for Fortran specific optimizations inside the + // region. + Fortran::lower::SymMap &symbolMap = converter.getSymbolMap(); + mlir::OpBuilder::InsertionGuard insertGuard(builder); + builder.setInsertionPointToStart(®ionOp.getRegion().front()); + llvm::SmallPtrSet seenSymbols; + mlir::IRMapping mapper; + for (auto [value, symbol] : dataOperandSymbolPairs) { + + // If A symbol appears on several data clause, just map it to the first + // result (all data operations results for a symbol are pointing same + // memory, so it does not matter which one is used). + if (seenSymbols.contains(&symbol.get())) + continue; + seenSymbols.insert(&symbol.get()); + std::optional hostDef = + symbolMap.lookupVariableDefinition(symbol); + assert(hostDef.has_value() && llvm::isa(*hostDef) && + "expected symbol to be mapped to hlfir.declare"); + auto hostDeclare = llvm::cast(*hostDef); + // Replace base input and DummyScope inputs. + mlir::Value hostInput = hostDeclare.getMemref(); + mlir::Type hostType = hostInput.getType(); + mlir::Type computeType = value.getType(); + if (hostType == computeType) { + mapper.map(hostInput, value); + } else if (llvm::isa(computeType)) { + assert(!llvm::isa(hostType) && + "box type mismatch between compute region variable and " + "hlfir.declare input unexpected"); + if (Fortran::semantics::IsOptional(symbol)) + TODO(regionOp.getLoc(), + "remapping OPTIONAL symbol in OpenACC compute region"); + auto rawValue = + fir::BoxAddrOp::create(builder, regionOp.getLoc(), hostType, value); + mapper.map(hostInput, rawValue); + } else { + assert(!llvm::isa(hostType) && + "compute region variable should not be raw address when host " + "hlfir.declare input was a box"); + assert(fir::isBoxAddress(hostType) == fir::isBoxAddress(computeType) && + "compute region variable should be a pointer/allocatable if and " + "only if host is"); + assert(fir::isa_ref_type(hostType) && fir::isa_ref_type(computeType) && + "compute region variable and host variable should both be raw " + "addresses"); + mlir::Value cast = + builder.createConvert(regionOp.getLoc(), hostType, value); + mapper.map(hostInput, cast); + } + if (mlir::Value dummyScope = hostDeclare.getDummyScope()) { + // Copy the dummy scope into the region so that aliasing rules about + // Fortran dummies are understood inside the region and the abstract dummy + // scope type does not have to cross the OpenACC compute region boundary. + if (!mapper.contains(dummyScope)) { + mlir::Operation *hostDummyScopeOp = dummyScope.getDefiningOp(); + assert(hostDummyScopeOp && + "dummyScope defining operation must be visible in lowering"); + (void)builder.clone(*hostDummyScopeOp, mapper); + } + } + + mlir::Operation *computeDef = + builder.clone(*hostDeclare.getOperation(), mapper); + + // The input box already went through an hlfir.declare. It has the correct + // local lower bounds and attribute. Do not generate a new fir.rebox. + if (llvm::isa(hostDeclare.getMemref().getType())) + llvm::cast(*computeDef).setSkipRebox(true); + + symbolMap.addVariableDefinition( + symbol, llvm::cast(computeDef)); + } +} + +static mlir::acc::LoopOp buildACCLoopOp( + Fortran::lower::AbstractConverter &converter, + mlir::Location currentLocation, + Fortran::semantics::SemanticsContext &semanticsContext, + Fortran::lower::StatementContext &stmtCtx, + const Fortran::parser::DoConstruct &outerDoConstruct, + Fortran::lower::pft::Evaluation &eval, + llvm::SmallVector &privateOperands, + llvm::SmallVector &privatizationRecipes, + llvm::SmallVector> + &dataOperandSymbolPairs, + llvm::SmallVector &gangOperands, + llvm::SmallVector &workerNumOperands, + llvm::SmallVector &vectorOperands, + llvm::SmallVector &tileOperands, + llvm::SmallVector &cacheOperands, + llvm::SmallVector &reductionOperands, + llvm::SmallVector &retTy, mlir::Value yieldValue, + uint64_t loopsToProcess) { fir::FirOpBuilder &builder = converter.getFirOpBuilder(); - llvm::SmallVector ivPrivate; + llvm::SmallVector> + ivPrivate; llvm::SmallVector ivTypes; llvm::SmallVector ivLocs; llvm::SmallVector inclusiveBounds; @@ -2231,10 +2361,22 @@ buildACCLoopOp(Fortran::lower::AbstractConverter &converter, builder, builder.getFusedLoc(locs), currentLocation, eval, operands, operandSegments, /*outerCombined=*/false, retTy, yieldValue, ivTypes, ivLocs); - - for (auto [arg, value] : llvm::zip( - loopOp.getLoopRegions().front()->front().getArguments(), ivPrivate)) - fir::StoreOp::create(builder, currentLocation, arg, value); + // Ensure the iv symbol is mapped to private iv SSA value for the scope of + // the loop even if it did not appear explicitly in a PRIVATE clause (if it + // appeared explicitly in such clause, that is also fine because duplicates + // in the list are ignored). + dataOperandSymbolPairs.append(ivPrivate.begin(), ivPrivate.end()); + // Remap symbols from data clauses to use data operation results + remapDataOperandSymbols(converter, builder, loopOp, dataOperandSymbolPairs); + + for (auto [arg, iv] : + llvm::zip(loopOp.getLoopRegions().front()->front().getArguments(), + ivPrivate)) { + // Store block argument to the related iv private variable. + mlir::Value privateValue = + converter.getSymbolAddress(std::get(iv)); + fir::StoreOp::create(builder, currentLocation, arg, privateValue); + } loopOp.setInclusiveUpperbound(inclusiveBounds); @@ -2260,6 +2402,10 @@ static mlir::acc::LoopOp createLoopOp( llvm::SmallVector tileOperandsSegments, gangOperandsSegments; llvm::SmallVector collapseValues; + // Vector to track mlir::Value results and their corresponding Fortran symbols + llvm::SmallVector> + dataOperandSymbolPairs; + llvm::SmallVector gangArgTypes; llvm::SmallVector seqDeviceTypes, independentDeviceTypes, autoDeviceTypes, vectorOperandsDeviceTypes, workerNumOperandsDeviceTypes, @@ -2380,7 +2526,8 @@ static mlir::acc::LoopOp createLoopOp( genPrivatizationRecipes( privateClause->v, converter, semanticsContext, stmtCtx, privateOperands, privatizationRecipes, /*async=*/{}, - /*asyncDeviceTypes=*/{}, /*asyncOnlyDeviceTypes=*/{}); + /*asyncDeviceTypes=*/{}, /*asyncOnlyDeviceTypes=*/{}, + &dataOperandSymbolPairs); } else if (const auto *reductionClause = std::get_if( &clause.u)) { @@ -2436,9 +2583,9 @@ static mlir::acc::LoopOp createLoopOp( Fortran::lower::getLoopCountForCollapseAndTile(accClauseList); auto loopOp = buildACCLoopOp( converter, currentLocation, semanticsContext, stmtCtx, outerDoConstruct, - eval, privateOperands, privatizationRecipes, gangOperands, - workerNumOperands, vectorOperands, tileOperands, cacheOperands, - reductionOperands, retTy, yieldValue, loopsToProcess); + eval, privateOperands, privatizationRecipes, dataOperandSymbolPairs, + gangOperands, workerNumOperands, vectorOperands, tileOperands, + cacheOperands, reductionOperands, retTy, yieldValue, loopsToProcess); if (!gangDeviceTypes.empty()) loopOp.setGangAttr(builder.getArrayAttr(gangDeviceTypes)); @@ -2568,7 +2715,9 @@ static void genDataOperandOperationsWithModifier( llvm::ArrayRef async, llvm::ArrayRef asyncDeviceTypes, llvm::ArrayRef asyncOnlyDeviceTypes, - bool setDeclareAttr = false) { + bool setDeclareAttr = false, + llvm::SmallVectorImpl> + *symbolPairs = nullptr) { const Fortran::parser::AccObjectListWithModifier &listWithModifier = x->v; const auto &accObjectList = std::get(listWithModifier.t); @@ -2581,7 +2730,7 @@ static void genDataOperandOperationsWithModifier( stmtCtx, dataClauseOperands, dataClause, /*structured=*/true, /*implicit=*/false, async, asyncDeviceTypes, asyncOnlyDeviceTypes, - setDeclareAttr); + setDeclareAttr, symbolPairs); } template @@ -2612,6 +2761,10 @@ static Op createComputeOp( llvm::SmallVector privatizationRecipes, firstPrivatizationRecipes, reductionRecipes; + // Vector to track mlir::Value results and their corresponding Fortran symbols + llvm::SmallVector> + dataOperandSymbolPairs; + // Self clause has optional values but can be present with // no value as well. When there is no value, the op has an attribute to // represent the clause. @@ -2732,7 +2885,8 @@ static Op createComputeOp( copyClause->v, converter, semanticsContext, stmtCtx, dataClauseOperands, mlir::acc::DataClause::acc_copy, /*structured=*/true, /*implicit=*/false, async, asyncDeviceTypes, - asyncOnlyDeviceTypes); + asyncOnlyDeviceTypes, /*setDeclareAttr=*/false, + &dataOperandSymbolPairs); copyEntryOperands.append(dataClauseOperands.begin() + crtDataStart, dataClauseOperands.end()); } else if (const auto *copyinClause = @@ -2744,7 +2898,8 @@ static Op createComputeOp( Fortran::parser::AccDataModifier::Modifier::ReadOnly, dataClauseOperands, mlir::acc::DataClause::acc_copyin, mlir::acc::DataClause::acc_copyin_readonly, async, asyncDeviceTypes, - asyncOnlyDeviceTypes); + asyncOnlyDeviceTypes, /*setDeclareAttr=*/false, + &dataOperandSymbolPairs); copyinEntryOperands.append(dataClauseOperands.begin() + crtDataStart, dataClauseOperands.end()); } else if (const auto *copyoutClause = @@ -2757,7 +2912,8 @@ static Op createComputeOp( Fortran::parser::AccDataModifier::Modifier::ReadOnly, dataClauseOperands, mlir::acc::DataClause::acc_copyout, mlir::acc::DataClause::acc_copyout_zero, async, asyncDeviceTypes, - asyncOnlyDeviceTypes); + asyncOnlyDeviceTypes, /*setDeclareAttr=*/false, + &dataOperandSymbolPairs); copyoutEntryOperands.append(dataClauseOperands.begin() + crtDataStart, dataClauseOperands.end()); } else if (const auto *createClause = @@ -2769,7 +2925,8 @@ static Op createComputeOp( Fortran::parser::AccDataModifier::Modifier::Zero, dataClauseOperands, mlir::acc::DataClause::acc_create, mlir::acc::DataClause::acc_create_zero, async, asyncDeviceTypes, - asyncOnlyDeviceTypes); + asyncOnlyDeviceTypes, /*setDeclareAttr=*/false, + &dataOperandSymbolPairs); createEntryOperands.append(dataClauseOperands.begin() + crtDataStart, dataClauseOperands.end()); } else if (const auto *noCreateClause = @@ -2780,7 +2937,8 @@ static Op createComputeOp( noCreateClause->v, converter, semanticsContext, stmtCtx, dataClauseOperands, mlir::acc::DataClause::acc_no_create, /*structured=*/true, /*implicit=*/false, async, asyncDeviceTypes, - asyncOnlyDeviceTypes); + asyncOnlyDeviceTypes, /*setDeclareAttr=*/false, + &dataOperandSymbolPairs); nocreateEntryOperands.append(dataClauseOperands.begin() + crtDataStart, dataClauseOperands.end()); } else if (const auto *presentClause = @@ -2791,17 +2949,21 @@ static Op createComputeOp( presentClause->v, converter, semanticsContext, stmtCtx, dataClauseOperands, mlir::acc::DataClause::acc_present, /*structured=*/true, /*implicit=*/false, async, asyncDeviceTypes, - asyncOnlyDeviceTypes); + asyncOnlyDeviceTypes, /*setDeclareAttr=*/false, + &dataOperandSymbolPairs); presentEntryOperands.append(dataClauseOperands.begin() + crtDataStart, dataClauseOperands.end()); } else if (const auto *devicePtrClause = std::get_if( &clause.u)) { + llvm::SmallVectorImpl< + std::pair> *symPairs = + enableDevicePtrRemap ? &dataOperandSymbolPairs : nullptr; genDataOperandOperations( devicePtrClause->v, converter, semanticsContext, stmtCtx, dataClauseOperands, mlir::acc::DataClause::acc_deviceptr, /*structured=*/true, /*implicit=*/false, async, asyncDeviceTypes, - asyncOnlyDeviceTypes); + asyncOnlyDeviceTypes, /*setDeclareAttr=*/false, symPairs); } else if (const auto *attachClause = std::get_if(&clause.u)) { auto crtDataStart = dataClauseOperands.size(); @@ -2809,7 +2971,8 @@ static Op createComputeOp( attachClause->v, converter, semanticsContext, stmtCtx, dataClauseOperands, mlir::acc::DataClause::acc_attach, /*structured=*/true, /*implicit=*/false, async, asyncDeviceTypes, - asyncOnlyDeviceTypes); + asyncOnlyDeviceTypes, /*setDeclareAttr=*/false, + &dataOperandSymbolPairs); attachEntryOperands.append(dataClauseOperands.begin() + crtDataStart, dataClauseOperands.end()); } else if (const auto *privateClause = @@ -2819,14 +2982,14 @@ static Op createComputeOp( genPrivatizationRecipes( privateClause->v, converter, semanticsContext, stmtCtx, privateOperands, privatizationRecipes, async, asyncDeviceTypes, - asyncOnlyDeviceTypes); + asyncOnlyDeviceTypes, &dataOperandSymbolPairs); } else if (const auto *firstprivateClause = std::get_if( &clause.u)) { genPrivatizationRecipes( firstprivateClause->v, converter, semanticsContext, stmtCtx, firstprivateOperands, firstPrivatizationRecipes, async, - asyncDeviceTypes, asyncOnlyDeviceTypes); + asyncDeviceTypes, asyncOnlyDeviceTypes, &dataOperandSymbolPairs); } else if (const auto *reductionClause = std::get_if( &clause.u)) { @@ -2846,7 +3009,8 @@ static Op createComputeOp( converter, semanticsContext, stmtCtx, dataClauseOperands, mlir::acc::DataClause::acc_reduction, /*structured=*/true, /*implicit=*/true, async, asyncDeviceTypes, - asyncOnlyDeviceTypes); + asyncOnlyDeviceTypes, /*setDeclareAttr=*/false, + &dataOperandSymbolPairs); copyEntryOperands.append(dataClauseOperands.begin() + crtDataStart, dataClauseOperands.end()); } @@ -2945,6 +3109,11 @@ static Op createComputeOp( computeOp.setCombinedAttr(builder.getUnitAttr()); auto insPt = builder.saveInsertionPoint(); + + // Remap symbols from data clauses to use data operation results + remapDataOperandSymbols(converter, builder, computeOp, + dataOperandSymbolPairs); + builder.setInsertionPointAfter(computeOp); // Create the exit operations after the region. @@ -4921,6 +5090,8 @@ mlir::Operation *Fortran::lower::genOpenACCLoopFromDoConstruct( reductionOperands; llvm::SmallVector privatizationRecipes; llvm::SmallVector retTy; + llvm::SmallVector> + dataOperandSymbolPairs; mlir::Value yieldValue; uint64_t loopsToProcess = 1; // Single loop construct @@ -4929,9 +5100,10 @@ mlir::Operation *Fortran::lower::genOpenACCLoopFromDoConstruct( Fortran::lower::StatementContext stmtCtx; auto loopOp = buildACCLoopOp( converter, converter.getCurrentLocation(), semanticsContext, stmtCtx, - doConstruct, eval, privateOperands, privatizationRecipes, gangOperands, - workerNumOperands, vectorOperands, tileOperands, cacheOperands, - reductionOperands, retTy, yieldValue, loopsToProcess); + doConstruct, eval, privateOperands, privatizationRecipes, + dataOperandSymbolPairs, gangOperands, workerNumOperands, vectorOperands, + tileOperands, cacheOperands, reductionOperands, retTy, yieldValue, + loopsToProcess); fir::FirOpBuilder &builder = converter.getFirOpBuilder(); if (!privatizationRecipes.empty()) diff --git a/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp b/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp index 0cc65f939723e..1332dc57fb086 100644 --- a/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp +++ b/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp @@ -281,7 +281,7 @@ void hlfir::DeclareOp::build(mlir::OpBuilder &builder, getDeclareOutputTypes(inputType, hasExplicitLbs); build(builder, result, {hlfirVariableType, firVarType}, memref, shape, typeparams, dummy_scope, storage, storage_offset, nameAttr, - fortran_attrs, data_attr); + fortran_attrs, data_attr, /*skip_rebox=*/mlir::UnitAttr{}); } llvm::LogicalResult hlfir::DeclareOp::verify() { @@ -294,6 +294,9 @@ llvm::LogicalResult hlfir::DeclareOp::verify() { return emitOpError("first result type is inconsistent with variable " "properties: expected ") << hlfirVariableType; + if (getSkipRebox() && !llvm::isa(getMemref().getType())) + return emitOpError( + "skip_rebox attribute must only be set when the input is a box"); // The rest of the argument verification is done by the // FortranVariableInterface verifier. auto fortranVar = diff --git a/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp b/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp index 8104e53920c27..6a57bf2ae6fec 100644 --- a/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp +++ b/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp @@ -23,6 +23,7 @@ #include "flang/Optimizer/HLFIR/HLFIROps.h" #include "flang/Optimizer/HLFIR/Passes.h" #include "mlir/Transforms/DialectConversion.h" +#include "llvm/ADT/SmallSet.h" namespace hlfir { #define GEN_PASS_DEF_CONVERTHLFIRTOFIR @@ -312,10 +313,12 @@ class DeclareOpConversion : public mlir::OpRewritePattern { // Propagate other attributes from hlfir.declare to fir.declare. // OpenACC's acc.declare is one example. Right now, the propagation // is verbatim. - mlir::NamedAttrList elidedAttrs = - mlir::NamedAttrList{firDeclareOp->getAttrs()}; + llvm::SmallSet elidedAttrs; + for (const mlir::NamedAttribute &firAttr : firDeclareOp->getAttrs()) + elidedAttrs.insert(firAttr.getName()); + elidedAttrs.insert(declareOp.getSkipReboxAttrName()); for (const mlir::NamedAttribute &attr : declareOp->getAttrs()) - if (!elidedAttrs.get(attr.getName())) + if (!elidedAttrs.contains(attr.getName())) firDeclareOp->setAttr(attr.getName(), attr.getValue()); auto firBase = firDeclareOp.getResult(); @@ -328,6 +331,8 @@ class DeclareOpConversion : public mlir::OpRewritePattern { auto genHlfirBox = [&]() -> mlir::Value { if (auto baseBoxType = mlir::dyn_cast(firBase.getType())) { + if (declareOp.getSkipRebox()) + return firBase; // Rebox so that lower bounds and attributes are correct. if (baseBoxType.isAssumedRank()) return fir::ReboxAssumedRankOp::create( diff --git a/flang/test/HLFIR/declare-codegen.fir b/flang/test/HLFIR/declare-codegen.fir index b3f0b73158603..04c2ddcece4a7 100644 --- a/flang/test/HLFIR/declare-codegen.fir +++ b/flang/test/HLFIR/declare-codegen.fir @@ -124,6 +124,15 @@ func.func @array_declare_box_2(%arg0: !fir.box>) { // CHECK: %[[VAL_1:.*]] = fir.declare %[[VAL_0]] {uniq_name = "x"} : (!fir.box>) -> !fir.box> // CHECK: %[[VAL_2:.*]] = fir.rebox %[[VAL_1]] : (!fir.box>) -> !fir.box> +func.func @array_declare_box_3(%arg0: !fir.box>) -> !fir.box> { + %0:2 = hlfir.declare %arg0 skip_rebox {uniq_name = "x"} : (!fir.box>) -> (!fir.box>, !fir.box>) + return %0#0 : !fir.box> +} +// CHECK-LABEL: func.func @array_declare_box_3( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.box>) -> !fir.box> { +// CHECK: %[[VAL_1:.*]] = fir.declare %[[VAL_0]] {uniq_name = "x"} : (!fir.box>) -> !fir.box> +// CHECK: return %[[VAL_1]] + func.func @array_declare_char_box(%arg0: !fir.box>>) { %0:2 = hlfir.declare %arg0 {uniq_name = "x"} : (!fir.box>>) -> (!fir.box>>, !fir.box>>) return diff --git a/flang/test/HLFIR/invalid.fir b/flang/test/HLFIR/invalid.fir index 887113959429c..91e9ed6c2e4c4 100644 --- a/flang/test/HLFIR/invalid.fir +++ b/flang/test/HLFIR/invalid.fir @@ -36,6 +36,15 @@ func.func @bad_array_declare(%arg0: !fir.ref>) { return } +// ----- +func.func @bad_declare_skip_rebox(%arg0: !fir.ref) { + // expected-error@+1 {{'hlfir.declare' op skip_rebox attribute must only be set when the input is a box}} + %0:2 = hlfir.declare %arg0 skip_rebox {uniq_name = "x"} : (!fir.ref) -> (!fir.ref, !fir.ref) + return +} + +// ----- + // ----- func.func @bad_assign_scalar_character(%arg0: !fir.boxchar<1>, %arg1: !fir.char<1,?>) { // expected-error@+1 {{'hlfir.assign' op operand #0 must be any Fortran value or variable type, but got '!fir.char<1,?>'}} diff --git a/flang/test/Lower/OpenACC/acc-data-operands-remapping.f90 b/flang/test/Lower/OpenACC/acc-data-operands-remapping.f90 new file mode 100644 index 0000000000000..9d36f6a99e8a7 --- /dev/null +++ b/flang/test/Lower/OpenACC/acc-data-operands-remapping.f90 @@ -0,0 +1,601 @@ +! Test remapping of variables appearing in OpenACC data clauses +! to the related acc dialect data operation result. + +! This tests checks how the hlfir.declare is recreated and used inside +! the acc compute region. + +! RUN: bbc -fopenacc -emit-hlfir %s -o - | FileCheck %s + +module m +interface +subroutine takes_scalar(x) + real :: x +end subroutine +subroutine takes_scalar_character(c, l) + integer :: l + character(l) :: c +end subroutine +subroutine takes_explicit_cst_shape(x) + real :: x(100) +end subroutine +subroutine takes_explicit_shape(x, n) + real :: x(n) +end subroutine +subroutine takes_assumed_shape(x) + real :: x(:) +end subroutine +subroutine takes_pointer(x) + real, pointer :: x(:) +end subroutine + +subroutine takes_optional_scalar(x) + real, optional :: x +end subroutine +subroutine takes_optional_explicit_cst_shape(x) + real, optional :: x(100) +end subroutine +subroutine takes_optional_explicit_shape(x, n) + real, optional :: x(n) +end subroutine +subroutine takes_optional_assumed_shape(x) + real, optional :: x(:) +end subroutine +subroutine takes_optional_pointer(x) + real, optional, pointer :: x(:) +end subroutine +end interface +contains + +! ----------------------------- Test forwarding ------------------------------ ! + + subroutine test_scalar(x) + real :: x + !$acc parallel copy(x) + call takes_scalar(x) + !$acc end parallel + end subroutine + + subroutine test_scalar_character(c, l) + integer :: l + character(l) :: c + !$acc parallel copy(x) + call takes_scalar_character(c, len(c)) + !$acc end parallel + end subroutine + + subroutine test_cst_shape(x) + real :: x(100) + !$acc parallel copy(x) + call takes_explicit_cst_shape(x) + !$acc end parallel + end subroutine + + subroutine test_explicit_shape(x, n) + real :: x(n) + !$acc parallel copy(x) + call takes_explicit_shape(x, size(x,dim=1)) + !$acc end parallel + end subroutine + + subroutine test_assumed_shape(x, n) + real :: x(:) + !$acc parallel copy(x) + call takes_assumed_shape(x) + !$acc end parallel + end subroutine + + subroutine test_contiguous_assumed_shape(x, n) + real, contiguous :: x(:) + !$acc parallel copy(x) + call takes_explicit_shape(x, size(x,dim=1)) + !$acc end parallel + end subroutine + + subroutine test_pointer(x, n) + real, pointer :: x(:) + !$acc parallel copy(x) + call takes_pointer(x) + !$acc end parallel + end subroutine + + subroutine test_using_both_results(x, n) + real :: x(n) + !$acc parallel copy(x) + ! using hlfir.declare result #0 + call takes_assumed_shape(x) + ! using hlfir.declare result #1 + call takes_explicit_shape(x, size(x,dim=1)) + !$acc end parallel + end subroutine + +! ------------------------- Test array addressing ---------------------------- ! + + subroutine addressing_cst_shape(x) + real :: x(10, 20) + !$acc parallel copy(x) + call takes_scalar(x(2,3)) + !$acc end parallel + end subroutine + + subroutine addressing_explicit_shape(x, n, m) + real :: x(n, m) + !$acc parallel copy(x) + call takes_scalar(x(2,3)) + !$acc end parallel + end subroutine + + subroutine addressing_assumed_shape(x, n) + real :: x(:, :) + !$acc parallel copy(x) + call takes_scalar(x(2,3)) + !$acc end parallel + end subroutine + + subroutine addressing_contiguous_assumed_shape(x, n) + real, contiguous :: x(:, :) + !$acc parallel copy(x) + call takes_scalar(x(2,3)) + !$acc end parallel + end subroutine + + subroutine addressing_pointer(x) + real, pointer :: x(:, :) + !$acc parallel copy(x) + call takes_scalar(x(2,3)) + !$acc end parallel + end subroutine + +! ------------------------ Test OPTIONAL handling ---------------------------- ! + + subroutine test_optional_scalar(x) + real, optional :: x + !$acc parallel copy(x) + call takes_optional_scalar(x) + !$acc end parallel + end subroutine + + subroutine test_optional_explicit_cst_shape(x) + real, optional :: x(100) + !$acc parallel copy(x) + call takes_optional_explicit_cst_shape(x) + !$acc end parallel + end subroutine + + subroutine test_optional_explicit_shape(x, n) + real, optional :: x(n) + !$acc parallel copy(x) + call takes_optional_explicit_shape(x, n) + !$acc end parallel + end subroutine + + subroutine test_optional_assumed_shape(x) + real, optional :: x(:) + !$acc parallel copy(x) + call takes_optional_assumed_shape(x) + !$acc end parallel + end subroutine + + subroutine test_optional_pointer(x) + real, optional, pointer :: x(:) + !$acc parallel copy(x) + call takes_optional_pointer(x) + !$acc end parallel + end subroutine + +end module + +! CHECK-LABEL: func.func @_QMmPtest_scalar( +! CHECK-SAME: %[[ARG0:.*]]: !fir.ref {fir.bindc_name = "x"}) { +! CHECK: %[[VAL_0:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[ARG0]] dummy_scope %[[VAL_0]] {uniq_name = "_QMmFtest_scalarEx"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) +! CHECK: %[[VAL_2:.*]] = acc.copyin varPtr(%[[VAL_1]]#0 : !fir.ref) -> !fir.ref {dataClause = #acc, name = "x"} +! CHECK: acc.parallel dataOperands(%[[VAL_2]] : !fir.ref) { +! CHECK: %[[VAL_3:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_2]] dummy_scope %[[VAL_3]] {uniq_name = "_QMmFtest_scalarEx"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) +! CHECK: fir.call @_QPtakes_scalar(%[[VAL_4]]#0) fastmath : (!fir.ref) -> () +! CHECK: acc.yield +! CHECK: } +! CHECK: acc.copyout accPtr(%[[VAL_2]] : !fir.ref) to varPtr(%[[VAL_1]]#0 : !fir.ref) {dataClause = #acc, name = "x"} +! CHECK: return +! CHECK: } + +! CHECK-LABEL: func.func @_QMmPtest_scalar_character( +! CHECK-SAME: %[[ARG0:.*]]: !fir.boxchar<1> {fir.bindc_name = "c"}, +! CHECK-SAME: %[[ARG1:.*]]: !fir.ref {fir.bindc_name = "l"}) { +! CHECK: %[[VAL_0:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[ARG1]] dummy_scope %[[VAL_0]] {uniq_name = "_QMmFtest_scalar_characterEl"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) +! CHECK: %[[VAL_2:.*]] = fir.alloca f32 {bindc_name = "x", uniq_name = "_QMmFtest_scalar_characterEx"} +! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_2]] {uniq_name = "_QMmFtest_scalar_characterEx"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: %[[VAL_4:.*]]:2 = fir.unboxchar %[[ARG0]] : (!fir.boxchar<1>) -> (!fir.ref>, index) +! CHECK: %[[VAL_5:.*]] = fir.load %[[VAL_1]]#0 : !fir.ref +! CHECK: %[[VAL_6:.*]] = arith.constant 0 : i32 +! CHECK: %[[VAL_7:.*]] = arith.cmpi sgt, %[[VAL_5]], %[[VAL_6]] : i32 +! CHECK: %[[VAL_8:.*]] = arith.select %[[VAL_7]], %[[VAL_5]], %[[VAL_6]] : i32 +! CHECK: %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_4]]#0 typeparams %[[VAL_8]] dummy_scope %[[VAL_0]] {uniq_name = "_QMmFtest_scalar_characterEc"} : (!fir.ref>, i32, !fir.dscope) -> (!fir.boxchar<1>, !fir.ref>) +! CHECK: %[[VAL_10:.*]] = acc.copyin varPtr(%[[VAL_3]]#0 : !fir.ref) -> !fir.ref {dataClause = #acc, name = "x"} +! CHECK: acc.parallel dataOperands(%[[VAL_10]] : !fir.ref) { +! CHECK: %[[VAL_11:.*]]:2 = hlfir.declare %[[VAL_10]] {uniq_name = "_QMmFtest_scalar_characterEx"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: %[[VAL_12:.*]]:3 = hlfir.associate %[[VAL_8]] {adapt.valuebyref} : (i32) -> (!fir.ref, !fir.ref, i1) +! CHECK: fir.call @_QPtakes_scalar_character(%[[VAL_9]]#0, %[[VAL_12]]#0) fastmath : (!fir.boxchar<1>, !fir.ref) -> () +! CHECK: hlfir.end_associate %[[VAL_12]]#1, %[[VAL_12]]#2 : !fir.ref, i1 +! CHECK: acc.yield +! CHECK: } +! CHECK: acc.copyout accPtr(%[[VAL_10]] : !fir.ref) to varPtr(%[[VAL_3]]#0 : !fir.ref) {dataClause = #acc, name = "x"} +! CHECK: return +! CHECK: } + +! CHECK-LABEL: func.func @_QMmPtest_cst_shape( +! CHECK-SAME: %[[ARG0:.*]]: !fir.ref> {fir.bindc_name = "x"}) { +! CHECK: %[[VAL_0:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_1:.*]] = arith.constant 100 : index +! CHECK: %[[VAL_2:.*]] = fir.shape %[[VAL_1]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[ARG0]](%[[VAL_2]]) dummy_scope %[[VAL_0]] {uniq_name = "_QMmFtest_cst_shapeEx"} : (!fir.ref>, !fir.shape<1>, !fir.dscope) -> (!fir.ref>, !fir.ref>) +! CHECK: %[[VAL_4:.*]] = acc.copyin varPtr(%[[VAL_3]]#0 : !fir.ref>) -> !fir.ref> {dataClause = #acc, name = "x"} +! CHECK: acc.parallel dataOperands(%[[VAL_4]] : !fir.ref>) { +! CHECK: %[[VAL_5:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_4]](%[[VAL_2]]) dummy_scope %[[VAL_5]] {uniq_name = "_QMmFtest_cst_shapeEx"} : (!fir.ref>, !fir.shape<1>, !fir.dscope) -> (!fir.ref>, !fir.ref>) +! CHECK: fir.call @_QPtakes_explicit_cst_shape(%[[VAL_6]]#0) fastmath : (!fir.ref>) -> () +! CHECK: acc.yield +! CHECK: } +! CHECK: acc.copyout accPtr(%[[VAL_4]] : !fir.ref>) to varPtr(%[[VAL_3]]#0 : !fir.ref>) {dataClause = #acc, name = "x"} +! CHECK: return +! CHECK: } + +! CHECK-LABEL: func.func @_QMmPtest_explicit_shape( +! CHECK-SAME: %[[ARG0:.*]]: !fir.ref> {fir.bindc_name = "x"}, +! CHECK-SAME: %[[ARG1:.*]]: !fir.ref {fir.bindc_name = "n"}) { +! CHECK: %[[VAL_0:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[ARG1]] dummy_scope %[[VAL_0]] {uniq_name = "_QMmFtest_explicit_shapeEn"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) +! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_1]]#0 : !fir.ref +! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (i32) -> i64 +! CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (i64) -> index +! CHECK: %[[VAL_5:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_6:.*]] = arith.cmpi sgt, %[[VAL_4]], %[[VAL_5]] : index +! CHECK: %[[VAL_7:.*]] = arith.select %[[VAL_6]], %[[VAL_4]], %[[VAL_5]] : index +! CHECK: %[[VAL_8:.*]] = fir.shape %[[VAL_7]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_9:.*]]:2 = hlfir.declare %[[ARG0]](%[[VAL_8]]) dummy_scope %[[VAL_0]] {uniq_name = "_QMmFtest_explicit_shapeEx"} : (!fir.ref>, !fir.shape<1>, !fir.dscope) -> (!fir.box>, !fir.ref>) +! CHECK: %[[VAL_10:.*]] = acc.copyin var(%[[VAL_9]]#0 : !fir.box>) -> !fir.box> {dataClause = #acc, name = "x"} +! CHECK: acc.parallel dataOperands(%[[VAL_10]] : !fir.box>) { +! CHECK: %[[VAL_11:.*]] = fir.box_addr %[[VAL_10]] : (!fir.box>) -> !fir.ref> +! CHECK: %[[VAL_12:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_13:.*]]:2 = hlfir.declare %[[VAL_11]](%[[VAL_8]]) dummy_scope %[[VAL_12]] {uniq_name = "_QMmFtest_explicit_shapeEx"} : (!fir.ref>, !fir.shape<1>, !fir.dscope) -> (!fir.box>, !fir.ref>) +! CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_7]] : (index) -> i64 +! CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_14]] : (i64) -> i32 +! CHECK: %[[VAL_16:.*]]:3 = hlfir.associate %[[VAL_15]] {adapt.valuebyref} : (i32) -> (!fir.ref, !fir.ref, i1) +! CHECK: fir.call @_QPtakes_explicit_shape(%[[VAL_13]]#1, %[[VAL_16]]#0) fastmath : (!fir.ref>, !fir.ref) -> () +! CHECK: hlfir.end_associate %[[VAL_16]]#1, %[[VAL_16]]#2 : !fir.ref, i1 +! CHECK: acc.yield +! CHECK: } +! CHECK: acc.copyout accVar(%[[VAL_10]] : !fir.box>) to var(%[[VAL_9]]#0 : !fir.box>) {dataClause = #acc, name = "x"} +! CHECK: return +! CHECK: } + +! CHECK-LABEL: func.func @_QMmPtest_assumed_shape( +! CHECK-SAME: %[[ARG0:.*]]: !fir.box> {fir.bindc_name = "x"}, +! CHECK-SAME: %[[ARG1:.*]]: !fir.ref {fir.bindc_name = "n"}) { +! CHECK: %[[VAL_0:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[ARG1]] dummy_scope %[[VAL_0]] {uniq_name = "_QMmFtest_assumed_shapeEn"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) +! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[ARG0]] dummy_scope %[[VAL_0]] {uniq_name = "_QMmFtest_assumed_shapeEx"} : (!fir.box>, !fir.dscope) -> (!fir.box>, !fir.box>) +! CHECK: %[[VAL_3:.*]] = acc.copyin var(%[[VAL_2]]#0 : !fir.box>) -> !fir.box> {dataClause = #acc, name = "x"} +! CHECK: acc.parallel dataOperands(%[[VAL_3]] : !fir.box>) { +! CHECK: %[[VAL_4:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_3]] dummy_scope %[[VAL_4]] skip_rebox {uniq_name = "_QMmFtest_assumed_shapeEx"} : (!fir.box>, !fir.dscope) -> (!fir.box>, !fir.box>) +! CHECK: fir.call @_QPtakes_assumed_shape(%[[VAL_5]]#0) fastmath : (!fir.box>) -> () +! CHECK: acc.yield +! CHECK: } +! CHECK: acc.copyout accVar(%[[VAL_3]] : !fir.box>) to var(%[[VAL_2]]#0 : !fir.box>) {dataClause = #acc, name = "x"} +! CHECK: return +! CHECK: } + +! CHECK-LABEL: func.func @_QMmPtest_contiguous_assumed_shape( +! CHECK-SAME: %[[ARG0:.*]]: !fir.box> {fir.bindc_name = "x", fir.contiguous}, +! CHECK-SAME: %[[ARG1:.*]]: !fir.ref {fir.bindc_name = "n"}) { +! CHECK: %[[VAL_0:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[ARG1]] dummy_scope %[[VAL_0]] {uniq_name = "_QMmFtest_contiguous_assumed_shapeEn"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) +! CHECK: %[[VAL_2:.*]] = fir.box_addr %[[ARG0]] : (!fir.box>) -> !fir.ref> +! CHECK: %[[VAL_3:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_4:.*]]:3 = fir.box_dims %[[ARG0]], %[[VAL_3]] : (!fir.box>, index) -> (index, index, index) +! CHECK: %[[VAL_5:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_6:.*]] = fir.shape_shift %[[VAL_5]], %[[VAL_4]]#1 : (index, index) -> !fir.shapeshift<1> +! CHECK: %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_2]](%[[VAL_6]]) dummy_scope %[[VAL_0]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMmFtest_contiguous_assumed_shapeEx"} : (!fir.ref>, !fir.shapeshift<1>, !fir.dscope) -> (!fir.box>, !fir.ref>) +! CHECK: %[[VAL_8:.*]] = acc.copyin var(%[[VAL_7]]#0 : !fir.box>) -> !fir.box> {dataClause = #acc, name = "x"} +! CHECK: acc.parallel dataOperands(%[[VAL_8]] : !fir.box>) { +! CHECK: %[[VAL_9:.*]] = fir.box_addr %[[VAL_8]] : (!fir.box>) -> !fir.ref> +! CHECK: %[[VAL_10:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_11:.*]]:2 = hlfir.declare %[[VAL_9]](%[[VAL_6]]) dummy_scope %[[VAL_10]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMmFtest_contiguous_assumed_shapeEx"} : (!fir.ref>, !fir.shapeshift<1>, !fir.dscope) -> (!fir.box>, !fir.ref>) +! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_4]]#1 : (index) -> i64 +! CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_12]] : (i64) -> i32 +! CHECK: %[[VAL_14:.*]]:3 = hlfir.associate %[[VAL_13]] {adapt.valuebyref} : (i32) -> (!fir.ref, !fir.ref, i1) +! CHECK: fir.call @_QPtakes_explicit_shape(%[[VAL_11]]#1, %[[VAL_14]]#0) fastmath : (!fir.ref>, !fir.ref) -> () +! CHECK: hlfir.end_associate %[[VAL_14]]#1, %[[VAL_14]]#2 : !fir.ref, i1 +! CHECK: acc.yield +! CHECK: } +! CHECK: acc.copyout accVar(%[[VAL_8]] : !fir.box>) to var(%[[VAL_7]]#0 : !fir.box>) {dataClause = #acc, name = "x"} +! CHECK: return +! CHECK: } + +! CHECK-LABEL: func.func @_QMmPtest_pointer( +! CHECK-SAME: %[[ARG0:.*]]: !fir.ref>>> {fir.bindc_name = "x"}, +! CHECK-SAME: %[[ARG1:.*]]: !fir.ref {fir.bindc_name = "n"}) { +! CHECK: %[[VAL_0:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[ARG1]] dummy_scope %[[VAL_0]] {uniq_name = "_QMmFtest_pointerEn"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) +! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[ARG0]] dummy_scope %[[VAL_0]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMmFtest_pointerEx"} : (!fir.ref>>>, !fir.dscope) -> (!fir.ref>>>, !fir.ref>>>) +! CHECK: %[[VAL_3:.*]] = acc.copyin varPtr(%[[VAL_2]]#0 : !fir.ref>>>) -> !fir.ref>>> {dataClause = #acc, name = "x"} +! CHECK: acc.parallel dataOperands(%[[VAL_3]] : !fir.ref>>>) { +! CHECK: %[[VAL_4:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_3]] dummy_scope %[[VAL_4]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMmFtest_pointerEx"} : (!fir.ref>>>, !fir.dscope) -> (!fir.ref>>>, !fir.ref>>>) +! CHECK: fir.call @_QPtakes_pointer(%[[VAL_5]]#0) fastmath : (!fir.ref>>>) -> () +! CHECK: acc.yield +! CHECK: } +! CHECK: acc.copyout accPtr(%[[VAL_3]] : !fir.ref>>>) to varPtr(%[[VAL_2]]#0 : !fir.ref>>>) {dataClause = #acc, name = "x"} +! CHECK: return +! CHECK: } + +! CHECK-LABEL: func.func @_QMmPtest_using_both_results( +! CHECK-SAME: %[[ARG0:.*]]: !fir.ref> {fir.bindc_name = "x"}, +! CHECK-SAME: %[[ARG1:.*]]: !fir.ref {fir.bindc_name = "n"}) { +! CHECK: %[[VAL_0:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[ARG1]] dummy_scope %[[VAL_0]] {uniq_name = "_QMmFtest_using_both_resultsEn"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) +! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_1]]#0 : !fir.ref +! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (i32) -> i64 +! CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (i64) -> index +! CHECK: %[[VAL_5:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_6:.*]] = arith.cmpi sgt, %[[VAL_4]], %[[VAL_5]] : index +! CHECK: %[[VAL_7:.*]] = arith.select %[[VAL_6]], %[[VAL_4]], %[[VAL_5]] : index +! CHECK: %[[VAL_8:.*]] = fir.shape %[[VAL_7]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_9:.*]]:2 = hlfir.declare %[[ARG0]](%[[VAL_8]]) dummy_scope %[[VAL_0]] {uniq_name = "_QMmFtest_using_both_resultsEx"} : (!fir.ref>, !fir.shape<1>, !fir.dscope) -> (!fir.box>, !fir.ref>) +! CHECK: %[[VAL_10:.*]] = acc.copyin var(%[[VAL_9]]#0 : !fir.box>) -> !fir.box> {dataClause = #acc, name = "x"} +! CHECK: acc.parallel dataOperands(%[[VAL_10]] : !fir.box>) { +! CHECK: %[[VAL_11:.*]] = fir.box_addr %[[VAL_10]] : (!fir.box>) -> !fir.ref> +! CHECK: %[[VAL_12:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_13:.*]]:2 = hlfir.declare %[[VAL_11]](%[[VAL_8]]) dummy_scope %[[VAL_12]] {uniq_name = "_QMmFtest_using_both_resultsEx"} : (!fir.ref>, !fir.shape<1>, !fir.dscope) -> (!fir.box>, !fir.ref>) +! CHECK: fir.call @_QPtakes_assumed_shape(%[[VAL_13]]#0) fastmath : (!fir.box>) -> () +! CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_7]] : (index) -> i64 +! CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_14]] : (i64) -> i32 +! CHECK: %[[VAL_16:.*]]:3 = hlfir.associate %[[VAL_15]] {adapt.valuebyref} : (i32) -> (!fir.ref, !fir.ref, i1) +! CHECK: fir.call @_QPtakes_explicit_shape(%[[VAL_13]]#1, %[[VAL_16]]#0) fastmath : (!fir.ref>, !fir.ref) -> () +! CHECK: hlfir.end_associate %[[VAL_16]]#1, %[[VAL_16]]#2 : !fir.ref, i1 +! CHECK: acc.yield +! CHECK: } +! CHECK: acc.copyout accVar(%[[VAL_10]] : !fir.box>) to var(%[[VAL_9]]#0 : !fir.box>) {dataClause = #acc, name = "x"} +! CHECK: return +! CHECK: } + +! CHECK-LABEL: func.func @_QMmPaddressing_cst_shape( +! CHECK-SAME: %[[ARG0:.*]]: !fir.ref> {fir.bindc_name = "x"}) { +! CHECK: %[[VAL_0:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_1:.*]] = arith.constant 10 : index +! CHECK: %[[VAL_2:.*]] = arith.constant 20 : index +! CHECK: %[[VAL_3:.*]] = fir.shape %[[VAL_1]], %[[VAL_2]] : (index, index) -> !fir.shape<2> +! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[ARG0]](%[[VAL_3]]) dummy_scope %[[VAL_0]] {uniq_name = "_QMmFaddressing_cst_shapeEx"} : (!fir.ref>, !fir.shape<2>, !fir.dscope) -> (!fir.ref>, !fir.ref>) +! CHECK: %[[VAL_5:.*]] = acc.copyin varPtr(%[[VAL_4]]#0 : !fir.ref>) -> !fir.ref> {dataClause = #acc, name = "x"} +! CHECK: acc.parallel dataOperands(%[[VAL_5]] : !fir.ref>) { +! CHECK: %[[VAL_6:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_5]](%[[VAL_3]]) dummy_scope %[[VAL_6]] {uniq_name = "_QMmFaddressing_cst_shapeEx"} : (!fir.ref>, !fir.shape<2>, !fir.dscope) -> (!fir.ref>, !fir.ref>) +! CHECK: %[[VAL_8:.*]] = arith.constant 2 : index +! CHECK: %[[VAL_9:.*]] = arith.constant 3 : index +! CHECK: %[[VAL_10:.*]] = hlfir.designate %[[VAL_7]]#0 (%[[VAL_8]], %[[VAL_9]]) : (!fir.ref>, index, index) -> !fir.ref +! CHECK: fir.call @_QPtakes_scalar(%[[VAL_10]]) fastmath : (!fir.ref) -> () +! CHECK: acc.yield +! CHECK: } +! CHECK: acc.copyout accPtr(%[[VAL_5]] : !fir.ref>) to varPtr(%[[VAL_4]]#0 : !fir.ref>) {dataClause = #acc, name = "x"} +! CHECK: return +! CHECK: } + +! CHECK-LABEL: func.func @_QMmPaddressing_explicit_shape( +! CHECK-SAME: %[[ARG0:.*]]: !fir.ref> {fir.bindc_name = "x"}, +! CHECK-SAME: %[[ARG1:.*]]: !fir.ref {fir.bindc_name = "n"}, +! CHECK-SAME: %[[ARG2:.*]]: !fir.ref {fir.bindc_name = "m"}) { +! CHECK: %[[VAL_0:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[ARG2]] dummy_scope %[[VAL_0]] {uniq_name = "_QMmFaddressing_explicit_shapeEm"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) +! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[ARG1]] dummy_scope %[[VAL_0]] {uniq_name = "_QMmFaddressing_explicit_shapeEn"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) +! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_2]]#0 : !fir.ref +! CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (i32) -> i64 +! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (i64) -> index +! CHECK: %[[VAL_6:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_7:.*]] = arith.cmpi sgt, %[[VAL_5]], %[[VAL_6]] : index +! CHECK: %[[VAL_8:.*]] = arith.select %[[VAL_7]], %[[VAL_5]], %[[VAL_6]] : index +! CHECK: %[[VAL_9:.*]] = fir.load %[[VAL_1]]#0 : !fir.ref +! CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_9]] : (i32) -> i64 +! CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_10]] : (i64) -> index +! CHECK: %[[VAL_12:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_13:.*]] = arith.cmpi sgt, %[[VAL_11]], %[[VAL_12]] : index +! CHECK: %[[VAL_14:.*]] = arith.select %[[VAL_13]], %[[VAL_11]], %[[VAL_12]] : index +! CHECK: %[[VAL_15:.*]] = fir.shape %[[VAL_8]], %[[VAL_14]] : (index, index) -> !fir.shape<2> +! CHECK: %[[VAL_16:.*]]:2 = hlfir.declare %[[ARG0]](%[[VAL_15]]) dummy_scope %[[VAL_0]] {uniq_name = "_QMmFaddressing_explicit_shapeEx"} : (!fir.ref>, !fir.shape<2>, !fir.dscope) -> (!fir.box>, !fir.ref>) +! CHECK: %[[VAL_17:.*]] = acc.copyin var(%[[VAL_16]]#0 : !fir.box>) -> !fir.box> {dataClause = #acc, name = "x"} +! CHECK: acc.parallel dataOperands(%[[VAL_17]] : !fir.box>) { +! CHECK: %[[VAL_18:.*]] = fir.box_addr %[[VAL_17]] : (!fir.box>) -> !fir.ref> +! CHECK: %[[VAL_19:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_20:.*]]:2 = hlfir.declare %[[VAL_18]](%[[VAL_15]]) dummy_scope %[[VAL_19]] {uniq_name = "_QMmFaddressing_explicit_shapeEx"} : (!fir.ref>, !fir.shape<2>, !fir.dscope) -> (!fir.box>, !fir.ref>) +! CHECK: %[[VAL_21:.*]] = arith.constant 2 : index +! CHECK: %[[VAL_22:.*]] = arith.constant 3 : index +! CHECK: %[[VAL_23:.*]] = hlfir.designate %[[VAL_20]]#0 (%[[VAL_21]], %[[VAL_22]]) : (!fir.box>, index, index) -> !fir.ref +! CHECK: fir.call @_QPtakes_scalar(%[[VAL_23]]) fastmath : (!fir.ref) -> () +! CHECK: acc.yield +! CHECK: } +! CHECK: acc.copyout accVar(%[[VAL_17]] : !fir.box>) to var(%[[VAL_16]]#0 : !fir.box>) {dataClause = #acc, name = "x"} +! CHECK: return +! CHECK: } + +! CHECK-LABEL: func.func @_QMmPaddressing_assumed_shape( +! CHECK-SAME: %[[ARG0:.*]]: !fir.box> {fir.bindc_name = "x"}, +! CHECK-SAME: %[[ARG1:.*]]: !fir.ref {fir.bindc_name = "n"}) { +! CHECK: %[[VAL_0:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[ARG1]] dummy_scope %[[VAL_0]] {uniq_name = "_QMmFaddressing_assumed_shapeEn"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) +! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[ARG0]] dummy_scope %[[VAL_0]] {uniq_name = "_QMmFaddressing_assumed_shapeEx"} : (!fir.box>, !fir.dscope) -> (!fir.box>, !fir.box>) +! CHECK: %[[VAL_3:.*]] = acc.copyin var(%[[VAL_2]]#0 : !fir.box>) -> !fir.box> {dataClause = #acc, name = "x"} +! CHECK: acc.parallel dataOperands(%[[VAL_3]] : !fir.box>) { +! CHECK: %[[VAL_4:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_3]] dummy_scope %[[VAL_4]] skip_rebox {uniq_name = "_QMmFaddressing_assumed_shapeEx"} : (!fir.box>, !fir.dscope) -> (!fir.box>, !fir.box>) +! CHECK: %[[VAL_6:.*]] = arith.constant 2 : index +! CHECK: %[[VAL_7:.*]] = arith.constant 3 : index +! CHECK: %[[VAL_8:.*]] = hlfir.designate %[[VAL_5]]#0 (%[[VAL_6]], %[[VAL_7]]) : (!fir.box>, index, index) -> !fir.ref +! CHECK: fir.call @_QPtakes_scalar(%[[VAL_8]]) fastmath : (!fir.ref) -> () +! CHECK: acc.yield +! CHECK: } +! CHECK: acc.copyout accVar(%[[VAL_3]] : !fir.box>) to var(%[[VAL_2]]#0 : !fir.box>) {dataClause = #acc, name = "x"} +! CHECK: return +! CHECK: } + +! CHECK-LABEL: func.func @_QMmPaddressing_contiguous_assumed_shape( +! CHECK-SAME: %[[ARG0:.*]]: !fir.box> {fir.bindc_name = "x", fir.contiguous}, +! CHECK-SAME: %[[ARG1:.*]]: !fir.ref {fir.bindc_name = "n"}) { +! CHECK: %[[VAL_0:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[ARG1]] dummy_scope %[[VAL_0]] {uniq_name = "_QMmFaddressing_contiguous_assumed_shapeEn"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) +! CHECK: %[[VAL_2:.*]] = fir.box_addr %[[ARG0]] : (!fir.box>) -> !fir.ref> +! CHECK: %[[VAL_3:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_4:.*]]:3 = fir.box_dims %[[ARG0]], %[[VAL_3]] : (!fir.box>, index) -> (index, index, index) +! CHECK: %[[VAL_5:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_6:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_7:.*]]:3 = fir.box_dims %[[ARG0]], %[[VAL_6]] : (!fir.box>, index) -> (index, index, index) +! CHECK: %[[VAL_8:.*]] = arith.constant 1 : index +! CHECK: %[[VAL_9:.*]] = fir.shape_shift %[[VAL_5]], %[[VAL_4]]#1, %[[VAL_8]], %[[VAL_7]]#1 : (index, index, index, index) -> !fir.shapeshift<2> +! CHECK: %[[VAL_10:.*]]:2 = hlfir.declare %[[VAL_2]](%[[VAL_9]]) dummy_scope %[[VAL_0]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMmFaddressing_contiguous_assumed_shapeEx"} : (!fir.ref>, !fir.shapeshift<2>, !fir.dscope) -> (!fir.box>, !fir.ref>) +! CHECK: %[[VAL_11:.*]] = acc.copyin var(%[[VAL_10]]#0 : !fir.box>) -> !fir.box> {dataClause = #acc, name = "x"} +! CHECK: acc.parallel dataOperands(%[[VAL_11]] : !fir.box>) { +! CHECK: %[[VAL_12:.*]] = fir.box_addr %[[VAL_11]] : (!fir.box>) -> !fir.ref> +! CHECK: %[[VAL_13:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_14:.*]]:2 = hlfir.declare %[[VAL_12]](%[[VAL_9]]) dummy_scope %[[VAL_13]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMmFaddressing_contiguous_assumed_shapeEx"} : (!fir.ref>, !fir.shapeshift<2>, !fir.dscope) -> (!fir.box>, !fir.ref>) +! CHECK: %[[VAL_15:.*]] = arith.constant 2 : index +! CHECK: %[[VAL_16:.*]] = arith.constant 3 : index +! CHECK: %[[VAL_17:.*]] = hlfir.designate %[[VAL_14]]#0 (%[[VAL_15]], %[[VAL_16]]) : (!fir.box>, index, index) -> !fir.ref +! CHECK: fir.call @_QPtakes_scalar(%[[VAL_17]]) fastmath : (!fir.ref) -> () +! CHECK: acc.yield +! CHECK: } +! CHECK: acc.copyout accVar(%[[VAL_11]] : !fir.box>) to var(%[[VAL_10]]#0 : !fir.box>) {dataClause = #acc, name = "x"} +! CHECK: return +! CHECK: } + +! CHECK-LABEL: func.func @_QMmPaddressing_pointer( +! CHECK-SAME: %[[ARG0:.*]]: !fir.ref>>> {fir.bindc_name = "x"}) { +! CHECK: %[[VAL_0:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[ARG0]] dummy_scope %[[VAL_0]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMmFaddressing_pointerEx"} : (!fir.ref>>>, !fir.dscope) -> (!fir.ref>>>, !fir.ref>>>) +! CHECK: %[[VAL_2:.*]] = acc.copyin varPtr(%[[VAL_1]]#0 : !fir.ref>>>) -> !fir.ref>>> {dataClause = #acc, name = "x"} +! CHECK: acc.parallel dataOperands(%[[VAL_2]] : !fir.ref>>>) { +! CHECK: %[[VAL_3:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_2]] dummy_scope %[[VAL_3]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMmFaddressing_pointerEx"} : (!fir.ref>>>, !fir.dscope) -> (!fir.ref>>>, !fir.ref>>>) +! CHECK: %[[VAL_5:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref>>> +! CHECK: %[[VAL_6:.*]] = arith.constant 2 : index +! CHECK: %[[VAL_7:.*]] = arith.constant 3 : index +! CHECK: %[[VAL_8:.*]] = hlfir.designate %[[VAL_5]] (%[[VAL_6]], %[[VAL_7]]) : (!fir.box>>, index, index) -> !fir.ref +! CHECK: fir.call @_QPtakes_scalar(%[[VAL_8]]) fastmath : (!fir.ref) -> () +! CHECK: acc.yield +! CHECK: } +! CHECK: acc.copyout accPtr(%[[VAL_2]] : !fir.ref>>>) to varPtr(%[[VAL_1]]#0 : !fir.ref>>>) {dataClause = #acc, name = "x"} +! CHECK: return +! CHECK: } + +! CHECK-LABEL: func.func @_QMmPtest_optional_scalar( +! CHECK-SAME: %[[ARG0:.*]]: !fir.ref {fir.bindc_name = "x", fir.optional}) { +! CHECK: %[[VAL_0:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[ARG0]] dummy_scope %[[VAL_0]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMmFtest_optional_scalarEx"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) +! CHECK: %[[VAL_2:.*]] = acc.copyin varPtr(%[[VAL_1]]#0 : !fir.ref) -> !fir.ref {dataClause = #acc, name = "x"} +! CHECK: acc.parallel dataOperands(%[[VAL_2]] : !fir.ref) { +! CHECK: %[[VAL_3:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_2]] dummy_scope %[[VAL_3]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMmFtest_optional_scalarEx"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) +! CHECK: %[[VAL_5:.*]] = fir.is_present %[[VAL_4]]#0 : (!fir.ref) -> i1 +! CHECK: %[[VAL_6:.*]] = fir.if %[[VAL_5]] -> (!fir.ref) { +! CHECK: fir.result %[[VAL_4]]#0 : !fir.ref +! CHECK: } else { +! CHECK: %[[VAL_7:.*]] = fir.absent !fir.ref +! CHECK: fir.result %[[VAL_7]] : !fir.ref +! CHECK: } +! CHECK: fir.call @_QPtakes_optional_scalar(%[[VAL_6]]) fastmath : (!fir.ref) -> () +! CHECK: acc.yield +! CHECK: } +! CHECK: acc.copyout accPtr(%[[VAL_2]] : !fir.ref) to varPtr(%[[VAL_1]]#0 : !fir.ref) {dataClause = #acc, name = "x"} +! CHECK: return +! CHECK: } + +! CHECK-LABEL: func.func @_QMmPtest_optional_explicit_cst_shape( +! CHECK-SAME: %[[ARG0:.*]]: !fir.ref> {fir.bindc_name = "x", fir.optional}) { +! CHECK: %[[VAL_0:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_1:.*]] = arith.constant 100 : index +! CHECK: %[[VAL_2:.*]] = fir.shape %[[VAL_1]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[ARG0]](%[[VAL_2]]) dummy_scope %[[VAL_0]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMmFtest_optional_explicit_cst_shapeEx"} : (!fir.ref>, !fir.shape<1>, !fir.dscope) -> (!fir.ref>, !fir.ref>) +! CHECK: %[[VAL_4:.*]] = acc.copyin varPtr(%[[VAL_3]]#0 : !fir.ref>) -> !fir.ref> {dataClause = #acc, name = "x"} +! CHECK: acc.parallel dataOperands(%[[VAL_4]] : !fir.ref>) { +! CHECK: %[[VAL_5:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_4]](%[[VAL_2]]) dummy_scope %[[VAL_5]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMmFtest_optional_explicit_cst_shapeEx"} : (!fir.ref>, !fir.shape<1>, !fir.dscope) -> (!fir.ref>, !fir.ref>) +! CHECK: %[[VAL_7:.*]] = fir.is_present %[[VAL_6]]#0 : (!fir.ref>) -> i1 +! CHECK: %[[VAL_8:.*]] = fir.if %[[VAL_7]] -> (!fir.ref>) { +! CHECK: fir.result %[[VAL_6]]#0 : !fir.ref> +! CHECK: } else { +! CHECK: %[[VAL_9:.*]] = fir.absent !fir.ref> +! CHECK: fir.result %[[VAL_9]] : !fir.ref> +! CHECK: } +! CHECK: fir.call @_QPtakes_optional_explicit_cst_shape(%[[VAL_8]]) fastmath : (!fir.ref>) -> () +! CHECK: acc.yield +! CHECK: } +! CHECK: acc.copyout accPtr(%[[VAL_4]] : !fir.ref>) to varPtr(%[[VAL_3]]#0 : !fir.ref>) {dataClause = #acc, name = "x"} +! CHECK: return +! CHECK: } + +! CHECK-LABEL: func.func @_QMmPtest_optional_explicit_shape( +! CHECK-SAME: %[[ARG0:.*]]: !fir.ref> {fir.bindc_name = "x", fir.optional}, +! CHECK-SAME: %[[ARG1:.*]]: !fir.ref {fir.bindc_name = "n"}) { +! CHECK: %[[VAL_0:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[ARG1]] dummy_scope %[[VAL_0]] {uniq_name = "_QMmFtest_optional_explicit_shapeEn"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) +! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_1]]#0 : !fir.ref +! CHECK: %[[VAL_3:.*]] = fir.convert %[[VAL_2]] : (i32) -> i64 +! CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (i64) -> index +! CHECK: %[[VAL_5:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_6:.*]] = arith.cmpi sgt, %[[VAL_4]], %[[VAL_5]] : index +! CHECK: %[[VAL_7:.*]] = arith.select %[[VAL_6]], %[[VAL_4]], %[[VAL_5]] : index +! CHECK: %[[VAL_8:.*]] = fir.shape %[[VAL_7]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_9:.*]]:2 = hlfir.declare %[[ARG0]](%[[VAL_8]]) dummy_scope %[[VAL_0]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMmFtest_optional_explicit_shapeEx"} : (!fir.ref>, !fir.shape<1>, !fir.dscope) -> (!fir.box>, !fir.ref>) +! CHECK: %[[VAL_10:.*]] = acc.copyin varPtr(%[[VAL_9]]#1 : !fir.ref>) -> !fir.ref> {dataClause = #acc, name = "x"} +! CHECK: acc.parallel dataOperands(%[[VAL_10]] : !fir.ref>) { +! CHECK: %[[VAL_11:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_12:.*]]:2 = hlfir.declare %[[VAL_10]](%[[VAL_8]]) dummy_scope %[[VAL_11]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMmFtest_optional_explicit_shapeEx"} : (!fir.ref>, !fir.shape<1>, !fir.dscope) -> (!fir.box>, !fir.ref>) +! CHECK: %[[VAL_13:.*]] = fir.is_present %[[VAL_12]]#0 : (!fir.box>) -> i1 +! CHECK: %[[VAL_14:.*]] = fir.if %[[VAL_13]] -> (!fir.ref>) { +! CHECK: fir.result %[[VAL_12]]#1 : !fir.ref> +! CHECK: } else { +! CHECK: %[[VAL_15:.*]] = fir.absent !fir.ref> +! CHECK: fir.result %[[VAL_15]] : !fir.ref> +! CHECK: } +! CHECK: fir.call @_QPtakes_optional_explicit_shape(%[[VAL_14]], %[[VAL_1]]#0) fastmath : (!fir.ref>, !fir.ref) -> () +! CHECK: acc.yield +! CHECK: } +! CHECK: acc.copyout accPtr(%[[VAL_10]] : !fir.ref>) to varPtr(%[[VAL_9]]#1 : !fir.ref>) {dataClause = #acc, name = "x"} +! CHECK: return +! CHECK: } + +! CHECK-LABEL: func.func @_QMmPtest_optional_assumed_shape( +! CHECK-SAME: %[[ARG0:.*]]: !fir.box> {fir.bindc_name = "x", fir.optional}) { +! CHECK: %[[VAL_0:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[ARG0]] dummy_scope %[[VAL_0]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMmFtest_optional_assumed_shapeEx"} : (!fir.box>, !fir.dscope) -> (!fir.box>, !fir.box>) +! CHECK: %[[VAL_2:.*]] = acc.copyin var(%[[VAL_1]]#0 : !fir.box>) -> !fir.box> {dataClause = #acc, name = "x"} +! CHECK: acc.parallel dataOperands(%[[VAL_2]] : !fir.box>) { +! CHECK: %[[VAL_3:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_2]] dummy_scope %[[VAL_3]] skip_rebox {fortran_attrs = #fir.var_attrs, uniq_name = "_QMmFtest_optional_assumed_shapeEx"} : (!fir.box>, !fir.dscope) -> (!fir.box>, !fir.box>) +! CHECK: %[[VAL_5:.*]] = fir.is_present %[[VAL_4]]#0 : (!fir.box>) -> i1 +! CHECK: %[[VAL_6:.*]] = fir.if %[[VAL_5]] -> (!fir.box>) { +! CHECK: fir.result %[[VAL_4]]#0 : !fir.box> +! CHECK: } else { +! CHECK: %[[VAL_7:.*]] = fir.absent !fir.box> +! CHECK: fir.result %[[VAL_7]] : !fir.box> +! CHECK: } +! CHECK: fir.call @_QPtakes_optional_assumed_shape(%[[VAL_6]]) fastmath : (!fir.box>) -> () +! CHECK: acc.yield +! CHECK: } +! CHECK: acc.copyout accVar(%[[VAL_2]] : !fir.box>) to var(%[[VAL_1]]#0 : !fir.box>) {dataClause = #acc, name = "x"} +! CHECK: return +! CHECK: } + +! CHECK-LABEL: func.func @_QMmPtest_optional_pointer( +! CHECK-SAME: %[[ARG0:.*]]: !fir.ref>>> {fir.bindc_name = "x", fir.optional}) { +! CHECK: %[[VAL_0:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[ARG0]] dummy_scope %[[VAL_0]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMmFtest_optional_pointerEx"} : (!fir.ref>>>, !fir.dscope) -> (!fir.ref>>>, !fir.ref>>>) +! CHECK: %[[VAL_2:.*]] = acc.copyin varPtr(%[[VAL_1]]#0 : !fir.ref>>>) -> !fir.ref>>> {dataClause = #acc, name = "x"} +! CHECK: acc.parallel dataOperands(%[[VAL_2]] : !fir.ref>>>) { +! CHECK: %[[VAL_3:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_2]] dummy_scope %[[VAL_3]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMmFtest_optional_pointerEx"} : (!fir.ref>>>, !fir.dscope) -> (!fir.ref>>>, !fir.ref>>>) +! CHECK: fir.call @_QPtakes_optional_pointer(%[[VAL_4]]#0) fastmath : (!fir.ref>>>) -> () +! CHECK: acc.yield +! CHECK: } +! CHECK: acc.copyout accPtr(%[[VAL_2]] : !fir.ref>>>) to varPtr(%[[VAL_1]]#0 : !fir.ref>>>) {dataClause = #acc, name = "x"} +! CHECK: return +! CHECK: } diff --git a/flang/test/Lower/OpenACC/acc-firstprivate-derived-allocatable-component.f90 b/flang/test/Lower/OpenACC/acc-firstprivate-derived-allocatable-component.f90 index bc94837b0e4f3..429f207bb5669 100644 --- a/flang/test/Lower/OpenACC/acc-firstprivate-derived-allocatable-component.f90 +++ b/flang/test/Lower/OpenACC/acc-firstprivate-derived-allocatable-component.f90 @@ -41,19 +41,21 @@ subroutine test(a) ! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_4]] {uniq_name = "_QMm_firstprivate_derived_alloc_compFtestEn"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: %[[VAL_6:.*]] = acc.firstprivate varPtr(%[[VAL_1]]#0 : !fir.ref>>}>>) -> !fir.ref>>}>> {name = "a"} ! CHECK: acc.parallel combined(loop) firstprivate(@firstprivatization_ref_rec__QMm_firstprivate_derived_alloc_compTpoint -> %[[VAL_6]] : !fir.ref>>}>>) { -! CHECK: %[[VAL_7:.*]] = arith.constant 1 : i32 -! CHECK: %[[VAL_8:.*]] = fir.load %[[VAL_5]]#0 : !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_alloc_compFtestEa"} : (!fir.ref>>}>>, !fir.dscope) -> (!fir.ref>>}>>, !fir.ref>>}>>) ! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i32 -! CHECK: %[[VAL_10:.*]] = acc.private varPtr(%[[VAL_3]]#0 : !fir.ref) -> !fir.ref {implicit = true, name = "i"} -! CHECK: %[[VAL_11:.*]]:2 = hlfir.declare %[[VAL_10]] {uniq_name = "_QMm_firstprivate_derived_alloc_compFtestEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) -! CHECK: acc.loop combined(parallel) private(@privatization_ref_i32 -> %[[VAL_10]] : !fir.ref) control(%[[VAL_12:.*]] : i32) = (%[[VAL_7]] : i32) to (%[[VAL_8]] : i32) step (%[[VAL_9]] : i32) { -! CHECK: fir.store %[[VAL_12]] to %[[VAL_11]]#0 : !fir.ref -! CHECK: %[[VAL_13:.*]] = arith.constant 1.000000e+00 : f32 -! CHECK: %[[VAL_14:.*]] = hlfir.designate %[[VAL_1]]#0{"x"} {fortran_attrs = #fir.var_attrs} : (!fir.ref>>}>>) -> !fir.ref>>> -! CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_14]] : !fir.ref>>> -! CHECK: %[[VAL_16:.*]] = arith.constant 10 : index -! CHECK: %[[VAL_17:.*]] = hlfir.designate %[[VAL_15]] (%[[VAL_16]]) : (!fir.box>>, index) -> !fir.ref -! CHECK: hlfir.assign %[[VAL_13]] to %[[VAL_17]] : f32, !fir.ref +! 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) -> !fir.ref {implicit = true, name = "i"} +! CHECK: acc.loop combined(parallel) private(@privatization_ref_i32 -> %[[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_alloc_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 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 f18d722921710..9ef4fe6913551 100644 --- a/flang/test/Lower/OpenACC/acc-firstprivate-derived-pointer-component.f90 +++ b/flang/test/Lower/OpenACC/acc-firstprivate-derived-pointer-component.f90 @@ -41,19 +41,21 @@ subroutine test(a) ! 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>>}>>) -> !fir.ref>>}>> {name = "a"} ! CHECK: acc.parallel combined(loop) firstprivate(@firstprivatization_ref_rec__QMm_firstprivate_derived_ptr_compTpoint -> %[[VAL_6]] : !fir.ref>>}>>) { -! CHECK: %[[VAL_7:.*]] = arith.constant 1 : i32 -! CHECK: %[[VAL_8:.*]] = fir.load %[[VAL_5]]#0 : !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:.*]] = acc.private varPtr(%[[VAL_3]]#0 : !fir.ref) -> !fir.ref {implicit = true, name = "i"} -! CHECK: %[[VAL_11:.*]]:2 = hlfir.declare %[[VAL_10]] {uniq_name = "_QMm_firstprivate_derived_ptr_compFtestEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) -! CHECK: acc.loop combined(parallel) private(@privatization_ref_i32 -> %[[VAL_10]] : !fir.ref) control(%[[VAL_12:.*]] : i32) = (%[[VAL_7]] : i32) to (%[[VAL_8]] : i32) step (%[[VAL_9]] : i32) { -! CHECK: fir.store %[[VAL_12]] to %[[VAL_11]]#0 : !fir.ref -! CHECK: %[[VAL_13:.*]] = arith.constant 1.000000e+00 : f32 -! CHECK: %[[VAL_14:.*]] = hlfir.designate %[[VAL_1]]#0{"x"} {fortran_attrs = #fir.var_attrs} : (!fir.ref>>}>>) -> !fir.ref>>> -! CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_14]] : !fir.ref>>> -! CHECK: %[[VAL_16:.*]] = arith.constant 10 : index -! CHECK: %[[VAL_17:.*]] = hlfir.designate %[[VAL_15]] (%[[VAL_16]]) : (!fir.box>>, index) -> !fir.ref -! CHECK: hlfir.assign %[[VAL_13]] to %[[VAL_17]] : f32, !fir.ref +! 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) -> !fir.ref {implicit = true, name = "i"} +! CHECK: acc.loop combined(parallel) private(@privatization_ref_i32 -> %[[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 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 f389c46cca55a..e90ec323bd4c7 100644 --- a/flang/test/Lower/OpenACC/acc-firstprivate-derived-user-assign.f90 +++ b/flang/test/Lower/OpenACC/acc-firstprivate-derived-user-assign.f90 @@ -55,16 +55,17 @@ subroutine test() ! CHECK: %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_5]] {uniq_name = "_QMm_firstprivate_derived_user_defFtestEn"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: %[[VAL_7:.*]] = acc.firstprivate varPtr(%[[VAL_2]]#0 : !fir.ref>) -> !fir.ref> {name = "a"} ! CHECK: acc.parallel combined(loop) firstprivate(@firstprivatization_ref_rec__QMm_firstprivate_derived_user_defTpoint -> %[[VAL_7]] : !fir.ref>) { -! CHECK: %[[VAL_8:.*]] = arith.constant 1 : i32 -! CHECK: %[[VAL_9:.*]] = fir.load %[[VAL_6]]#0 : !fir.ref -! CHECK: %[[VAL_10:.*]] = arith.constant 1 : i32 -! CHECK: %[[VAL_11:.*]] = acc.private varPtr(%[[VAL_4]]#0 : !fir.ref) -> !fir.ref {implicit = true, name = "i"} -! CHECK: %[[VAL_12:.*]]:2 = hlfir.declare %[[VAL_11]] {uniq_name = "_QMm_firstprivate_derived_user_defFtestEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) -! CHECK: acc.loop combined(parallel) private(@privatization_ref_i32 -> %[[VAL_11]] : !fir.ref) control(%[[VAL_13:.*]] : i32) = (%[[VAL_8]] : i32) to (%[[VAL_9]] : i32) step (%[[VAL_10]] : i32) { -! CHECK: fir.store %[[VAL_13]] to %[[VAL_12]]#0 : !fir.ref -! CHECK: %[[VAL_14:.*]] = arith.constant 1.000000e+00 : f32 -! CHECK: %[[VAL_15:.*]] = hlfir.designate %[[VAL_2]]#0{"x"} : (!fir.ref>) -> !fir.ref -! CHECK: hlfir.assign %[[VAL_14]] to %[[VAL_15]] : f32, !fir.ref +! CHECK: %[[VAL_8:.*]]:2 = hlfir.declare %[[VAL_7]] {uniq_name = "_QMm_firstprivate_derived_user_defFtestEa"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) +! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i32 +! CHECK: %[[VAL_10:.*]] = fir.load %[[VAL_6]]#0 : !fir.ref +! CHECK: %[[VAL_11:.*]] = arith.constant 1 : i32 +! CHECK: %[[VAL_12:.*]] = acc.private varPtr(%[[VAL_4]]#0 : !fir.ref) -> !fir.ref {implicit = true, name = "i"} +! CHECK: acc.loop combined(parallel) private(@privatization_ref_i32 -> %[[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_user_defFtestEi"} : (!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"} : (!fir.ref>) -> !fir.ref +! CHECK: hlfir.assign %[[VAL_15]] to %[[VAL_16]] : f32, !fir.ref ! CHECK: acc.yield ! CHECK: } attributes {inclusiveUpperbound = array, independent = [#acc.device_type]} ! CHECK: acc.yield diff --git a/flang/test/Lower/OpenACC/acc-firstprivate-derived.f90 b/flang/test/Lower/OpenACC/acc-firstprivate-derived.f90 index 677c3aea4f554..e91fc9b45cd29 100644 --- a/flang/test/Lower/OpenACC/acc-firstprivate-derived.f90 +++ b/flang/test/Lower/OpenACC/acc-firstprivate-derived.f90 @@ -41,16 +41,17 @@ subroutine test() ! CHECK: %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_5]] {uniq_name = "_QMm_firstprivate_derivedFtestEn"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: %[[VAL_7:.*]] = acc.firstprivate varPtr(%[[VAL_2]]#0 : !fir.ref>) -> !fir.ref> {name = "a"} ! CHECK: acc.parallel combined(loop) firstprivate(@firstprivatization_ref_rec__QMm_firstprivate_derivedTpoint -> %[[VAL_7]] : !fir.ref>) { -! CHECK: %[[VAL_8:.*]] = arith.constant 1 : i32 -! CHECK: %[[VAL_9:.*]] = fir.load %[[VAL_6]]#0 : !fir.ref -! CHECK: %[[VAL_10:.*]] = arith.constant 1 : i32 -! CHECK: %[[VAL_11:.*]] = acc.private varPtr(%[[VAL_4]]#0 : !fir.ref) -> !fir.ref {implicit = true, name = "i"} -! CHECK: %[[VAL_12:.*]]:2 = hlfir.declare %[[VAL_11]] {uniq_name = "_QMm_firstprivate_derivedFtestEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) -! CHECK: acc.loop combined(parallel) private(@privatization_ref_i32 -> %[[VAL_11]] : !fir.ref) control(%[[VAL_13:.*]] : i32) = (%[[VAL_8]] : i32) to (%[[VAL_9]] : i32) step (%[[VAL_10]] : i32) { -! CHECK: fir.store %[[VAL_13]] to %[[VAL_12]]#0 : !fir.ref -! CHECK: %[[VAL_14:.*]] = arith.constant 1.000000e+00 : f32 -! CHECK: %[[VAL_15:.*]] = hlfir.designate %[[VAL_2]]#0{"x"} : (!fir.ref>) -> !fir.ref -! CHECK: hlfir.assign %[[VAL_14]] to %[[VAL_15]] : f32, !fir.ref +! CHECK: %[[VAL_8:.*]]:2 = hlfir.declare %[[VAL_7]] {uniq_name = "_QMm_firstprivate_derivedFtestEa"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) +! CHECK: %[[VAL_9:.*]] = arith.constant 1 : i32 +! CHECK: %[[VAL_10:.*]] = fir.load %[[VAL_6]]#0 : !fir.ref +! CHECK: %[[VAL_11:.*]] = arith.constant 1 : i32 +! CHECK: %[[VAL_12:.*]] = acc.private varPtr(%[[VAL_4]]#0 : !fir.ref) -> !fir.ref {implicit = true, name = "i"} +! CHECK: acc.loop combined(parallel) private(@privatization_ref_i32 -> %[[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_derivedFtestEi"} : (!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"} : (!fir.ref>) -> !fir.ref +! CHECK: hlfir.assign %[[VAL_15]] to %[[VAL_16]] : f32, !fir.ref ! CHECK: acc.yield ! CHECK: } attributes {inclusiveUpperbound = array, independent = [#acc.device_type]} ! CHECK: acc.yield diff --git a/flang/test/Lower/OpenACC/acc-loop-exit.f90 b/flang/test/Lower/OpenACC/acc-loop-exit.f90 index 85394e4a5b74c..af11b34d5f65f 100644 --- a/flang/test/Lower/OpenACC/acc-loop-exit.f90 +++ b/flang/test/Lower/OpenACC/acc-loop-exit.f90 @@ -16,8 +16,8 @@ subroutine sub1(x, a) ! CHECK-LABEL: func.func @_QPsub1 ! CHECK: %[[A:.*]]:2 = hlfir.declare %arg1 dummy_scope %{{[0-9]+}} {uniq_name = "_QFsub1Ea"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) ! CHECK: %[[I:.*]]:2 = hlfir.declare %{{[0-9]+}} {uniq_name = "_QFsub1Ei"} : (!fir.ref) -> (!fir.ref, !fir.ref) -! CHECK: %[[I:.*]]:2 = hlfir.declare %{{[0-9]+}} {uniq_name = "_QFsub1Ei"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: %[[EXIT_COND:.*]] = acc.loop +! CHECK: %[[I:.*]]:2 = hlfir.declare %{{[0-9]+}} {uniq_name = "_QFsub1Ei"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: ^bb{{.*}}: ! CHECK: ^bb{{.*}}: ! CHECK: %[[LOAD_I:.*]] = fir.load %[[I]]#0 : !fir.ref diff --git a/flang/test/Lower/OpenACC/acc-private.f90 b/flang/test/Lower/OpenACC/acc-private.f90 index 5ca08a39a1e1c..d37eb8d7aaf6d 100644 --- a/flang/test/Lower/OpenACC/acc-private.f90 +++ b/flang/test/Lower/OpenACC/acc-private.f90 @@ -426,7 +426,7 @@ subroutine acc_private_use() ! CHECK: %[[DECL_I:.*]]:2 = hlfir.declare %[[I]] {uniq_name = "_QFacc_private_useEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: acc.parallel ! CHECK: %[[PRIV_I:.*]] = acc.private varPtr(%[[DECL_I]]#0 : !fir.ref) -> !fir.ref {implicit = true, name = "i"} -! CHECK: %[[DECL_PRIV_I:.*]]:2 = hlfir.declare %[[PRIV_I]] {uniq_name = "_QFacc_private_useEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: acc.loop {{.*}} private(@privatization_ref_i32 -> %[[PRIV_I]] : !fir.ref) control(%[[IV0:.*]] : i32) = (%c1{{.*}} : i32) to (%c10{{.*}} : i32) step (%c1{{.*}} : i32) +! CHECK: %[[DECL_PRIV_I:.*]]:2 = hlfir.declare %[[PRIV_I]] {uniq_name = "_QFacc_private_useEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: fir.store %[[IV0]] to %[[DECL_PRIV_I]]#0 : !fir.ref ! CHECK: %{{.*}} = fir.load %[[DECL_PRIV_I]]#0 : !fir.ref diff --git a/flang/test/Lower/OpenACC/do-loops-to-acc-loops.f90 b/flang/test/Lower/OpenACC/do-loops-to-acc-loops.f90 index a75a022690fcc..eaf734f155157 100644 --- a/flang/test/Lower/OpenACC/do-loops-to-acc-loops.f90 +++ b/flang/test/Lower/OpenACC/do-loops-to-acc-loops.f90 @@ -19,8 +19,8 @@ subroutine basic_do_loop() ! CHECK: acc.kernels { ! CHECK: %[[PRIVATE_IV:.*]] = acc.private varPtr(%{{.*}} : !fir.ref) -> !fir.ref {implicit = true, name = "i"} -! CHECK: %[[PRIVATE_DECLARE:.*]]:2 = hlfir.declare %[[PRIVATE_IV]] {uniq_name = "_QFbasic_do_loopEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: acc.loop private(@privatization_ref_i32 -> %[[PRIVATE_IV]] : !fir.ref) control(%{{.*}} : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) +! CHECK: %[[PRIVATE_DECLARE:.*]]:2 = hlfir.declare %[[PRIVATE_IV]] {uniq_name = "_QFbasic_do_loopEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: fir.store %{{.*}} to %[[PRIVATE_DECLARE]]#0 : !fir.ref ! CHECK: %{{.*}} = fir.load %[[PRIVATE_DECLARE]]#0 : !fir.ref ! CHECK: %{{.*}} = fir.load %[[PRIVATE_DECLARE]]#0 : !fir.ref @@ -48,8 +48,8 @@ subroutine basic_do_concurrent() ! CHECK: acc.kernels { ! CHECK: %[[PRIVATE_IV:.*]] = acc.private varPtr(%{{.*}} : !fir.ref) -> !fir.ref {implicit = true, name = "i"} -! CHECK: %[[PRIVATE_DECLARE:.*]]:2 = hlfir.declare %[[PRIVATE_IV]] {uniq_name = "_QFbasic_do_concurrentEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: acc.loop private(@privatization_ref_i32 -> %[[PRIVATE_IV]] : !fir.ref) control(%{{.*}} : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) +! CHECK: %[[PRIVATE_DECLARE:.*]]:2 = hlfir.declare %[[PRIVATE_IV]] {uniq_name = "_QFbasic_do_concurrentEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: fir.store %{{.*}} to %[[PRIVATE_DECLARE]]#0 : !fir.ref ! CHECK: %{{.*}} = fir.load %[[PRIVATE_DECLARE]]#0 : !fir.ref ! CHECK: %{{.*}} = fir.load %[[PRIVATE_DECLARE]]#0 : !fir.ref @@ -77,8 +77,8 @@ subroutine basic_do_loop_parallel() ! CHECK: acc.parallel { ! CHECK: %[[PRIVATE_IV:.*]] = acc.private varPtr(%{{.*}} : !fir.ref) -> !fir.ref {implicit = true, name = "i"} -! CHECK: %[[PRIVATE_DECLARE:.*]]:2 = hlfir.declare %[[PRIVATE_IV]] {uniq_name = "_QFbasic_do_loop_parallelEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: acc.loop private(@privatization_ref_i32 -> %[[PRIVATE_IV]] : !fir.ref) control(%{{.*}} : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) +! CHECK: %[[PRIVATE_DECLARE:.*]]:2 = hlfir.declare %[[PRIVATE_IV]] {uniq_name = "_QFbasic_do_loop_parallelEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: fir.store %{{.*}} to %[[PRIVATE_DECLARE]]#0 : !fir.ref ! CHECK: %{{.*}} = fir.load %[[PRIVATE_DECLARE]]#0 : !fir.ref ! CHECK: %{{.*}} = fir.load %[[PRIVATE_DECLARE]]#0 : !fir.ref @@ -106,8 +106,8 @@ subroutine basic_do_loop_serial() ! CHECK: acc.serial { ! CHECK: %[[PRIVATE_IV:.*]] = acc.private varPtr(%{{.*}} : !fir.ref) -> !fir.ref {implicit = true, name = "i"} -! CHECK: %[[PRIVATE_DECLARE:.*]]:2 = hlfir.declare %[[PRIVATE_IV]] {uniq_name = "_QFbasic_do_loop_serialEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: acc.loop private(@privatization_ref_i32 -> %[[PRIVATE_IV]] : !fir.ref) control(%{{.*}} : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) +! CHECK: %[[PRIVATE_DECLARE:.*]]:2 = hlfir.declare %[[PRIVATE_IV]] {uniq_name = "_QFbasic_do_loop_serialEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: fir.store %{{.*}} to %[[PRIVATE_DECLARE]]#0 : !fir.ref ! CHECK: %{{.*}} = fir.load %[[PRIVATE_DECLARE]]#0 : !fir.ref ! CHECK: %{{.*}} = fir.load %[[PRIVATE_DECLARE]]#0 : !fir.ref @@ -135,8 +135,8 @@ subroutine basic_do_concurrent_parallel() ! CHECK: acc.parallel { ! CHECK: %[[PRIVATE_IV:.*]] = acc.private varPtr(%{{.*}} : !fir.ref) -> !fir.ref {implicit = true, name = "i"} -! CHECK: %[[PRIVATE_DECLARE:.*]]:2 = hlfir.declare %[[PRIVATE_IV]] {uniq_name = "_QFbasic_do_concurrent_parallelEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: acc.loop private(@privatization_ref_i32 -> %[[PRIVATE_IV]] : !fir.ref) control(%{{.*}} : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) +! CHECK: %[[PRIVATE_DECLARE:.*]]:2 = hlfir.declare %[[PRIVATE_IV]] {uniq_name = "_QFbasic_do_concurrent_parallelEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: fir.store %{{.*}} to %[[PRIVATE_DECLARE]]#0 : !fir.ref ! CHECK: %{{.*}} = fir.load %[[PRIVATE_DECLARE]]#0 : !fir.ref ! CHECK: %{{.*}} = fir.load %[[PRIVATE_DECLARE]]#0 : !fir.ref @@ -164,8 +164,8 @@ subroutine basic_do_concurrent_serial() ! CHECK: acc.serial { ! CHECK: %[[PRIVATE_IV:.*]] = acc.private varPtr(%{{.*}} : !fir.ref) -> !fir.ref {implicit = true, name = "i"} -! CHECK: %[[PRIVATE_DECLARE:.*]]:2 = hlfir.declare %[[PRIVATE_IV]] {uniq_name = "_QFbasic_do_concurrent_serialEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: acc.loop private(@privatization_ref_i32 -> %[[PRIVATE_IV]] : !fir.ref) control(%{{.*}} : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) +! CHECK: %[[PRIVATE_DECLARE:.*]]:2 = hlfir.declare %[[PRIVATE_IV]] {uniq_name = "_QFbasic_do_concurrent_serialEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: fir.store %{{.*}} to %[[PRIVATE_DECLARE]]#0 : !fir.ref ! CHECK: %{{.*}} = fir.load %[[PRIVATE_DECLARE]]#0 : !fir.ref ! CHECK: %{{.*}} = fir.load %[[PRIVATE_DECLARE]]#0 : !fir.ref @@ -195,10 +195,10 @@ subroutine multi_dimension_do_concurrent() ! CHECK-DAG: %[[PRIVATE_I:.*]] = acc.private varPtr(%{{.*}} : !fir.ref) -> !fir.ref {implicit = true, name = "i"} ! CHECK-DAG: %[[PRIVATE_J:.*]] = acc.private varPtr(%{{.*}} : !fir.ref) -> !fir.ref {implicit = true, name = "j"} ! CHECK-DAG: %[[PRIVATE_K:.*]] = acc.private varPtr(%{{.*}} : !fir.ref) -> !fir.ref {implicit = true, name = "k"} +! CHECK: acc.loop private(@privatization_ref_i32 -> %[[PRIVATE_I]] : !fir.ref, @privatization_ref_i32 -> %[[PRIVATE_J]] : !fir.ref, @privatization_ref_i32 -> %[[PRIVATE_K]] : !fir.ref) control(%{{.*}} : i32, %{{.*}} : i32, %{{.*}} : i32) = (%c1{{.*}}, %c1{{.*}}, %c1{{.*}} : i32, i32, i32) to (%{{.*}}, %{{.*}}, %{{.*}} : i32, i32, i32) step (%c1{{.*}}, %c1{{.*}}, %c1{{.*}} : i32, i32, i32) ! CHECK-DAG: %[[PRIVATE_I_DECLARE:.*]]:2 = hlfir.declare %[[PRIVATE_I]] {uniq_name = "_QFmulti_dimension_do_concurrentEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK-DAG: %[[PRIVATE_J_DECLARE:.*]]:2 = hlfir.declare %[[PRIVATE_J]] {uniq_name = "_QFmulti_dimension_do_concurrentEj"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK-DAG: %[[PRIVATE_K_DECLARE:.*]]:2 = hlfir.declare %[[PRIVATE_K]] {uniq_name = "_QFmulti_dimension_do_concurrentEk"} : (!fir.ref) -> (!fir.ref, !fir.ref) -! CHECK: acc.loop private(@privatization_ref_i32 -> %[[PRIVATE_I]] : !fir.ref, @privatization_ref_i32 -> %[[PRIVATE_J]] : !fir.ref, @privatization_ref_i32 -> %[[PRIVATE_K]] : !fir.ref) control(%{{.*}} : i32, %{{.*}} : i32, %{{.*}} : i32) = (%c1{{.*}}, %c1{{.*}}, %c1{{.*}} : i32, i32, i32) to (%{{.*}}, %{{.*}}, %{{.*}} : i32, i32, i32) step (%c1{{.*}}, %c1{{.*}}, %c1{{.*}} : i32, i32, i32) ! CHECK: fir.store %{{.*}} to %[[PRIVATE_I_DECLARE]]#0 : !fir.ref ! CHECK: fir.store %{{.*}} to %[[PRIVATE_J_DECLARE]]#0 : !fir.ref ! CHECK: fir.store %{{.*}} to %[[PRIVATE_K_DECLARE]]#0 : !fir.ref @@ -235,12 +235,12 @@ subroutine nested_do_loops() ! CHECK: acc.kernels { ! CHECK-DAG: %[[PRIVATE_I:.*]] = acc.private varPtr(%{{.*}} : !fir.ref) -> !fir.ref {implicit = true, name = "i"} -! CHECK-DAG: %[[PRIVATE_I_DECLARE:.*]]:2 = hlfir.declare %[[PRIVATE_I]] {uniq_name = "_QFnested_do_loopsEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: acc.loop private(@privatization_ref_i32 -> %[[PRIVATE_I]] : !fir.ref) control(%{{.*}} : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) +! CHECK-DAG: %[[PRIVATE_I_DECLARE:.*]]:2 = hlfir.declare %[[PRIVATE_I]] {uniq_name = "_QFnested_do_loopsEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: fir.store %{{.*}} to %[[PRIVATE_I_DECLARE]]#0 : !fir.ref ! CHECK-DAG: %[[PRIVATE_J:.*]] = acc.private varPtr(%{{.*}} : !fir.ref) -> !fir.ref {implicit = true, name = "j"} -! CHECK-DAG: %[[PRIVATE_J_DECLARE:.*]]:2 = hlfir.declare %[[PRIVATE_J]] {uniq_name = "_QFnested_do_loopsEj"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: acc.loop private(@privatization_ref_i32 -> %[[PRIVATE_J]] : !fir.ref) control(%{{.*}} : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) +! CHECK-DAG: %[[PRIVATE_J_DECLARE:.*]]:2 = hlfir.declare %[[PRIVATE_J]] {uniq_name = "_QFnested_do_loopsEj"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: fir.store %{{.*}} to %[[PRIVATE_J_DECLARE]]#0 : !fir.ref ! CHECK: %{{.*}} = fir.load %[[PRIVATE_I_DECLARE]]#0 : !fir.ref ! CHECK: %{{.*}} = fir.load %[[PRIVATE_J_DECLARE]]#0 : !fir.ref @@ -272,8 +272,8 @@ subroutine variable_bounds_and_step(n, start_val, step_val) ! CHECK: acc.kernels { ! CHECK: %[[PRIVATE_IV:.*]] = acc.private varPtr(%{{.*}} : !fir.ref) -> !fir.ref {implicit = true, name = "i"} -! CHECK: %[[PRIVATE_DECLARE:.*]]:2 = hlfir.declare %[[PRIVATE_IV]] {uniq_name = "_QFvariable_bounds_and_stepEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: acc.loop private(@privatization_ref_i32 -> %[[PRIVATE_IV]] : !fir.ref) control(%{{.*}} : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) +! CHECK: %[[PRIVATE_DECLARE:.*]]:2 = hlfir.declare %[[PRIVATE_IV]] {uniq_name = "_QFvariable_bounds_and_stepEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: fir.store %{{.*}} to %[[PRIVATE_DECLARE]]#0 : !fir.ref ! CHECK: %{{.*}} = fir.load %[[PRIVATE_DECLARE]]#0 : !fir.ref ! CHECK: %{{.*}} = fir.load %[[PRIVATE_DECLARE]]#0 : !fir.ref @@ -315,22 +315,22 @@ subroutine different_iv_types() ! CHECK: acc.kernels { ! CHECK: %[[PRIVATE_I8:.*]] = acc.private varPtr(%{{.*}} : !fir.ref) -> !fir.ref {implicit = true, name = "i8"} -! CHECK: %[[PRIVATE_I8_DECLARE:.*]]:2 = hlfir.declare %[[PRIVATE_I8]] {uniq_name = "_QFdifferent_iv_typesEi8"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: acc.loop private(@privatization_ref_i64 -> %[[PRIVATE_I8]] : !fir.ref) control(%{{.*}} : i64) = (%{{.*}} : i64) to (%{{.*}} : i64) step (%{{.*}} : i64) +! CHECK: %[[PRIVATE_I8_DECLARE:.*]]:2 = hlfir.declare %[[PRIVATE_I8]] {uniq_name = "_QFdifferent_iv_typesEi8"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: fir.store %{{.*}} to %[[PRIVATE_I8_DECLARE]]#0 : !fir.ref ! CHECK: %{{.*}} = fir.load %[[PRIVATE_I8_DECLARE]]#0 : !fir.ref ! CHECK: %{{.*}} = fir.load %[[PRIVATE_I8_DECLARE]]#0 : !fir.ref ! CHECK: acc.kernels { ! CHECK: %[[PRIVATE_I4:.*]] = acc.private varPtr(%{{.*}} : !fir.ref) -> !fir.ref {implicit = true, name = "i4"} -! CHECK: %[[PRIVATE_I4_DECLARE:.*]]:2 = hlfir.declare %[[PRIVATE_I4]] {uniq_name = "_QFdifferent_iv_typesEi4"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: acc.loop private(@privatization_ref_i32 -> %[[PRIVATE_I4]] : !fir.ref) control(%{{.*}} : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) +! CHECK: %[[PRIVATE_I4_DECLARE:.*]]:2 = hlfir.declare %[[PRIVATE_I4]] {uniq_name = "_QFdifferent_iv_typesEi4"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: fir.store %{{.*}} to %[[PRIVATE_I4_DECLARE]]#0 : !fir.ref ! CHECK: %{{.*}} = fir.load %[[PRIVATE_I4_DECLARE]]#0 : !fir.ref ! CHECK: %{{.*}} = fir.load %[[PRIVATE_I4_DECLARE]]#0 : !fir.ref ! CHECK: acc.kernels { ! CHECK: %[[PRIVATE_I2:.*]] = acc.private varPtr(%{{.*}} : !fir.ref) -> !fir.ref {implicit = true, name = "i2"} -! CHECK: %[[PRIVATE_I2_DECLARE:.*]]:2 = hlfir.declare %[[PRIVATE_I2]] {uniq_name = "_QFdifferent_iv_typesEi2"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: acc.loop private(@privatization_ref_i16 -> %[[PRIVATE_I2]] : !fir.ref) control(%{{.*}} : i16) = (%{{.*}} : i16) to (%{{.*}} : i16) step (%{{.*}} : i16) +! CHECK: %[[PRIVATE_I2_DECLARE:.*]]:2 = hlfir.declare %[[PRIVATE_I2]] {uniq_name = "_QFdifferent_iv_typesEi2"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: fir.store %{{.*}} to %[[PRIVATE_I2_DECLARE]]#0 : !fir.ref ! CHECK: %{{.*}} = fir.load %[[PRIVATE_I2_DECLARE]]#0 : !fir.ref ! CHECK: %{{.*}} = fir.load %[[PRIVATE_I2_DECLARE]]#0 : !fir.ref @@ -362,12 +362,12 @@ subroutine nested_loop_with_reduction(x, y) ! CHECK: %[[REDUCTION_X:.*]] = acc.reduction varPtr(%{{.*}} : !fir.ref) -> !fir.ref {name = "x"} ! CHECK: %[[REDUCTION_Y:.*]] = acc.reduction varPtr(%{{.*}} : !fir.ref) -> !fir.ref {name = "y"} ! CHECK: %[[PRIVATE_I:.*]] = acc.private varPtr(%{{.*}} : !fir.ref) -> !fir.ref {implicit = true, name = "i"} -! CHECK: %[[PRIVATE_I_DECLARE:.*]]:2 = hlfir.declare %[[PRIVATE_I]] {uniq_name = "_QFnested_loop_with_reductionEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: acc.loop private(@privatization_ref_i32 -> %[[PRIVATE_I]] : !fir.ref) reduction(@reduction_add_ref_i32 -> %[[REDUCTION_X]] : !fir.ref, @reduction_add_ref_i32 -> %[[REDUCTION_Y]] : !fir.ref) control(%{{.*}} : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) +! CHECK: %[[PRIVATE_I_DECLARE:.*]]:2 = hlfir.declare %[[PRIVATE_I]] {uniq_name = "_QFnested_loop_with_reductionEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: fir.store %{{.*}} to %[[PRIVATE_I_DECLARE]]#0 : !fir.ref ! CHECK: %[[PRIVATE_J:.*]] = acc.private varPtr(%{{.*}} : !fir.ref) -> !fir.ref {implicit = true, name = "j"} -! CHECK: %[[PRIVATE_J_DECLARE:.*]]:2 = hlfir.declare %[[PRIVATE_J]] {uniq_name = "_QFnested_loop_with_reductionEj"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: acc.loop private(@privatization_ref_i32 -> %[[PRIVATE_J]] : !fir.ref) control(%{{.*}} : i32) = (%{{.*}} : i32) to (%{{.*}} : i32) step (%{{.*}} : i32) +! CHECK: %[[PRIVATE_J_DECLARE:.*]]:2 = hlfir.declare %[[PRIVATE_J]] {uniq_name = "_QFnested_loop_with_reductionEj"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: fir.store %{{.*}} to %[[PRIVATE_J_DECLARE]]#0 : !fir.ref ! CHECK: %{{.*}} = fir.load %{{.*}} : !fir.ref ! CHECK: %{{.*}} = arith.addi %{{.*}}, %{{.*}} : i32