diff --git a/flang/include/flang/Optimizer/Builder/HLFIRTools.h b/flang/include/flang/Optimizer/Builder/HLFIRTools.h index 9f7c10c2b06c2..891373e8dbb0a 100644 --- a/flang/include/flang/Optimizer/Builder/HLFIRTools.h +++ b/flang/include/flang/Optimizer/Builder/HLFIRTools.h @@ -450,6 +450,41 @@ mlir::Value inlineElementalOp( mlir::IRMapping &mapper, const std::function &mustRecursivelyInline); +/// Generate an element-by-element assignment from \p rhs to \p lhs for arrays +/// that are known not to alias. The assignment is performed using a loop nest +/// over the optimal extents deduced from both shapes. If \p emitWorkshareLoop +/// is true, a workshare loop construct may be emitted when available. +/// Allocatable LHS must be allocated with the right shape and parameters. +void genNoAliasArrayAssignment( + mlir::Location loc, fir::FirOpBuilder &builder, hlfir::Entity rhs, + hlfir::Entity lhs, bool emitWorkshareLoop = false, + bool temporaryLHS = false, + std::function *combiner = + nullptr); + +/// Generate an assignment from \p rhs to \p lhs when they are known not to +/// alias. Handles both arrays and scalars: for arrays, delegates to +/// genNoAliasArrayAssignment; for scalars, performs load/store for trivial +/// scalar types and falls back to hlfir.assign otherwise. +/// Allocatable LHS must be allocated with the right shape and parameters. +void genNoAliasAssignment( + mlir::Location loc, fir::FirOpBuilder &builder, hlfir::Entity rhs, + hlfir::Entity lhs, bool emitWorkshareLoop = false, + bool temporaryLHS = false, + std::function *combiner = + nullptr); +inline void genNoAliasAssignment( + mlir::Location loc, fir::FirOpBuilder &builder, hlfir::Entity rhs, + hlfir::Entity lhs, bool emitWorkshareLoop, bool temporaryLHS, + std::function + combiner) { + genNoAliasAssignment(loc, builder, rhs, lhs, emitWorkshareLoop, temporaryLHS, + &combiner); +} + /// Create a new temporary with the shape and parameters of the provided /// hlfir.eval_in_mem operation and clone the body of the hlfir.eval_in_mem /// operating on this new temporary. returns the temporary and whether the diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp index 1f75ed1d8e6a1..6208bed6d0aea 100644 --- a/flang/lib/Lower/OpenACC.cpp +++ b/flang/lib/Lower/OpenACC.cpp @@ -1196,59 +1196,6 @@ genConstantBounds(fir::FirOpBuilder &builder, mlir::Location loc, return {lb, ub, step}; } -static mlir::Value genShapeFromBoundsOrArgs( - mlir::Location loc, fir::FirOpBuilder &builder, fir::SequenceType seqTy, - const llvm::SmallVector &bounds, mlir::ValueRange arguments) { - llvm::SmallVector args; - if (bounds.empty() && seqTy) { - if (seqTy.hasDynamicExtents()) { - assert(!arguments.empty() && "arguments must hold the entity"); - auto entity = hlfir::Entity{arguments[0]}; - return hlfir::genShape(loc, builder, entity); - } - return genShapeOp(builder, seqTy, loc).getResult(); - } else if (areAllBoundConstant(bounds)) { - for (auto bound : llvm::reverse(bounds)) { - auto dataBound = - mlir::cast(bound.getDefiningOp()); - args.append(genConstantBounds(builder, loc, dataBound)); - } - } else { - assert(((arguments.size() - 2) / 3 == seqTy.getDimension()) && - "Expect 3 block arguments per dimension"); - for (auto arg : arguments.drop_front(2)) - args.push_back(arg); - } - - assert(args.size() % 3 == 0 && "Triplets must be a multiple of 3"); - llvm::SmallVector extents; - mlir::Type idxTy = builder.getIndexType(); - mlir::Value one = builder.createIntegerConstant(loc, idxTy, 1); - mlir::Value zero = builder.createIntegerConstant(loc, idxTy, 0); - for (unsigned i = 0; i < args.size(); i += 3) { - mlir::Value s1 = - mlir::arith::SubIOp::create(builder, loc, args[i + 1], args[0]); - mlir::Value s2 = mlir::arith::AddIOp::create(builder, loc, s1, one); - mlir::Value s3 = - mlir::arith::DivSIOp::create(builder, loc, s2, args[i + 2]); - mlir::Value cmp = mlir::arith::CmpIOp::create( - builder, loc, mlir::arith::CmpIPredicate::sgt, s3, zero); - mlir::Value ext = - mlir::arith::SelectOp::create(builder, loc, cmp, s3, zero); - extents.push_back(ext); - } - return fir::ShapeOp::create(builder, loc, extents); -} - -static hlfir::DesignateOp::Subscripts -getSubscriptsFromArgs(mlir::ValueRange args) { - hlfir::DesignateOp::Subscripts triplets; - for (unsigned i = 2; i < args.size(); i += 3) - triplets.emplace_back( - hlfir::DesignateOp::Triplet{args[i], args[i + 1], args[i + 2]}); - return triplets; -} - static hlfir::Entity genDesignateWithTriplets( fir::FirOpBuilder &builder, mlir::Location loc, hlfir::Entity &entity, hlfir::DesignateOp::Subscripts &triplets, mlir::Value shape) { @@ -1262,19 +1209,88 @@ static hlfir::Entity genDesignateWithTriplets( return hlfir::Entity{designate.getResult()}; } -mlir::acc::FirstprivateRecipeOp Fortran::lower::createOrGetFirstprivateRecipe( - fir::FirOpBuilder &builder, llvm::StringRef recipeName, mlir::Location loc, - mlir::Type ty, llvm::SmallVector &bounds) { - mlir::ModuleOp mod = - builder.getBlock()->getParent()->getParentOfType(); - if (auto recipe = - mod.lookupSymbol(recipeName)) - return recipe; +// Designate uses triplets based on object lower bounds while acc.bounds are +// zero based. This helper shift the bounds to create the designate triplets. +static hlfir::DesignateOp::Subscripts +genTripletsFromAccBounds(fir::FirOpBuilder &builder, mlir::Location loc, + const llvm::SmallVector &accBounds, + hlfir::Entity entity) { + assert(entity.getRank() * 3 == static_cast(accBounds.size()) && + "must get lb,ub,step for each dimension"); + hlfir::DesignateOp::Subscripts triplets; + for (unsigned i = 0; i < accBounds.size(); i += 3) { + mlir::Value lb = hlfir::genLBound(loc, builder, entity, i / 3); + lb = builder.createConvert(loc, accBounds[i].getType(), lb); + assert(accBounds[i].getType() == accBounds[i + 1].getType() && + "mix of integer types in triplets"); + mlir::Value sliceLB = + builder.createOrFold(loc, accBounds[i], lb); + mlir::Value sliceUB = + builder.createOrFold(loc, accBounds[i + 1], lb); + triplets.emplace_back( + hlfir::DesignateOp::Triplet{sliceLB, sliceUB, accBounds[i + 2]}); + } + return triplets; +} - auto ip = builder.saveInsertionPoint(); - auto recipe = genRecipeOp( - builder, mod, recipeName, loc, ty); - bool allConstantBound = areAllBoundConstant(bounds); +static std::pair +genArraySectionsInRecipe(fir::FirOpBuilder &builder, mlir::Location loc, + llvm::SmallVector &dataOperationBounds, + mlir::ValueRange recipeArguments, + bool allConstantBound, hlfir::Entity lhs, + hlfir::Entity rhs) { + lhs = hlfir::derefPointersAndAllocatables(loc, builder, lhs); + rhs = hlfir::derefPointersAndAllocatables(loc, builder, rhs); + // Get the list of lb,ub,step values for the sections that can be used inside + // the recipe region. + llvm::SmallVector bounds; + if (allConstantBound) { + // For constant bounds, the bounds are not region arguments. Materialize + // constants looking at the IR for the bounds on the data operation. + for (auto bound : dataOperationBounds) { + auto dataBound = + mlir::cast(bound.getDefiningOp()); + bounds.append(genConstantBounds(builder, loc, dataBound)); + } + } else { + // If one bound is not constant, all of the bounds are region arguments. + for (auto arg : recipeArguments.drop_front(2)) + bounds.push_back(arg); + } + // Compute the fir.shape of the array section and the triplets to create + // hlfir.designate. + assert(lhs.getRank() * 3 == static_cast(bounds.size()) && + "must get lb,ub,step for each dimension"); + llvm::SmallVector extents; + mlir::Type idxTy = builder.getIndexType(); + for (unsigned i = 0; i < bounds.size(); i += 3) + extents.push_back(builder.genExtentFromTriplet( + loc, bounds[i], bounds[i + 1], bounds[i + 2], idxTy)); + mlir::Value shape = fir::ShapeOp::create(builder, loc, extents); + hlfir::DesignateOp::Subscripts rhsTriplets = + genTripletsFromAccBounds(builder, loc, bounds, rhs); + hlfir::DesignateOp::Subscripts lhsTriplets; + // Share the bounds when both rhs/lhs are known to be 1-based to avoid noise + // in the IR for the most common cases. + if (!lhs.mayHaveNonDefaultLowerBounds() && + !rhs.mayHaveNonDefaultLowerBounds()) + lhsTriplets = rhsTriplets; + else + lhsTriplets = genTripletsFromAccBounds(builder, loc, bounds, lhs); + hlfir::Entity leftSection = + genDesignateWithTriplets(builder, loc, lhs, lhsTriplets, shape); + hlfir::Entity rightSection = + genDesignateWithTriplets(builder, loc, rhs, rhsTriplets, shape); + return {leftSection, rightSection}; +} + +// Generate the combiner or copy region block and block arguments and return the +// source and destination entities. +static std::pair +genRecipeCombinerOrCopyRegion(fir::FirOpBuilder &builder, mlir::Location loc, + mlir::Type ty, mlir::Region ®ion, + llvm::SmallVector &bounds, + bool allConstantBound) { llvm::SmallVector argsTy{ty, ty}; llvm::SmallVector argsLoc{loc, loc}; if (!allConstantBound) { @@ -1289,72 +1305,56 @@ mlir::acc::FirstprivateRecipeOp Fortran::lower::createOrGetFirstprivateRecipe( argsLoc.push_back(dataBound.getStartIdx().getLoc()); } } - builder.createBlock(&recipe.getCopyRegion(), recipe.getCopyRegion().end(), - argsTy, argsLoc); + mlir::Block *block = + builder.createBlock(®ion, region.end(), argsTy, argsLoc); + builder.setInsertionPointToEnd(®ion.back()); + return {hlfir::Entity{block->getArgument(0)}, + hlfir::Entity{block->getArgument(1)}}; +} - builder.setInsertionPointToEnd(&recipe.getCopyRegion().back()); - ty = fir::unwrapRefType(ty); - if (fir::isa_trivial(ty)) { - mlir::Value initValue = fir::LoadOp::create( - builder, loc, recipe.getCopyRegion().front().getArgument(0)); - fir::StoreOp::create(builder, loc, initValue, - recipe.getCopyRegion().front().getArgument(1)); - } else if (auto seqTy = mlir::dyn_cast_or_null(ty)) { - fir::FirOpBuilder firBuilder{builder, recipe.getOperation()}; - auto shape = genShapeFromBoundsOrArgs( - loc, firBuilder, seqTy, bounds, recipe.getCopyRegion().getArguments()); - - auto leftDeclOp = hlfir::DeclareOp::create( - builder, loc, recipe.getCopyRegion().getArgument(0), llvm::StringRef{}, - shape); - auto rightDeclOp = hlfir::DeclareOp::create( - builder, loc, recipe.getCopyRegion().getArgument(1), llvm::StringRef{}, - shape); - - hlfir::DesignateOp::Subscripts triplets = - getSubscriptsFromArgs(recipe.getCopyRegion().getArguments()); - auto leftEntity = hlfir::Entity{leftDeclOp.getBase()}; - auto left = - genDesignateWithTriplets(firBuilder, loc, leftEntity, triplets, shape); - auto rightEntity = hlfir::Entity{rightDeclOp.getBase()}; - auto right = - genDesignateWithTriplets(firBuilder, loc, rightEntity, triplets, shape); - - hlfir::AssignOp::create(firBuilder, loc, left, right); - - } else if (auto boxTy = mlir::dyn_cast_or_null(ty)) { - fir::FirOpBuilder firBuilder{builder, recipe.getOperation()}; - llvm::SmallVector tripletArgs; - mlir::Type innerTy = fir::extractSequenceType(boxTy); - fir::SequenceType seqTy = - mlir::dyn_cast_or_null(innerTy); - if (!seqTy) - TODO(loc, "Unsupported boxed type in OpenACC firstprivate"); - - auto shape = genShapeFromBoundsOrArgs( - loc, firBuilder, seqTy, bounds, recipe.getCopyRegion().getArguments()); - hlfir::DesignateOp::Subscripts triplets = - getSubscriptsFromArgs(recipe.getCopyRegion().getArguments()); - auto leftEntity = hlfir::Entity{recipe.getCopyRegion().getArgument(0)}; - auto left = - genDesignateWithTriplets(firBuilder, loc, leftEntity, triplets, shape); - auto rightEntity = hlfir::Entity{recipe.getCopyRegion().getArgument(1)}; - auto right = - genDesignateWithTriplets(firBuilder, loc, rightEntity, triplets, shape); - hlfir::AssignOp::create(firBuilder, loc, left, right); - } else { - // Copy scalar derived type. - // The temporary_lhs flag allows indicating that user defined assignments - // should not be called while copying components, and that the LHS and RHS - // are known to not alias since the LHS is a created object. - hlfir::AssignOp::create( - builder, loc, recipe.getCopyRegion().getArgument(0), - recipe.getCopyRegion().getArgument(1), /*realloc=*/false, - /*keep_lhs_length_if_realloc=*/false, /*temporary_lhs=*/true); - } +mlir::acc::FirstprivateRecipeOp Fortran::lower::createOrGetFirstprivateRecipe( + fir::FirOpBuilder &builder, llvm::StringRef recipeName, mlir::Location loc, + mlir::Type ty, llvm::SmallVector &bounds) { + mlir::ModuleOp mod = + builder.getBlock()->getParent()->getParentOfType(); + if (auto recipe = + mod.lookupSymbol(recipeName)) + return recipe; + + mlir::OpBuilder::InsertionGuard guard(builder); + auto recipe = genRecipeOp( + builder, mod, recipeName, loc, ty); + bool allConstantBound = areAllBoundConstant(bounds); + auto [source, destination] = genRecipeCombinerOrCopyRegion( + builder, loc, ty, recipe.getCopyRegion(), bounds, allConstantBound); + fir::FirOpBuilder firBuilder{builder, recipe.getOperation()}; + + source = hlfir::derefPointersAndAllocatables(loc, builder, source); + destination = hlfir::derefPointersAndAllocatables(loc, builder, destination); + + if (!bounds.empty()) + std::tie(source, destination) = genArraySectionsInRecipe( + firBuilder, loc, bounds, recipe.getCopyRegion().getArguments(), + allConstantBound, source, destination); + // The source and the destination of the firstprivate copy cannot alias, + // the destination is already properly allocated, so a simple assignment + // can be generated right away to avoid ending-up with runtime calls + // for arrays of numerical, logical and, character types. + // + // The temporary_lhs flag allows indicating that user defined assignments + // should not be called while copying components, and that the LHS and RHS + // are known to not alias since the LHS is a created object. + // + // TODO: detect cases where user defined assignment is needed and add a TODO. + // using temporary_lhs allows more aggressive optimizations of simple derived + // types. Existing compilers supporting OpenACC do not call user defined + // assignments, some use case is needed to decide what to do. + source = hlfir::loadTrivialScalar(loc, builder, source); + hlfir::AssignOp::create(builder, loc, source, destination, /*realloc=*/false, + /*keep_lhs_length_if_realloc=*/false, + /*temporary_lhs=*/true); mlir::acc::TerminatorOp::create(builder, loc); - builder.restoreInsertionPoint(ip); return recipe; } @@ -1611,205 +1611,6 @@ static mlir::Value genScalarCombiner(fir::FirOpBuilder &builder, TODO(loc, "reduction operator"); } -static hlfir::DesignateOp::Subscripts -getTripletsFromArgs(mlir::acc::ReductionRecipeOp recipe) { - hlfir::DesignateOp::Subscripts triplets; - for (unsigned i = 2; i < recipe.getCombinerRegion().getArguments().size(); - i += 3) - triplets.emplace_back(hlfir::DesignateOp::Triplet{ - recipe.getCombinerRegion().getArgument(i), - recipe.getCombinerRegion().getArgument(i + 1), - recipe.getCombinerRegion().getArgument(i + 2)}); - return triplets; -} - -static void genCombiner(fir::FirOpBuilder &builder, mlir::Location loc, - mlir::acc::ReductionOperator op, mlir::Type ty, - mlir::Value value1, mlir::Value value2, - mlir::acc::ReductionRecipeOp &recipe, - llvm::SmallVector &bounds, - bool allConstantBound) { - ty = fir::unwrapRefType(ty); - - if (auto seqTy = mlir::dyn_cast(ty)) { - mlir::Type refTy = fir::ReferenceType::get(seqTy.getEleTy()); - llvm::SmallVector loops; - llvm::SmallVector ivs; - if (seqTy.hasDynamicExtents()) { - auto shape = - genShapeFromBoundsOrArgs(loc, builder, seqTy, bounds, - recipe.getCombinerRegion().getArguments()); - auto v1DeclareOp = hlfir::DeclareOp::create(builder, loc, value1, - llvm::StringRef{}, shape); - auto v2DeclareOp = hlfir::DeclareOp::create(builder, loc, value2, - llvm::StringRef{}, shape); - hlfir::DesignateOp::Subscripts triplets = getTripletsFromArgs(recipe); - - llvm::SmallVector lenParamsLeft; - auto leftEntity = hlfir::Entity{v1DeclareOp.getBase()}; - hlfir::genLengthParameters(loc, builder, leftEntity, lenParamsLeft); - auto leftDesignate = hlfir::DesignateOp::create( - builder, loc, v1DeclareOp.getBase().getType(), v1DeclareOp.getBase(), - /*component=*/"", - /*componentShape=*/mlir::Value{}, triplets, - /*substring=*/mlir::ValueRange{}, /*complexPartAttr=*/std::nullopt, - shape, lenParamsLeft); - auto left = hlfir::Entity{leftDesignate.getResult()}; - - llvm::SmallVector lenParamsRight; - auto rightEntity = hlfir::Entity{v2DeclareOp.getBase()}; - hlfir::genLengthParameters(loc, builder, rightEntity, lenParamsLeft); - auto rightDesignate = hlfir::DesignateOp::create( - builder, loc, v2DeclareOp.getBase().getType(), v2DeclareOp.getBase(), - /*component=*/"", - /*componentShape=*/mlir::Value{}, triplets, - /*substring=*/mlir::ValueRange{}, /*complexPartAttr=*/std::nullopt, - shape, lenParamsRight); - auto right = hlfir::Entity{rightDesignate.getResult()}; - - llvm::SmallVector typeParams; - auto genKernel = [&builder, &loc, op, seqTy, &left, &right]( - mlir::Location l, fir::FirOpBuilder &b, - mlir::ValueRange oneBasedIndices) -> hlfir::Entity { - auto leftElement = hlfir::getElementAt(l, b, left, oneBasedIndices); - auto rightElement = hlfir::getElementAt(l, b, right, oneBasedIndices); - auto leftVal = hlfir::loadTrivialScalar(l, b, leftElement); - auto rightVal = hlfir::loadTrivialScalar(l, b, rightElement); - return hlfir::Entity{genScalarCombiner( - builder, loc, op, seqTy.getEleTy(), leftVal, rightVal)}; - }; - mlir::Value elemental = hlfir::genElementalOp( - loc, builder, seqTy.getEleTy(), shape, typeParams, genKernel, - /*isUnordered=*/true); - hlfir::AssignOp::create(builder, loc, elemental, v1DeclareOp.getBase()); - return; - } - if (bounds.empty()) { - llvm::SmallVector extents; - mlir::Type idxTy = builder.getIndexType(); - for (auto extent : llvm::reverse(seqTy.getShape())) { - mlir::Value lb = mlir::arith::ConstantOp::create( - builder, loc, idxTy, builder.getIntegerAttr(idxTy, 0)); - mlir::Value ub = mlir::arith::ConstantOp::create( - builder, loc, idxTy, builder.getIntegerAttr(idxTy, extent - 1)); - mlir::Value step = mlir::arith::ConstantOp::create( - builder, loc, idxTy, builder.getIntegerAttr(idxTy, 1)); - auto loop = fir::DoLoopOp::create(builder, loc, lb, ub, step, - /*unordered=*/false); - builder.setInsertionPointToStart(loop.getBody()); - loops.push_back(loop); - ivs.push_back(loop.getInductionVar()); - } - } else if (allConstantBound) { - // Use the constant bound directly in the combiner region so they do not - // need to be passed as block argument. - assert(!bounds.empty() && - "seq type with constant bounds cannot have empty bounds"); - for (auto bound : llvm::reverse(bounds)) { - auto dataBound = - mlir::dyn_cast(bound.getDefiningOp()); - llvm::SmallVector values = - genConstantBounds(builder, loc, dataBound); - auto loop = - fir::DoLoopOp::create(builder, loc, values[0], values[1], values[2], - /*unordered=*/false); - builder.setInsertionPointToStart(loop.getBody()); - loops.push_back(loop); - ivs.push_back(loop.getInductionVar()); - } - } else { - // Lowerbound, upperbound and step are passed as block arguments. - unsigned nbRangeArgs = - recipe.getCombinerRegion().getArguments().size() - 2; - assert((nbRangeArgs / 3 == seqTy.getDimension()) && - "Expect 3 block arguments per dimension"); - for (int i = nbRangeArgs - 1; i >= 2; i -= 3) { - mlir::Value lb = recipe.getCombinerRegion().getArgument(i); - mlir::Value ub = recipe.getCombinerRegion().getArgument(i + 1); - mlir::Value step = recipe.getCombinerRegion().getArgument(i + 2); - auto loop = fir::DoLoopOp::create(builder, loc, lb, ub, step, - /*unordered=*/false); - builder.setInsertionPointToStart(loop.getBody()); - loops.push_back(loop); - ivs.push_back(loop.getInductionVar()); - } - } - llvm::SmallVector reversedIvs(ivs.rbegin(), ivs.rend()); - auto addr1 = - fir::CoordinateOp::create(builder, loc, refTy, value1, reversedIvs); - auto addr2 = - fir::CoordinateOp::create(builder, loc, refTy, value2, reversedIvs); - auto load1 = fir::LoadOp::create(builder, loc, addr1); - auto load2 = fir::LoadOp::create(builder, loc, addr2); - mlir::Value res = - genScalarCombiner(builder, loc, op, seqTy.getEleTy(), load1, load2); - fir::StoreOp::create(builder, loc, res, addr1); - builder.setInsertionPointAfter(loops[0]); - } else if (auto boxTy = mlir::dyn_cast(ty)) { - mlir::Type innerTy = fir::unwrapRefType(boxTy.getEleTy()); - if (fir::isa_trivial(innerTy)) { - mlir::Value boxAddr1 = value1, boxAddr2 = value2; - if (fir::isBoxAddress(boxAddr1.getType())) - boxAddr1 = fir::LoadOp::create(builder, loc, boxAddr1); - if (fir::isBoxAddress(boxAddr2.getType())) - boxAddr2 = fir::LoadOp::create(builder, loc, boxAddr2); - boxAddr1 = fir::BoxAddrOp::create(builder, loc, boxAddr1); - boxAddr2 = fir::BoxAddrOp::create(builder, loc, boxAddr2); - auto leftEntity = hlfir::Entity{boxAddr1}; - auto rightEntity = hlfir::Entity{boxAddr2}; - - auto leftVal = hlfir::loadTrivialScalar(loc, builder, leftEntity); - auto rightVal = hlfir::loadTrivialScalar(loc, builder, rightEntity); - mlir::Value res = - genScalarCombiner(builder, loc, op, innerTy, leftVal, rightVal); - hlfir::AssignOp::create(builder, loc, res, boxAddr1); - } else { - mlir::Type innerTy = fir::extractSequenceType(boxTy); - fir::SequenceType seqTy = - mlir::dyn_cast_or_null(innerTy); - if (!seqTy) - TODO(loc, "Unsupported boxed type in OpenACC reduction combiner"); - - auto shape = - genShapeFromBoundsOrArgs(loc, builder, seqTy, bounds, - recipe.getCombinerRegion().getArguments()); - hlfir::DesignateOp::Subscripts triplets = - getSubscriptsFromArgs(recipe.getCombinerRegion().getArguments()); - auto leftEntity = hlfir::Entity{value1}; - if (fir::isBoxAddress(value1.getType())) - leftEntity = hlfir::Entity{ - fir::LoadOp::create(builder, loc, value1).getResult()}; - auto left = - genDesignateWithTriplets(builder, loc, leftEntity, triplets, shape); - auto rightEntity = hlfir::Entity{value2}; - if (fir::isBoxAddress(value2.getType())) - rightEntity = hlfir::Entity{ - fir::LoadOp::create(builder, loc, value2).getResult()}; - auto right = - genDesignateWithTriplets(builder, loc, rightEntity, triplets, shape); - - llvm::SmallVector typeParams; - auto genKernel = [&builder, &loc, op, seqTy, &left, &right]( - mlir::Location l, fir::FirOpBuilder &b, - mlir::ValueRange oneBasedIndices) -> hlfir::Entity { - auto leftElement = hlfir::getElementAt(l, b, left, oneBasedIndices); - auto rightElement = hlfir::getElementAt(l, b, right, oneBasedIndices); - auto leftVal = hlfir::loadTrivialScalar(l, b, leftElement); - auto rightVal = hlfir::loadTrivialScalar(l, b, rightElement); - return hlfir::Entity{genScalarCombiner( - builder, loc, op, seqTy.getEleTy(), leftVal, rightVal)}; - }; - mlir::Value elemental = hlfir::genElementalOp( - loc, builder, seqTy.getEleTy(), shape, typeParams, genKernel, - /*isUnordered=*/true); - hlfir::AssignOp::create(builder, loc, elemental, value1); - } - } else { - mlir::Value res = genScalarCombiner(builder, loc, op, ty, value1, value2); - fir::StoreOp::create(builder, loc, res, value1); - } -} - mlir::acc::ReductionRecipeOp Fortran::lower::createOrGetReductionRecipe( fir::FirOpBuilder &builder, llvm::StringRef recipeName, mlir::Location loc, mlir::Type ty, mlir::acc::ReductionOperator op, @@ -1819,37 +1620,33 @@ mlir::acc::ReductionRecipeOp Fortran::lower::createOrGetReductionRecipe( if (auto recipe = mod.lookupSymbol(recipeName)) return recipe; - auto ip = builder.saveInsertionPoint(); - + mlir::OpBuilder::InsertionGuard guard(builder); auto recipe = genRecipeOp( builder, mod, recipeName, loc, ty, op); - - // The two first block arguments are the two values to be combined. - // The next arguments are the iteration ranges (lb, ub, step) to be used - // for the combiner if needed. - llvm::SmallVector argsTy{ty, ty}; - llvm::SmallVector argsLoc{loc, loc}; bool allConstantBound = areAllBoundConstant(bounds); - if (!allConstantBound) { - for (mlir::Value bound : llvm::reverse(bounds)) { - auto dataBound = - mlir::dyn_cast(bound.getDefiningOp()); - argsTy.push_back(dataBound.getLowerbound().getType()); - argsLoc.push_back(dataBound.getLowerbound().getLoc()); - argsTy.push_back(dataBound.getUpperbound().getType()); - argsLoc.push_back(dataBound.getUpperbound().getLoc()); - argsTy.push_back(dataBound.getStartIdx().getType()); - argsLoc.push_back(dataBound.getStartIdx().getLoc()); - } - } - builder.createBlock(&recipe.getCombinerRegion(), - recipe.getCombinerRegion().end(), argsTy, argsLoc); - builder.setInsertionPointToEnd(&recipe.getCombinerRegion().back()); - mlir::Value v1 = recipe.getCombinerRegion().front().getArgument(0); - mlir::Value v2 = recipe.getCombinerRegion().front().getArgument(1); - genCombiner(builder, loc, op, ty, v1, v2, recipe, bounds, allConstantBound); - mlir::acc::YieldOp::create(builder, loc, v1); - builder.restoreInsertionPoint(ip); + + auto [dest, src] = genRecipeCombinerOrCopyRegion( + builder, loc, ty, recipe.getCombinerRegion(), bounds, allConstantBound); + // Generate loops that combine and assign the inputs into dest (or array + // section of the inputs when there are bounds). + hlfir::Entity srcSection = src; + hlfir::Entity destSection = dest; + if (!bounds.empty()) + std::tie(srcSection, destSection) = genArraySectionsInRecipe( + builder, loc, bounds, recipe.getCombinerRegion().getArguments(), + allConstantBound, srcSection, destSection); + + mlir::Type elementType = fir::getFortranElementType(ty); + auto genKernel = [&](mlir::Location l, fir::FirOpBuilder &b, + hlfir::Entity srcElementValue, + hlfir::Entity destElementValue) -> hlfir::Entity { + return hlfir::Entity{genScalarCombiner(builder, loc, op, elementType, + srcElementValue, destElementValue)}; + }; + hlfir::genNoAliasAssignment(loc, builder, srcSection, destSection, + /*emitWorkshareLoop=*/false, + /*temporaryLHS=*/false, genKernel); + mlir::acc::YieldOp::create(builder, loc, dest); return recipe; } diff --git a/flang/lib/Optimizer/Builder/HLFIRTools.cpp b/flang/lib/Optimizer/Builder/HLFIRTools.cpp index 93dfc577665ce..7b69b7d428a8f 100644 --- a/flang/lib/Optimizer/Builder/HLFIRTools.cpp +++ b/flang/lib/Optimizer/Builder/HLFIRTools.cpp @@ -18,6 +18,7 @@ #include "flang/Optimizer/Builder/Todo.h" #include "flang/Optimizer/Dialect/FIRType.h" #include "flang/Optimizer/HLFIR/HLFIROps.h" +#include "flang/Optimizer/OpenMP/Passes.h" #include "mlir/IR/IRMapping.h" #include "mlir/Support/LLVM.h" #include "llvm/ADT/TypeSwitch.h" @@ -1392,6 +1393,66 @@ bool hlfir::elementalOpMustProduceTemp(hlfir::ElementalOp elemental) { return false; } +static void combineAndStoreElement( + mlir::Location loc, fir::FirOpBuilder &builder, hlfir::Entity lhs, + hlfir::Entity rhs, bool temporaryLHS, + std::function *combiner) { + hlfir::Entity valueToAssign = hlfir::loadTrivialScalar(loc, builder, rhs); + if (combiner) { + hlfir::Entity lhsValue = hlfir::loadTrivialScalar(loc, builder, lhs); + valueToAssign = (*combiner)(loc, builder, lhsValue, valueToAssign); + } + hlfir::AssignOp::create(builder, loc, valueToAssign, lhs, + /*realloc=*/false, + /*keep_lhs_length_if_realloc=*/false, + /*temporary_lhs=*/temporaryLHS); +} + +void hlfir::genNoAliasArrayAssignment( + mlir::Location loc, fir::FirOpBuilder &builder, hlfir::Entity rhs, + hlfir::Entity lhs, bool emitWorkshareLoop, bool temporaryLHS, + std::function *combiner) { + mlir::OpBuilder::InsertionGuard guard(builder); + rhs = hlfir::derefPointersAndAllocatables(loc, builder, rhs); + lhs = hlfir::derefPointersAndAllocatables(loc, builder, lhs); + mlir::Value lhsShape = hlfir::genShape(loc, builder, lhs); + llvm::SmallVector lhsExtents = + hlfir::getIndexExtents(loc, builder, lhsShape); + mlir::Value rhsShape = hlfir::genShape(loc, builder, rhs); + llvm::SmallVector rhsExtents = + hlfir::getIndexExtents(loc, builder, rhsShape); + llvm::SmallVector extents = + fir::factory::deduceOptimalExtents(lhsExtents, rhsExtents); + hlfir::LoopNest loopNest = + hlfir::genLoopNest(loc, builder, extents, + /*isUnordered=*/true, emitWorkshareLoop); + builder.setInsertionPointToStart(loopNest.body); + auto rhsArrayElement = + hlfir::getElementAt(loc, builder, rhs, loopNest.oneBasedIndices); + rhsArrayElement = hlfir::loadTrivialScalar(loc, builder, rhsArrayElement); + auto lhsArrayElement = + hlfir::getElementAt(loc, builder, lhs, loopNest.oneBasedIndices); + combineAndStoreElement(loc, builder, lhsArrayElement, rhsArrayElement, + temporaryLHS, combiner); +} + +void hlfir::genNoAliasAssignment( + mlir::Location loc, fir::FirOpBuilder &builder, hlfir::Entity rhs, + hlfir::Entity lhs, bool emitWorkshareLoop, bool temporaryLHS, + std::function *combiner) { + if (lhs.isArray()) { + genNoAliasArrayAssignment(loc, builder, rhs, lhs, emitWorkshareLoop, + temporaryLHS, combiner); + return; + } + rhs = hlfir::derefPointersAndAllocatables(loc, builder, rhs); + lhs = hlfir::derefPointersAndAllocatables(loc, builder, lhs); + combineAndStoreElement(loc, builder, lhs, rhs, temporaryLHS, combiner); +} + std::pair hlfir::createTempFromMold(mlir::Location loc, fir::FirOpBuilder &builder, hlfir::Entity mold) { diff --git a/flang/lib/Optimizer/HLFIR/Transforms/InlineHLFIRAssign.cpp b/flang/lib/Optimizer/HLFIR/Transforms/InlineHLFIRAssign.cpp index 86d39749df93d..1fc592c7fe522 100644 --- a/flang/lib/Optimizer/HLFIR/Transforms/InlineHLFIRAssign.cpp +++ b/flang/lib/Optimizer/HLFIR/Transforms/InlineHLFIRAssign.cpp @@ -107,26 +107,8 @@ class InlineHLFIRAssignConversion mlir::Location loc = assign->getLoc(); fir::FirOpBuilder builder(rewriter, assign.getOperation()); builder.setInsertionPoint(assign); - rhs = hlfir::derefPointersAndAllocatables(loc, builder, rhs); - lhs = hlfir::derefPointersAndAllocatables(loc, builder, lhs); - mlir::Value lhsShape = hlfir::genShape(loc, builder, lhs); - llvm::SmallVector lhsExtents = - hlfir::getIndexExtents(loc, builder, lhsShape); - mlir::Value rhsShape = hlfir::genShape(loc, builder, rhs); - llvm::SmallVector rhsExtents = - hlfir::getIndexExtents(loc, builder, rhsShape); - llvm::SmallVector extents = - fir::factory::deduceOptimalExtents(lhsExtents, rhsExtents); - hlfir::LoopNest loopNest = - hlfir::genLoopNest(loc, builder, extents, /*isUnordered=*/true, - flangomp::shouldUseWorkshareLowering(assign)); - builder.setInsertionPointToStart(loopNest.body); - auto rhsArrayElement = - hlfir::getElementAt(loc, builder, rhs, loopNest.oneBasedIndices); - rhsArrayElement = hlfir::loadTrivialScalar(loc, builder, rhsArrayElement); - auto lhsArrayElement = - hlfir::getElementAt(loc, builder, lhs, loopNest.oneBasedIndices); - hlfir::AssignOp::create(builder, loc, rhsArrayElement, lhsArrayElement); + hlfir::genNoAliasArrayAssignment( + loc, builder, rhs, lhs, flangomp::shouldUseWorkshareLowering(assign)); rewriter.eraseOp(assign); return mlir::success(); } diff --git a/flang/test/Lower/OpenACC/acc-private.f90 b/flang/test/Lower/OpenACC/acc-private.f90 index 485825dfa8129..910e87f773ac4 100644 --- a/flang/test/Lower/OpenACC/acc-private.f90 +++ b/flang/test/Lower/OpenACC/acc-private.f90 @@ -21,10 +21,7 @@ ! CHECK: acc.yield %[[DECL]]#0 : !fir.box> ! CHECK: } copy { ! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box>, %[[ARG1:.*]]: !fir.box>): -! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}}, %{{.*}}, %{{.*}} : (index, index, index) -> !fir.shape<3> -! CHECK: %[[DES_SRC:.*]] = hlfir.designate %[[ARG0]] shape %[[SHAPE]] : (!fir.box>, !fir.shape<3>) -> !fir.box> -! CHECK: %[[DES_DST:.*]] = hlfir.designate %[[ARG1]] shape %[[SHAPE]] : (!fir.box>, !fir.shape<3>) -> !fir.box> -! CHECK: hlfir.assign %[[DES_SRC]] to %[[DES_DST]] : !fir.box>, !fir.box> +! CHECK: hlfir.assign %[[ARG0]] to %[[ARG1]] temporary_lhs : !fir.box>, !fir.box> ! CHECK: acc.terminator ! CHECK: } destroy { ! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box>, %[[ARG1:.*]]: !fir.box>): @@ -38,20 +35,7 @@ ! CHECK: ^bb0(%{{.*}}: !fir.box>): ! CHECK: } copy { ! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box>, %[[ARG1:.*]]: !fir.box>): -! CHECK: %[[LB:.*]] = arith.constant 4 : index -! CHECK: %[[UB:.*]] = arith.constant 9 : index -! CHECK: %[[STEP:.*]] = arith.constant 1 : index -! CHECK: %[[C1:.*]] = arith.constant 1 : index -! CHECK: %[[C0:.*]] = arith.constant 0 : index -! CHECK: %[[EXT0:.*]] = arith.subi %[[UB]], %[[LB]] : index -! CHECK: %[[EXT1:.*]] = arith.addi %[[EXT0]], %[[C1]] : index -! CHECK: %[[EXT2:.*]] = arith.divsi %[[EXT1]], %[[STEP]] : index -! CHECK: %[[CMP:.*]] = arith.cmpi sgt, %[[EXT2]], %[[C0]] : index -! CHECK: %[[SELECT:.*]] = arith.select %[[CMP]], %[[EXT2]], %[[C0]] : index -! CHECK: %[[SHAPE:.*]] = fir.shape %[[SELECT]] : (index) -> !fir.shape<1> -! CHECK: %[[LEFT:.*]] = hlfir.designate %[[ARG0]] shape %[[SHAPE]] : (!fir.box>, !fir.shape<1>) -> !fir.box> -! CHECK: %[[RIGHT:.*]] = hlfir.designate %[[ARG1]] shape %[[SHAPE]] : (!fir.box>, !fir.shape<1>) -> !fir.box> -! CHECK: hlfir.assign %[[LEFT]] to %[[RIGHT]] : !fir.box>, !fir.box> +! CHECK: hlfir.assign {{.*}} to {{.*}} temporary_lhs : !fir.box>, !fir.box> ! CHECK: acc.terminator ! CHECK: } destroy { ! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box>, %[[ARG1:.*]]: !fir.box>): @@ -71,10 +55,7 @@ ! CHECK: acc.yield %[[DECL]]#0 : !fir.box> ! CHECK: } copy { ! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box>, %[[ARG1:.*]]: !fir.box>): -! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1> -! CHECK: %[[DES_V1:.*]] = hlfir.designate %[[ARG0]] shape %[[SHAPE]] : (!fir.box>, !fir.shape<1>) -> !fir.box> -! CHECK: %[[DES_V2:.*]] = hlfir.designate %[[ARG1]] shape %[[SHAPE]] : (!fir.box>, !fir.shape<1>) -> !fir.box> -! CHECK: hlfir.assign %[[DES_V1]] to %[[DES_V2]] : !fir.box>, !fir.box> +! CHECK: hlfir.assign %[[ARG0]] to %[[ARG1]] temporary_lhs : !fir.box>, !fir.box> ! CHECK: acc.terminator ! CHECK: } destroy { ! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box>, %[[ARG1:.*]]: !fir.box>): @@ -183,12 +164,19 @@ ! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref> ! CHECK: } copy { ! CHECK: ^bb0(%[[SRC:.*]]: !fir.ref>, %[[DST:.*]]: !fir.ref>): -! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1> -! CHECK: %[[DECL_SRC:.*]]:2 = hlfir.declare %[[SRC]](%[[SHAPE]]) {uniq_name = ""} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) -! CHECK: %[[DECL_DST:.*]]:2 = hlfir.declare %[[DST]](%[[SHAPE]]) {uniq_name = ""} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) -! CHECK: %[[DES_SRC:.*]] = hlfir.designate %[[DECL_SRC]]#0 shape %[[SHAPE:.*]] : (!fir.ref>, !fir.shape<1>) -> !fir.ref> -! CHECK: %[[DES_DST:.*]] = hlfir.designate %[[DECL_DST]]#0 shape %[[SHAPE:.*]] : (!fir.ref>, !fir.shape<1>) -> !fir.ref> -! CHECK: hlfir.assign %[[DES_SRC]] to %[[DES_DST]] : !fir.ref>, !fir.ref> +! CHECK: %[[C50:.*]] = arith.constant 50 : index +! CHECK: %[[C99:.*]] = arith.constant 99 : index +! CHECK: %[[C1:.*]] = arith.constant 1 : index +! CHECK: %[[C0:.*]] = arith.constant 0 : index +! CHECK: %[[D0:.*]] = arith.subi %[[C99]], %[[C50]] : index +! CHECK: %[[D1:.*]] = arith.addi %[[D0]], %[[C1]] : index +! CHECK: %[[D2:.*]] = arith.divsi %[[D1]], %[[C1]] : index +! CHECK: %[[CMP:.*]] = arith.cmpi sgt, %[[D2]], %[[C0]] : index +! CHECK: %[[SEL:.*]] = arith.select %[[CMP]], %[[D2]], %[[C0]] : index +! CHECK: %[[SH:.*]] = fir.shape %[[SEL]] : (index) -> !fir.shape<1> +! CHECK: %[[SEC_SRC:.*]] = hlfir.designate %[[SRC]] (%c51{{.*}}:%c100{{.*}}:%c1{{.*}}) shape %[[SH]] : (!fir.ref>, index, index, index, !fir.shape<1>) -> !fir.ref> +! CHECK: %[[SEC_DST:.*]] = hlfir.designate %[[DST]] (%c51{{.*}}:%c100{{.*}}:%c1{{.*}}) shape %[[SH]] : (!fir.ref>, index, index, index, !fir.shape<1>) -> !fir.ref> +! CHECK: hlfir.assign %[[SEC_SRC]] to %[[SEC_DST]] temporary_lhs : !fir.ref>, !fir.ref> ! CHECK: acc.terminator ! CHECK: } @@ -200,12 +188,7 @@ ! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref> ! CHECK: } copy { ! CHECK: ^bb0(%[[SRC:.*]]: !fir.ref>, %[[DST:.*]]: !fir.ref>): -! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1> -! CHECK: %[[DECL_SRC:.*]]:2 = hlfir.declare %[[SRC]](%[[SHAPE]]) {uniq_name = ""} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) -! CHECK: %[[DECL_DST:.*]]:2 = hlfir.declare %[[DST]](%[[SHAPE]]) {uniq_name = ""} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) -! CHECK: %[[DES_SRC:.*]] = hlfir.designate %[[DECL_SRC]]#0 shape %[[SHAPE]] : (!fir.ref>, !fir.shape<1>) -> !fir.ref> -! CHECK: %[[DES_DST:.*]] = hlfir.designate %[[DECL_DST]]#0 shape %[[SHAPE]] : (!fir.ref>, !fir.shape<1>) -> !fir.ref> -! CHECK: hlfir.assign %[[DES_SRC]] to %[[DES_DST]] : !fir.ref>, !fir.ref> +! CHECK: hlfir.assign %[[SRC]] to %[[DST]] temporary_lhs : !fir.ref>, !fir.ref> ! CHECK: acc.terminator ! CHECK: } @@ -217,7 +200,7 @@ ! CHECK: } copy { ! CHECK: ^bb0(%[[SRC:.*]]: !fir.ref, %[[DST:.*]]: !fir.ref): ! CHECK: %[[VALUE:.*]] = fir.load %[[SRC]] : !fir.ref -! CHECK: fir.store %[[VALUE]] to %[[DST]] : !fir.ref +! CHECK: fir.assign %[[VALUE]] to %[[DST]] temporary_lhs : i32, !fir.ref ! CHECK: acc.terminator ! CHECK: } diff --git a/flang/test/Lower/OpenACC/acc-reduction.f90 b/flang/test/Lower/OpenACC/acc-reduction.f90 index 6cb8bdf6b511a..aee28f0026819 100644 --- a/flang/test/Lower/OpenACC/acc-reduction.f90 +++ b/flang/test/Lower/OpenACC/acc-reduction.f90 @@ -2,757 +2,1212 @@ ! RUN: bbc -fopenacc -emit-hlfir %s -o - | FileCheck %s -! CHECK-LABEL: acc.reduction.recipe @reduction_max_box_UxUxf32 : !fir.box> reduction_operator init { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box>): -! CHECK: %[[CST:.*]] = arith.constant -1.401300e-45 : f32 -! CHECK: %[[DIMS0:.*]]:3 = fir.box_dims %[[ARG0]], %c0{{.*}} : (!fir.box>, index) -> (index, index, index) -! CHECK: %[[DIMS1:.*]]:3 = fir.box_dims %[[ARG0]], %c1 : (!fir.box>, index) -> (index, index, index) -! CHECK: %[[SHAPE:.*]] = fir.shape %[[DIMS0]]#1, %[[DIMS1]]#1 : (index, index) -> !fir.shape<2> -! CHECK: %[[TEMP:.*]] = fir.allocmem !fir.array, %[[DIMS0]]#1, %[[DIMS1]]#1 {bindc_name = ".tmp", uniq_name = ""} -! CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[TEMP]](%[[SHAPE]]) {uniq_name = ".tmp"} : (!fir.heap>, !fir.shape<2>) -> (!fir.box>, !fir.heap>) -! CHECK: hlfir.assign %[[CST]] to %[[DECL]]#0 : f32, !fir.box> -! CHECK: acc.yield %[[DECL]]#0 : !fir.box> -! CHECK: } combiner { -! CHECK: ^bb0(%[[V1:.*]]: !fir.box>, %[[V2:.*]]: !fir.box>): -! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2> -! CHECK: %[[DES_V1:.*]] = hlfir.designate %[[V1]] shape %[[SHAPE]] : (!fir.box>, !fir.shape<2>) -> !fir.box> -! CHECK: %[[DES_V2:.*]] = hlfir.designate %[[V2]] shape %[[SHAPE]] : (!fir.box>, !fir.shape<2>) -> !fir.box> -! CHECK: %[[ELEMENTAL:.*]] = hlfir.elemental %[[SHAPE]] unordered : (!fir.shape<2>) -> !hlfir.expr { -! CHECK: ^bb0(%[[ARG0:.*]]: index, %[[ARG1:.*]]: index): -! CHECK: %[[D1:.*]] = hlfir.designate %[[DES_V1]] (%[[ARG0]], %[[ARG1]]) : (!fir.box>, index, index) -> !fir.ref -! CHECK: %[[D2:.*]] = hlfir.designate %[[DES_V2]] (%[[ARG0]], %[[ARG1]]) : (!fir.box>, index, index) -> !fir.ref -! CHECK: %[[LOAD1:.*]] = fir.load %[[D1]] : !fir.ref -! CHECK: %[[LOAD2:.*]] = fir.load %[[D2]] : !fir.ref -! CHECK: %[[CMP:.*]] = arith.cmpf ogt, %[[LOAD1]], %[[LOAD2]] {{.*}} : f32 -! CHECK: %[[SELECT:.*]] = arith.select %[[CMP]], %[[LOAD1]], %[[LOAD2]] : f32 -! CHECK: hlfir.yield_element %[[SELECT]] : f32 -! CHECK: } -! CHECK: hlfir.assign %[[ELEMENTAL]] to %[[V1]] : !hlfir.expr, !fir.box> -! CHECK: acc.yield %[[V1]] : !fir.box> -! CHECK: } - -! CHECK-LABEL: acc.reduction.recipe @reduction_max_ref_box_ptr_Uxf32 : !fir.ref>>> reduction_operator init { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref>>>): -! CHECK: %[[CST:.*]] = arith.constant -1.401300e-45 : f32 -! CHECK: %[[BOX:.*]] = fir.load %[[ARG0]] : !fir.ref>>> -! CHECK: %[[C0:.*]] = arith.constant 0 : index -! CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[BOX]], %[[C0]] : (!fir.box>>, index) -> (index, index, index) -! CHECK: %[[SHAPE:.*]] = fir.shape %[[BOX_DIMS]]#1 : (index) -> !fir.shape<1> -! CHECK: %[[TEMP:.*]] = fir.allocmem !fir.array, %[[BOX_DIMS]]#1 {bindc_name = ".tmp", uniq_name = ""} -! CHECK: %[[STORAGE:.*]]:2 = hlfir.declare %[[TEMP]](%[[SHAPE]]) {uniq_name = ".tmp"} : (!fir.heap>, !fir.shape<1>) -> (!fir.box>, !fir.heap>) -! CHECK: %[[BOXTEMP:.*]] = fir.alloca !fir.box>> -! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[BOXTEMP]] {uniq_name = "acc.reduction.init"} : (!fir.ref>>>) -> (!fir.ref>>>, !fir.ref>>>) -! CHECK: hlfir.assign %[[CST]] to %[[DECLARE]]#0 : f32, !fir.ref>>> -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref>>> -! CHECK: } combiner { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref>>>, %[[ARG1:.*]]: !fir.ref>>>): -! CHECK: %[[BOX0:.*]] = fir.load %[[ARG0]] : !fir.ref>>> -! CHECK: %[[C0:.*]] = arith.constant 0 : index -! CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[BOX0]], %[[C0]] : (!fir.box>>, index) -> (index, index, index) -! CHECK: %[[SHAPE:.*]] = fir.shape %[[BOX_DIMS]]#1 : (index) -> !fir.shape<1> -! CHECK: %[[BOX0:.*]] = fir.load %[[ARG0]] : !fir.ref>>> -! CHECK: %[[DES_V1:.*]] = hlfir.designate %[[BOX0]] shape %[[SHAPE]] : (!fir.box>>, !fir.shape<1>) -> !fir.box>> -! CHECK: %[[BOX1:.*]] = fir.load %[[ARG1]] : !fir.ref>>> -! CHECK: %[[DES_V2:.*]] = hlfir.designate %[[BOX1]] shape %[[SHAPE]] : (!fir.box>>, !fir.shape<1>) -> !fir.box>> -! CHECK: %[[ELEMENTAL:.*]] = hlfir.elemental %[[SHAPE]] unordered : (!fir.shape<1>) -> !hlfir.expr { -! CHECK: ^bb0(%[[IV:.*]]: index): -! CHECK: %[[V1:.*]] = hlfir.designate %[[DES_V1]] (%[[IV]]) : (!fir.box>>, index) -> !fir.ref -! CHECK: %[[V2:.*]] = hlfir.designate %[[DES_V2]] (%[[IV]]) : (!fir.box>>, index) -> !fir.ref -! CHECK: %[[LOAD_V1:.*]] = fir.load %[[V1]] : !fir.ref -! CHECK: %[[LOAD_V2:.*]] = fir.load %[[V2]] : !fir.ref -! CHECK: %[[CMP:.*]] = arith.cmpf ogt, %[[LOAD_V1]], %[[LOAD_V2]] {{.*}} : f32 -! CHECK: %[[SELECT:.*]] = arith.select %[[CMP]], %[[LOAD_V1]], %[[LOAD_V2]] : f32 -! CHECK: hlfir.yield_element %[[SELECT]] : f32 -! CHECK: } -! CHECK: hlfir.assign %[[ELEMENTAL]] to %[[ARG0]] : !hlfir.expr, !fir.ref>>> -! CHECK: acc.yield %[[ARG0]] : !fir.ref>>> -! CHECK: } - -! CHECK-LABEL: acc.reduction.recipe @reduction_max_ref_box_heap_Uxf32 : !fir.ref>>> reduction_operator init { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref>>>): -! CHECK: %[[CST:.*]] = arith.constant -1.401300e-45 : f32 -! CHECK: %[[BOX:.*]] = fir.load %[[ARG0]] : !fir.ref>>> -! CHECK: %[[C0:.*]] = arith.constant 0 : index -! CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[BOX]], %[[C0]] : (!fir.box>>, index) -> (index, index, index) -! CHECK: %[[SHAPE:.*]] = fir.shape %[[BOX_DIMS]]#1 : (index) -> !fir.shape<1> -! CHECK: %[[TEMP:.*]] = fir.allocmem !fir.array, %[[BOX_DIMS]]#1 {bindc_name = ".tmp", uniq_name = ""} -! CHECK: %[[STORAGE:.*]]:2 = hlfir.declare %[[TEMP]](%[[SHAPE]]) {uniq_name = ".tmp"} : (!fir.heap>, !fir.shape<1>) -> (!fir.box>, !fir.heap>) -! CHECK: %[[BOXTEMP:.*]] = fir.alloca !fir.box>> -! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[BOXTEMP]] {uniq_name = "acc.reduction.init"} : (!fir.ref>>>) -> (!fir.ref>>>, !fir.ref>>>) -! CHECK: hlfir.assign %[[CST]] to %[[DECLARE]]#0 : f32, !fir.ref>>> -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref>>> -! CHECK: } combiner { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref>>>, %[[ARG1:.*]]: !fir.ref>>>): -! CHECK: %[[BOX0:.*]] = fir.load %[[ARG0]] : !fir.ref>>> -! CHECK: %[[C0:.*]] = arith.constant 0 : index -! CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[BOX0]], %[[C0]] : (!fir.box>>, index) -> (index, index, index) -! CHECK: %[[SHAPE:.*]] = fir.shape %[[BOX_DIMS]]#1 : (index) -> !fir.shape<1> -! CHECK: %[[BOX0:.*]] = fir.load %[[ARG0]] : !fir.ref>>> -! CHECK: %[[DES_V1:.*]] = hlfir.designate %[[BOX0]] shape %[[SHAPE]] : (!fir.box>>, !fir.shape<1>) -> !fir.box>> -! CHECK: %[[BOX1:.*]] = fir.load %[[ARG1]] : !fir.ref>>> -! CHECK: %[[DES_V2:.*]] = hlfir.designate %[[BOX1]] shape %[[SHAPE]] : (!fir.box>>, !fir.shape<1>) -> !fir.box>> -! CHECK: %[[ELEMENTAL:.*]] = hlfir.elemental %[[SHAPE]] unordered : (!fir.shape<1>) -> !hlfir.expr { -! CHECK: ^bb0(%[[IV:.*]]: index): -! CHECK: %[[V1:.*]] = hlfir.designate %[[DES_V1]] (%[[IV]]) : (!fir.box>>, index) -> !fir.ref -! CHECK: %[[V2:.*]] = hlfir.designate %[[DES_V2]] (%[[IV]]) : (!fir.box>>, index) -> !fir.ref -! CHECK: %[[LOAD_V1:.*]] = fir.load %[[V1]] : !fir.ref -! CHECK: %[[LOAD_V2:.*]] = fir.load %[[V2]] : !fir.ref -! CHECK: %[[CMP:.*]] = arith.cmpf ogt, %[[LOAD_V1]], %[[LOAD_V2]] {{.*}} : f32 -! CHECK: %[[SELECT:.*]] = arith.select %[[CMP]], %[[LOAD_V1]], %[[LOAD_V2]] : f32 -! CHECK: hlfir.yield_element %[[SELECT]] : f32 -! CHECK: } -! CHECK: hlfir.assign %[[ELEMENTAL]] to %[[ARG0]] : !hlfir.expr, !fir.ref>>> -! CHECK: acc.yield %[[ARG0]] : !fir.ref>>> -! CHECK: } - -! CHECK-LABEL: acc.reduction.recipe @reduction_add_section_lb1.ub3_box_Uxi32 : !fir.box> reduction_operator init { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box>): -! CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[ARG0]], %c0{{.*}} : (!fir.box>, index) -> (index, index, index) -! CHECK: %[[SHAPE:.*]] = fir.shape %[[BOX_DIMS]]#1 : (index) -> !fir.shape<1> -! CHECK: %[[TEMP:.*]] = fir.allocmem !fir.array, %0#1 {bindc_name = ".tmp", uniq_name = ""} -! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[TEMP]](%[[SHAPE]]) {uniq_name = ".tmp"} : (!fir.heap>, !fir.shape<1>) -> (!fir.box>, !fir.heap>) -! CHECK: hlfir.assign %c0{{.*}} to %[[DECLARE]]#0 : i32, !fir.box> -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.box> -! CHECK: } combiner { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box>, %[[ARG1:.*]]: !fir.box>): -! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1> -! CHECK: %[[DES1:.*]] = hlfir.designate %[[ARG0]] shape %[[SHAPE]] : (!fir.box>, !fir.shape<1>) -> !fir.box> -! CHECK: %[[DES2:.*]] = hlfir.designate %[[ARG1]] shape %[[SHAPE]] : (!fir.box>, !fir.shape<1>) -> !fir.box> -! CHECK: %[[ELEMENTAL:.*]] = hlfir.elemental %[[SHAPE]] unordered : (!fir.shape<1>) -> !hlfir.expr { -! CHECK: ^bb0(%[[IV:.*]]: index): -! CHECK: %[[DES_V1:.*]] = hlfir.designate %[[DES1]] (%[[IV]]) : (!fir.box>, index) -> !fir.ref -! CHECK: %[[DES_V2:.*]] = hlfir.designate %[[DES2]] (%[[IV]]) : (!fir.box>, index) -> !fir.ref -! CHECK: %[[LOAD_V1:.*]] = fir.load %[[DES_V1]] : !fir.ref -! CHECK: %[[LOAD_V2:.*]] = fir.load %[[DES_V2]] : !fir.ref -! CHECK: %[[COMBINED:.*]] = arith.addi %[[LOAD_V1]], %[[LOAD_V2]] : i32 -! CHECK: hlfir.yield_element %[[COMBINED]] : i32 -! CHECK: } -! CHECK: hlfir.assign %[[ELEMENTAL]] to %[[ARG0]] : !hlfir.expr, !fir.box> -! CHECK: acc.yield %[[ARG0]] : !fir.box> -! CHECK: } - -! CHECK-LABEL: acc.reduction.recipe @reduction_max_box_Uxf32 : !fir.box> reduction_operator init { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box>): -! CHECK: %[[INIT_VALUE:.*]] = arith.constant -1.401300e-45 : f32 -! CHECK: %[[C0:.*]] = arith.constant 0 : index -! CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[ARG0]], %[[C0]] : (!fir.box>, index) -> (index, index, index) -! CHECK: %[[SHAPE:.*]] = fir.shape %[[BOX_DIMS]]#1 : (index) -> !fir.shape<1> -! CHECK: %[[TEMP:.*]] = fir.allocmem !fir.array, %0#1 {bindc_name = ".tmp", uniq_name = ""} -! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[TEMP]](%[[SHAPE]]) {uniq_name = ".tmp"} : (!fir.heap>, !fir.shape<1>) -> (!fir.box>, !fir.heap>) -! CHECK: hlfir.assign %[[INIT_VALUE]] to %[[DECLARE]]#0 : f32, !fir.box> -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.box> -! CHECK: } combiner { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box>, %[[ARG1:.*]]: !fir.box> -! CHECK: %[[LEFT:.*]] = hlfir.designate %[[ARG0]] shape %{{.*}} : (!fir.box>, !fir.shape<1>) -> !fir.box> -! CHECK: %[[RIGHT:.*]] = hlfir.designate %[[ARG1]] shape %{{.*}} : (!fir.box>, !fir.shape<1>) -> !fir.box> -! CHECK: %[[ELEMENTAL:.*]] = hlfir.elemental %{{.*}} unordered : (!fir.shape<1>) -> !hlfir.expr { -! CHECK: ^bb0(%{{.*}}: index): -! CHECK: %[[DES_V1:.*]] = hlfir.designate %[[LEFT]] (%{{.*}}) : (!fir.box>, index) -> !fir.ref -! CHECK: %[[DES_V2:.*]] = hlfir.designate %[[RIGHT]] (%{{.*}}) : (!fir.box>, index) -> !fir.ref -! CHECK: %[[LOAD_V1:.*]] = fir.load %[[DES_V1]] : !fir.ref -! CHECK: %[[LOAD_V2:.*]] = fir.load %[[DES_V2]] : !fir.ref -! CHECK: %[[CMPF:.*]] = arith.cmpf ogt, %[[LOAD_V1]], %[[LOAD_V2]] {{.*}} : f32 -! CHECK: %[[SELECT:.*]] = arith.select %[[CMPF]], %[[LOAD_V1]], %[[LOAD_V2]] : f32 -! CHECK: hlfir.yield_element %[[SELECT]] : f32 -! CHECK: } -! CHECK: hlfir.assign %[[ELEMENTAL]] to %[[ARG0]] : !hlfir.expr, !fir.box> -! CHECK: acc.yield %[[ARG0]] : !fir.box> -! CHECK: } - -! CHECK-LABEL: acc.reduction.recipe @reduction_add_box_Uxi32 : !fir.box> reduction_operator init { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box>): -! CHECK: %[[INIT_VALUE:.*]] = arith.constant 0 : i32 -! CHECK: %[[C0:.*]] = arith.constant 0 : index -! CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[ARG0]], %[[C0]] : (!fir.box>, index) -> (index, index, index) -! CHECK: %[[SHAPE:.*]] = fir.shape %[[BOX_DIMS]]#1 : (index) -> !fir.shape<1> -! CHECK: %[[TEMP:.*]] = fir.allocmem !fir.array, %[[BOX_DIMS]]#1 {bindc_name = ".tmp", uniq_name = ""} -! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[TEMP]](%[[SHAPE]]) {uniq_name = ".tmp"} : (!fir.heap>, !fir.shape<1>) -> (!fir.box>, !fir.heap>) -! CHECK: hlfir.assign %[[INIT_VALUE]] to %[[DECLARE]]#0 : i32, !fir.box> -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.box> -! CHECK: } combiner { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.box>, %[[ARG1:.*]]: !fir.box> -! CHECK: %[[C0:.*]] = arith.constant 0 : index -! CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[ARG0]], %[[C0]] : (!fir.box>, index) -> (index, index, index) -! CHECK: %[[SHAPE:.*]] = fir.shape %[[BOX_DIMS]]#1 : (index) -> !fir.shape<1> -! CHECK: %[[LEFT:.*]] = hlfir.designate %[[ARG0]] shape %[[SHAPE]] : (!fir.box>, !fir.shape<1>) -> !fir.box> -! CHECK: %[[RIGHT:.*]] = hlfir.designate %[[ARG1]] shape %[[SHAPE]] : (!fir.box>, !fir.shape<1>) -> !fir.box> -! CHECK: %[[ELEMENTAL:.*]] = hlfir.elemental %{{.*}} unordered : (!fir.shape<1>) -> !hlfir.expr { -! CHECK: ^bb0(%{{.*}}: index): -! CHECK: %[[DES_V1:.*]] = hlfir.designate %[[LEFT]] (%{{.*}}) : (!fir.box>, index) -> !fir.ref -! CHECK: %[[DES_V2:.*]] = hlfir.designate %[[RIGHT]] (%{{.*}}) : (!fir.box>, index) -> !fir.ref -! CHECK: %[[LOAD_V1:.*]] = fir.load %[[DES_V1]] : !fir.ref -! CHECK: %[[LOAD_V2:.*]] = fir.load %[[DES_V2]] : !fir.ref -! CHECK: %[[COMBINED:.*]] = arith.addi %[[LOAD_V1]], %[[LOAD_V2]] : i32 -! CHECK: hlfir.yield_element %[[COMBINED]] : i32 -! CHECK: } -! CHECK: hlfir.assign %[[ELEMENTAL]] to %[[ARG0]] : !hlfir.expr, !fir.box> -! CHECK: acc.yield %arg0 : !fir.box> -! CHECK: } - -! CHECK-LABEL: acc.reduction.recipe @reduction_add_section_lb0.ub9xlb0.ub19_ref_10x20xi32 : !fir.ref> reduction_operator init { -! CHECK: fir.do_loop %arg1 = %c0 to %c19 step %c1 { -! CHECK: fir.do_loop %arg2 = %c0_0 to %c9 step %c1_1 { -! CHECK: } combiner { -! CHECK: fir.do_loop %arg2 = %c0 to %c19 step %c1 { -! CHECK: fir.do_loop %arg3 = %c0_0 to %c9 step %c1_1 { -! CHECK: } - -! CHECK-LABEL: acc.reduction.recipe @reduction_mul_ref_z32 : !fir.ref> reduction_operator init { -! CHECK: ^bb0(%{{.*}}: !fir.ref>): -! CHECK: %[[REAL:.*]] = arith.constant 1.000000e+00 : f32 -! CHECK: %[[IMAG:.*]] = arith.constant 0.000000e+00 : f32 -! CHECK: %[[UNDEF:.*]] = fir.undefined complex -! CHECK: %[[UNDEF1:.*]] = fir.insert_value %[[UNDEF]], %[[REAL]], [0 : index] : (complex, f32) -> complex -! CHECK: %[[UNDEF2:.*]] = fir.insert_value %[[UNDEF1]], %[[IMAG]], [1 : index] : (complex, f32) -> complex -! CHECK: %[[ALLOCA:.*]] = fir.alloca complex -! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) -! CHECK: fir.store %[[UNDEF2]] to %[[DECLARE]]#0 : !fir.ref> -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref> -! CHECK: } combiner { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref>, %[[ARG1:.*]]: !fir.ref>): -! CHECK: %[[LOAD0:.*]] = fir.load %[[ARG0]] : !fir.ref> -! CHECK: %[[LOAD1:.*]] = fir.load %[[ARG1]] : !fir.ref> -! CHECK: %[[COMBINED:.*]] = fir.mulc %[[LOAD0]], %[[LOAD1]] {fastmath = #arith.fastmath} : complex -! CHECK: fir.store %[[COMBINED]] to %[[ARG0]] : !fir.ref> -! CHECK: acc.yield %[[ARG0]] : !fir.ref> -! CHECK: } - -! CHECK-LABEL: acc.reduction.recipe @reduction_add_ref_z32 : !fir.ref> reduction_operator init { -! CHECK: ^bb0(%{{.*}}: !fir.ref>): -! CHECK: %[[REAL:.*]] = arith.constant 0.000000e+00 : f32 -! CHECK: %[[IMAG:.*]] = arith.constant 0.000000e+00 : f32 -! CHECK: %[[UNDEF:.*]] = fir.undefined complex -! CHECK: %[[UNDEF1:.*]] = fir.insert_value %[[UNDEF]], %[[REAL]], [0 : index] : (complex, f32) -> complex -! CHECK: %[[UNDEF2:.*]] = fir.insert_value %[[UNDEF1]], %[[IMAG]], [1 : index] : (complex, f32) -> complex -! CHECK: %[[ALLOCA:.*]] = fir.alloca complex -! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) -! CHECK: fir.store %[[UNDEF2]] to %[[DECLARE]]#0 : !fir.ref> -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref> -! CHECK: } combiner { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref>, %[[ARG1:.*]]: !fir.ref>): -! CHECK: %[[LOAD0:.*]] = fir.load %[[ARG0]] : !fir.ref> -! CHECK: %[[LOAD1:.*]] = fir.load %[[ARG1]] : !fir.ref> -! CHECK: %[[COMBINED:.*]] = fir.addc %[[LOAD0]], %[[LOAD1]] {fastmath = #arith.fastmath} : complex -! CHECK: fir.store %[[COMBINED]] to %[[ARG0]] : !fir.ref> -! CHECK: acc.yield %[[ARG0]] : !fir.ref> -! CHECK: } - -! CHECK-LABEL: acc.reduction.recipe @reduction_neqv_ref_l32 : !fir.ref> reduction_operator init { -! CHECK: ^bb0(%{{.*}}: !fir.ref>): -! CHECK: %[[CST:.*]] = arith.constant false -! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.logical<4> -! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) -! CHECK: %[[CONVERT:.*]] = fir.convert %[[CST]] : (i1) -> !fir.logical<4> -! CHECK: fir.store %[[CONVERT]] to %[[DECLARE]]#0 : !fir.ref> -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref> -! CHECK: } combiner { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref>, %[[ARG1:.*]]: !fir.ref>): -! CHECK: %[[LOAD0:.*]] = fir.load %[[ARG0]] : !fir.ref> -! CHECK: %[[LOAD1:.*]] = fir.load %[[ARG1]] : !fir.ref> -! CHECK: %[[CONV0:.*]] = fir.convert %[[LOAD0]] : (!fir.logical<4>) -> i1 -! CHECK: %[[CONV1:.*]] = fir.convert %[[LOAD1]] : (!fir.logical<4>) -> i1 -! CHECK: %[[CMP:.*]] = arith.cmpi ne, %[[CONV0]], %[[CONV1]] : i1 -! CHECK: %[[CMP_CONV:.*]] = fir.convert %[[CMP]] : (i1) -> !fir.logical<4> -! CHECK: fir.store %[[CMP_CONV]] to %[[ARG0]] : !fir.ref> -! CHECK: acc.yield %[[ARG0]] : !fir.ref> -! CHECK: } - -! CHECK-LABEL: acc.reduction.recipe @reduction_eqv_ref_l32 : !fir.ref> reduction_operator init { -! CHECK: ^bb0(%{{.*}}: !fir.ref>): -! CHECK: %[[CST:.*]] = arith.constant true -! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.logical<4> -! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) -! CHECK: %[[CONVERT:.*]] = fir.convert %[[CST]] : (i1) -> !fir.logical<4> -! CHECK: fir.store %[[CONVERT]] to %[[DECLARE]]#0 : !fir.ref> -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref> -! CHECK: } combiner { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref>, %[[ARG1:.*]]: !fir.ref>): -! CHECK: %[[LOAD0:.*]] = fir.load %[[ARG0]] : !fir.ref> -! CHECK: %[[LOAD1:.*]] = fir.load %[[ARG1]] : !fir.ref> -! CHECK: %[[CONV0:.*]] = fir.convert %[[LOAD0]] : (!fir.logical<4>) -> i1 -! CHECK: %[[CONV1:.*]] = fir.convert %[[LOAD1]] : (!fir.logical<4>) -> i1 -! CHECK: %[[CMP:.*]] = arith.cmpi eq, %[[CONV0]], %[[CONV1]] : i1 -! CHECK: %[[CMP_CONV:.*]] = fir.convert %[[CMP]] : (i1) -> !fir.logical<4> -! CHECK: fir.store %[[CMP_CONV]] to %[[ARG0]] : !fir.ref> -! CHECK: acc.yield %[[ARG0]] : !fir.ref> -! CHECK: } - -! CHECK-LABEL: acc.reduction.recipe @reduction_lor_ref_l32 : !fir.ref> reduction_operator init { -! CHECK: ^bb0(%{{.*}}: !fir.ref>): -! CHECK: %[[CST:.*]] = arith.constant false -! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.logical<4> -! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) -! CHECK: %[[CONVERT:.*]] = fir.convert %[[CST]] : (i1) -> !fir.logical<4> -! CHECK: fir.store %[[CONVERT]] to %[[DECLARE]]#0 : !fir.ref> -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref> -! CHECK: } combiner { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref>, %[[ARG1:.*]]: !fir.ref>): -! CHECK: %[[LOAD0:.*]] = fir.load %[[ARG0]] : !fir.ref> -! CHECK: %[[LOAD1:.*]] = fir.load %[[ARG1]] : !fir.ref> -! CHECK: %[[CONV0:.*]] = fir.convert %[[LOAD0]] : (!fir.logical<4>) -> i1 -! CHECK: %[[CONV1:.*]] = fir.convert %[[LOAD1]] : (!fir.logical<4>) -> i1 -! CHECK: %[[CMP:.*]] = arith.ori %[[CONV0]], %[[CONV1]] : i1 -! CHECK: %[[CMP_CONV:.*]] = fir.convert %[[CMP]] : (i1) -> !fir.logical<4> -! CHECK: fir.store %[[CMP_CONV]] to %[[ARG0]] : !fir.ref> -! CHECK: acc.yield %[[ARG0]] : !fir.ref> -! CHECK: } - -! CHECK-LABEL: acc.reduction.recipe @reduction_land_ref_l32 : !fir.ref> reduction_operator init { -! CHECK: ^bb0(%{{.*}}: !fir.ref>): -! CHECK: %[[CST:.*]] = arith.constant true -! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.logical<4> -! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) -! CHECK: %[[CONVERT:.*]] = fir.convert %[[CST]] : (i1) -> !fir.logical<4> -! CHECK: fir.store %[[CONVERT]] to %[[DECLARE]]#0 : !fir.ref> -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref> -! CHECK: } combiner { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref>, %[[ARG1:.*]]: !fir.ref>): -! CHECK: %[[LOAD0:.*]] = fir.load %[[ARG0]] : !fir.ref> -! CHECK: %[[LOAD1:.*]] = fir.load %[[ARG1]] : !fir.ref> -! CHECK: %[[CONV0:.*]] = fir.convert %[[LOAD0]] : (!fir.logical<4>) -> i1 -! CHECK: %[[CONV1:.*]] = fir.convert %[[LOAD1]] : (!fir.logical<4>) -> i1 -! CHECK: %[[CMP:.*]] = arith.andi %[[CONV0]], %[[CONV1]] : i1 -! CHECK: %[[CMP_CONV:.*]] = fir.convert %[[CMP]] : (i1) -> !fir.logical<4> -! CHECK: fir.store %[[CMP_CONV]] to %[[ARG0]] : !fir.ref> -! CHECK: acc.yield %[[ARG0]] : !fir.ref> -! CHECK: } - -! CHECK-LABEL: acc.reduction.recipe @reduction_xor_ref_i32 : !fir.ref reduction_operator init { -! CHECK: ^bb0(%{{.*}}: !fir.ref): -! CHECK: %[[CST:.*]] = arith.constant 0 : i32 -! CHECK: %[[ALLOCA:.*]] = fir.alloca i32 -! CHECK: %[[DECLARE]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref) -> (!fir.ref, !fir.ref) -! CHECK: fir.store %[[CST]] to %[[DECLARE]]#0 : !fir.ref -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref -! CHECK: } combiner { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref, %[[ARG1:.*]]: !fir.ref): -! CHECK: %[[LOAD0:.*]] = fir.load %[[ARG0]] : !fir.ref -! CHECK: %[[LOAD1:.*]] = fir.load %[[ARG1]] : !fir.ref -! CHECK: %[[COMBINED:.*]] = arith.xori %[[LOAD0]], %[[LOAD1]] : i32 -! CHECK: fir.store %[[COMBINED]] to %[[ARG0]] : !fir.ref -! CHECK: acc.yield %[[ARG0]] : !fir.ref -! CHECK: } - -! CHECK-LABEL: acc.reduction.recipe @reduction_ior_ref_i32 : !fir.ref reduction_operator init { -! CHECK: ^bb0(%{{.*}}: !fir.ref): -! CHECK: %[[CST:.*]] = arith.constant 0 : i32 -! CHECK: %[[ALLOCA:.*]] = fir.alloca i32 -! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref) -> (!fir.ref, !fir.ref) -! CHECK: fir.store %[[CST]] to %[[DECLARE:.*]]#0 : !fir.ref -! CHECK: acc.yield %[[DECLARE:.*]]#0 : !fir.ref -! CHECK: } combiner { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref, %[[ARG1:.*]]: !fir.ref): -! CHECK: %[[LOAD0:.*]] = fir.load %[[ARG0]] : !fir.ref -! CHECK: %[[LOAD1:.*]] = fir.load %[[ARG1]] : !fir.ref -! CHECK: %[[COMBINED:.*]] = arith.ori %[[LOAD0]], %[[LOAD1]] : i32 -! CHECK: fir.store %[[COMBINED]] to %[[ARG0]] : !fir.ref -! CHECK: acc.yield %[[ARG0]] : !fir.ref -! CHECK: } - -! CHECK-LABEL: acc.reduction.recipe @reduction_iand_ref_i32 : !fir.ref reduction_operator init { -! CHECK: ^bb0(%{{.*}}: !fir.ref): -! CHECK: %[[CST:.*]] = arith.constant -1 : i32 -! CHECK: %[[ALLOCA:.*]] = fir.alloca i32 -! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref) -> (!fir.ref, !fir.ref) -! CHECK: fir.store %[[CST]] to %[[DECLARE]]#0 : !fir.ref -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref -! CHECK: } combiner { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref, %[[ARG1:.*]]: !fir.ref): -! CHECK: %[[LOAD0:.*]] = fir.load %[[ARG0]] : !fir.ref -! CHECK: %[[LOAD1:.*]] = fir.load %[[ARG1]] : !fir.ref -! CHECK: %[[COMBINED:.*]] = arith.andi %[[LOAD0]], %[[LOAD1]] : i32 -! CHECK: fir.store %[[COMBINED]] to %[[ARG0]] : !fir.ref -! CHECK: acc.yield %[[ARG0]] : !fir.ref -! CHECK: } - -! CHECK-LABEL: acc.reduction.recipe @reduction_max_ref_100xf32 : !fir.ref> reduction_operator init { -! CHECK: ^bb0(%{{.*}}: !fir.ref>): -! CHECK: %[[INIT:.*]] = arith.constant -1.401300e-45 : f32 -! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1> -! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<100xf32> -! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.reduction.init"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) -! CHECK: %[[LB:.*]] = arith.constant 0 : index -! CHECK: %[[UB:.*]] = arith.constant 99 : index -! CHECK: %[[STEP:.*]] = arith.constant 1 : index -! CHECK: fir.do_loop %[[IV:.*]] = %[[LB]] to %[[UB]] step %[[STEP]] { -! CHECK: %[[COORD:.*]] = fir.coordinate_of %[[DECLARE]]#0, %[[IV]] : (!fir.ref>, index) -> !fir.ref -! CHECK: fir.store %[[INIT]] to %[[COORD]] : !fir.ref -! CHECK: } -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref> -! CHECK: } combiner { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref>, %[[ARG1:.*]]: !fir.ref>): -! CHECK: %[[LB0:.*]] = arith.constant 0 : index -! CHECK: %[[UB0:.*]] = arith.constant 99 : index -! CHECK: %[[STEP0:.*]] = arith.constant 1 : index -! CHECK: fir.do_loop %[[IV0:.*]] = %[[LB0]] to %[[UB0]] step %[[STEP0]] { -! CHECK: %[[COORD1:.*]] = fir.coordinate_of %[[ARG0]], %[[IV0]] : (!fir.ref>, index) -> !fir.ref -! CHECK: %[[COORD2:.*]] = fir.coordinate_of %[[ARG1]], %[[IV0]] : (!fir.ref>, index) -> !fir.ref -! CHECK: %[[LOAD1:.*]] = fir.load %[[COORD1]] : !fir.ref -! CHECK: %[[LOAD2:.*]] = fir.load %[[COORD2]] : !fir.ref -! CHECK: %[[CMP:.*]] = arith.cmpf ogt, %[[LOAD1]], %[[LOAD2]] {{.*}} : f32 -! CHECK: %[[SELECT:.*]] = arith.select %[[CMP]], %[[LOAD1]], %[[LOAD2]] : f32 -! CHECK: fir.store %[[SELECT]] to %[[COORD1]] : !fir.ref -! CHECK: } -! CHECK: acc.yield %[[ARG0]] : !fir.ref> -! CHECK: } - -! CHECK-LABEL: acc.reduction.recipe @reduction_max_ref_f32 : !fir.ref reduction_operator init { -! CHECK: ^bb0(%{{.*}}: !fir.ref): -! CHECK: %[[INIT:.*]] = arith.constant -1.401300e-45 : f32 -! CHECK: %[[ALLOCA:.*]] = fir.alloca f32 -! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %0 {uniq_name = "acc.reduction.init"} : (!fir.ref) -> (!fir.ref, !fir.ref) -! CHECK: fir.store %[[INIT]] to %[[DECLARE]]#0 : !fir.ref -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref -! CHECK: } combiner { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref, %[[ARG1:.*]]: !fir.ref): -! CHECK: %[[LOAD0:.*]] = fir.load %[[ARG0]] : !fir.ref -! CHECK: %[[LOAD1:.*]] = fir.load %[[ARG1]] : !fir.ref -! CHECK: %[[CMP:.*]] = arith.cmpf ogt, %[[LOAD0]], %[[LOAD1]] {{.*}} : f32 -! CHECK: %[[SELECT:.*]] = arith.select %[[CMP]], %[[LOAD0]], %[[LOAD1]] : f32 -! CHECK: fir.store %[[SELECT]] to %[[ARG0]] : !fir.ref -! CHECK: acc.yield %[[ARG0]] : !fir.ref -! CHECK: } - -! CHECK-LABEL: acc.reduction.recipe @reduction_max_ref_100x10xi32 : !fir.ref> reduction_operator init { -! CHECK: ^bb0(%arg0: !fir.ref>): -! CHECK: %[[INIT:.*]] = arith.constant -2147483648 : i32 -! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2> -! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<100x10xi32> -! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.reduction.init"} : (!fir.ref>, !fir.shape<2>) -> (!fir.ref>, !fir.ref>) -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref> -! CHECK: } combiner { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref>, %[[ARG1:.*]]: !fir.ref>): -! CHECK: %[[LB0:.*]] = arith.constant 0 : index -! CHECK: %[[UB0:.*]] = arith.constant 9 : index -! CHECK: %[[STEP0:.*]] = arith.constant 1 : index -! CHECK: fir.do_loop %[[IV0:.*]] = %[[LB0]] to %[[UB0]] step %[[STEP0]] { -! CHECK: %[[LB1:.*]] = arith.constant 0 : index -! CHECK: %[[UB1:.*]] = arith.constant 99 : index -! CHECK: %[[STEP1:.*]] = arith.constant 1 : index -! CHECK: fir.do_loop %[[IV1:.*]] = %[[LB1]] to %[[UB1]] step %[[STEP1]] { -! CHECK: %[[COORD1:.*]] = fir.coordinate_of %[[ARG0:.*]], %[[IV1]], %[[IV0]] : (!fir.ref>, index, index) -> !fir.ref -! CHECK: %[[COORD2:.*]] = fir.coordinate_of %[[ARG1:.*]], %[[IV1]], %[[IV0]] : (!fir.ref>, index, index) -> !fir.ref -! CHECK: %[[LOAD1:.*]] = fir.load %[[COORD1]] : !fir.ref -! CHECK: %[[LOAD2:.*]] = fir.load %[[COORD2]] : !fir.ref -! CHECK: %[[CMP:.*]] = arith.cmpi sgt, %[[LOAD1]], %[[LOAD2]] : i32 -! CHECK: %[[SELECT:.*]] = arith.select %[[CMP]], %[[LOAD1]], %[[LOAD2]] : i32 -! CHECK: fir.store %[[SELECT]] to %[[COORD1]] : !fir.ref -! CHECK: } -! CHECK: } -! CHECK: acc.yield %[[ARG0]] : !fir.ref> -! CHECK: } - -! CHECK-LABEL: acc.reduction.recipe @reduction_max_ref_i32 : !fir.ref reduction_operator init { -! CHECK: ^bb0(%arg0: !fir.ref): -! CHECK: %[[INIT:.*]] = arith.constant -2147483648 : i32 -! CHECK: %[[ALLOCA:.*]] = fir.alloca i32 -! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref) -> (!fir.ref, !fir.ref) -! CHECK: fir.store %[[INIT]] to %[[DECLARE]]#0 : !fir.ref -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref -! CHECK: } combiner { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref, %[[ARG1:.*]]: !fir.ref): -! CHECK: %[[LOAD0:.*]] = fir.load %[[ARG0]] : !fir.ref -! CHECK: %[[LOAD1:.*]] = fir.load %[[ARG1]] : !fir.ref -! CHECK: %[[CMP:.*]] = arith.cmpi sgt, %[[LOAD0]], %[[LOAD1]] : i32 -! CHECK: %[[SELECT:.*]] = arith.select %[[CMP]], %[[LOAD0]], %[[LOAD1]] : i32 -! CHECK: fir.store %[[SELECT]] to %[[ARG0]] : !fir.ref -! CHECK: acc.yield %[[ARG0]] : !fir.ref -! CHECK: } - -! CHECK-LABEL: acc.reduction.recipe @reduction_min_ref_100x10xf32 : !fir.ref> reduction_operator init { -! CHECK: ^bb0(%{{.*}}: !fir.ref>): -! CHECK: %[[INIT:.*]] = arith.constant 3.40282347E+38 : f32 -! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2> -! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<100x10xf32> -! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.reduction.init"} : (!fir.ref>, !fir.shape<2>) -> (!fir.ref>, !fir.ref>) -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref> -! CHECK: } combiner { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref>, %[[ARG1:.*]]: !fir.ref>): -! CHECK: %[[LB0:.*]] = arith.constant 0 : index -! CHECK: %[[UB0:.*]] = arith.constant 9 : index -! CHECK: %[[STEP0:.*]] = arith.constant 1 : index -! CHECK: fir.do_loop %[[IV0:.*]] = %[[LB0]] to %[[UB0]] step %[[STEP0]] { -! CHECK: %[[LB1:.*]] = arith.constant 0 : index -! CHECK: %[[UB1:.*]] = arith.constant 99 : index -! CHECK: %[[STEP1:.*]] = arith.constant 1 : index -! CHECK: fir.do_loop %[[IV1:.*]] = %[[LB1]] to %[[UB1]] step %[[STEP1]] { -! CHECK: %[[COORD1:.*]] = fir.coordinate_of %[[ARG0]], %[[IV1]], %[[IV0]] : (!fir.ref>, index, index) -> !fir.ref -! CHECK: %[[COORD2:.*]] = fir.coordinate_of %[[ARG1]], %[[IV1]], %[[IV0]] : (!fir.ref>, index, index) -> !fir.ref -! CHECK: %[[LOAD1:.*]] = fir.load %[[COORD1]] : !fir.ref -! CHECK: %[[LOAD2:.*]] = fir.load %[[COORD2]] : !fir.ref -! CHECK: %[[CMP:.*]] = arith.cmpf olt, %[[LOAD1]], %[[LOAD2]] {{.*}} : f32 -! CHECK: %[[SELECT:.*]] = arith.select %[[CMP]], %[[LOAD1]], %[[LOAD2]] : f32 -! CHECK: fir.store %[[SELECT]] to %[[COORD1]] : !fir.ref -! CHECK: } -! CHECK: } -! CHECK: acc.yield %[[ARG0]] : !fir.ref> -! CHECK: } - -! CHECK-LABEL: acc.reduction.recipe @reduction_min_ref_f32 : !fir.ref reduction_operator init { -! CHECK: ^bb0(%{{.*}}: !fir.ref): -! CHECK: %[[INIT:.*]] = arith.constant 3.40282347E+38 : f32 -! CHECK: %[[ALLOCA:.*]] = fir.alloca f32 -! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref) -> (!fir.ref, !fir.ref) -! CHECK: fir.store %[[INIT]] to %[[DECLARE]]#0 : !fir.ref -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref -! CHECK: } combiner { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref, %[[ARG1:.*]]: !fir.ref): -! CHECK: %[[LOAD0:.*]] = fir.load %[[ARG0]] : !fir.ref -! CHECK: %[[LOAD1:.*]] = fir.load %[[ARG1]] : !fir.ref -! CHECK: %[[CMP:.*]] = arith.cmpf olt, %[[LOAD0]], %[[LOAD1]] {{.*}} : f32 -! CHECK: %[[SELECT:.*]] = arith.select %[[CMP]], %[[LOAD0]], %[[LOAD1]] : f32 -! CHECK: fir.store %[[SELECT]] to %[[ARG0]] : !fir.ref -! CHECK: acc.yield %[[ARG0]] : !fir.ref -! CHECK: } - -! CHECK-LABEL: acc.reduction.recipe @reduction_min_ref_100xi32 : !fir.ref> reduction_operator init { -! CHECK: ^bb0(%{{.*}}: !fir.ref>): -! CHECK: %[[INIT:.*]] = arith.constant 2147483647 : i32 -! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1> -! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<100xi32> -! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.reduction.init"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref> -! CHECK: } combiner { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref>, %[[ARG1:.*]]: !fir.ref>): -! CHECK: %[[LB0:.*]] = arith.constant 0 : index -! CHECK: %[[UB0:.*]] = arith.constant 99 : index -! CHECK: %[[STEP0:.*]] = arith.constant 1 : index -! CHECK: fir.do_loop %[[IV0:.*]] = %[[LB0]] to %[[UB0]] step %[[STEP0]] { -! CHECK: %[[COORD1:.*]] = fir.coordinate_of %[[ARG0]], %[[IV0]] : (!fir.ref>, index) -> !fir.ref -! CHECK: %[[COORD2:.*]] = fir.coordinate_of %[[ARG1]], %[[IV0]] : (!fir.ref>, index) -> !fir.ref -! CHECK: %[[LOAD1:.*]] = fir.load %[[COORD1]] : !fir.ref -! CHECK: %[[LOAD2:.*]] = fir.load %[[COORD2]] : !fir.ref -! CHECK: %[[CMP:.*]] = arith.cmpi slt, %[[LOAD1]], %[[LOAD2]] : i32 -! CHECK: %[[SELECT:.*]] = arith.select %[[CMP]], %[[LOAD1]], %[[LOAD2]] : i32 -! CHECK: fir.store %[[SELECT]] to %[[COORD1]] : !fir.ref -! CHECK: } -! CHECK: acc.yield %[[ARG0]] : !fir.ref> -! CHECK: } - -! CHECK-LABEL: acc.reduction.recipe @reduction_min_ref_i32 : !fir.ref reduction_operator init { -! CHECK: ^bb0(%{{.*}}: !fir.ref): -! CHECK: %[[INIT:.*]] = arith.constant 2147483647 : i32 -! CHECK: %[[ALLOCA:.*]] = fir.alloca i32 -! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref) -> (!fir.ref, !fir.ref) -! CHECK: fir.store %[[INIT]] to %[[DECLARE]]#0 : !fir.ref -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref -! CHECK: } combiner { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref, %[[ARG1:.*]]: !fir.ref): -! CHECK: %[[LOAD0:.*]] = fir.load %[[ARG0]] : !fir.ref -! CHECK: %[[LOAD1:.*]] = fir.load %[[ARG1]] : !fir.ref -! CHECK: %[[CMP:.*]] = arith.cmpi slt, %[[LOAD0]], %[[LOAD1]] : i32 -! CHECK: %[[SELECT:.*]] = arith.select %[[CMP]], %[[LOAD0]], %[[LOAD1]] : i32 -! CHECK: fir.store %[[SELECT]] to %[[ARG0]] : !fir.ref -! CHECK: acc.yield %[[ARG0]] : !fir.ref -! CHECK: } - -! CHECK-LABEL: acc.reduction.recipe @reduction_mul_ref_f32 : !fir.ref reduction_operator init { -! CHECK: ^bb0(%{{.*}}: !fir.ref): -! CHECK: %[[INIT:.*]] = arith.constant 1.000000e+00 : f32 -! CHECK: %[[ALLOCA:.*]] = fir.alloca f32 -! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref) -> (!fir.ref, !fir.ref) -! CHECK: fir.store %[[INIT]] to %[[DECLARE]]#0 : !fir.ref -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref -! CHECK: } combiner { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref, %[[ARG1:.*]]: !fir.ref): -! CHECK: %[[LOAD0:.*]] = fir.load %[[ARG0]] : !fir.ref -! CHECK: %[[LOAD1:.*]] = fir.load %[[ARG1]] : !fir.ref -! CHECK: %[[COMBINED:.*]] = arith.mulf %[[LOAD0]], %[[LOAD1]] fastmath : f32 -! CHECK: fir.store %[[COMBINED]] to %[[ARG0]] : !fir.ref -! CHECK: acc.yield %[[ARG0]] : !fir.ref -! CHECK: } - -! CHECK-LABEL: acc.reduction.recipe @reduction_mul_ref_100xi32 : !fir.ref> reduction_operator init { -! CHECK: ^bb0(%{{.*}}: !fir.ref>): -! CHECK: %[[INIT:.*]] = arith.constant 1 : i32 -! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1> -! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<100xi32> -! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.reduction.init"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref> -! CHECK: } combiner { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref>, %[[ARG1:.*]]: !fir.ref>): -! CHECK: %[[LB:.*]] = arith.constant 0 : index -! CHECK: %[[UB:.*]] = arith.constant 99 : index -! CHECK: %[[STEP:.*]] = arith.constant 1 : index -! CHECK: fir.do_loop %[[IV:.*]] = %[[LB]] to %[[UB]] step %[[STEP]] { -! CHECK: %[[COORD1:.*]] = fir.coordinate_of %[[ARG0]], %[[IV]] : (!fir.ref>, index) -> !fir.ref -! CHECK: %[[COORD2:.*]] = fir.coordinate_of %[[ARG1]], %[[IV]] : (!fir.ref>, index) -> !fir.ref -! CHECK: %[[LOAD1:.*]] = fir.load %[[COORD1]] : !fir.ref -! CHECK: %[[LOAD2:.*]] = fir.load %[[COORD2]] : !fir.ref -! CHECK: %[[COMBINED:.*]] = arith.muli %[[LOAD1]], %[[LOAD2]] : i32 -! CHECK: fir.store %[[COMBINED]] to %[[COORD1]] : !fir.ref -! CHECK: } -! CHECK: acc.yield %[[ARG0]] : !fir.ref> -! CHECK: } - -! CHECK-LABEL: acc.reduction.recipe @reduction_mul_ref_i32 : !fir.ref reduction_operator init { -! CHECK: ^bb0(%{{.*}}: !fir.ref): -! CHECK: %[[INIT:.*]] = arith.constant 1 : i32 -! CHECK: %[[ALLOCA:.*]] = fir.alloca i32 -! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref) -> (!fir.ref, !fir.ref) -! CHECK: fir.store %[[INIT]] to %[[DECLARE]]#0 : !fir.ref -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref -! CHECK: } combiner { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref, %[[ARG1:.*]]: !fir.ref): -! CHECK: %[[LOAD0:.*]] = fir.load %[[ARG0]] : !fir.ref -! CHECK: %[[LOAD1:.*]] = fir.load %[[ARG1]] : !fir.ref -! CHECK: %[[COMBINED:.*]] = arith.muli %[[LOAD0]], %[[LOAD1]] : i32 -! CHECK: fir.store %[[COMBINED]] to %[[ARG0]] : !fir.ref -! CHECK: acc.yield %[[ARG0]] : !fir.ref -! CHECK: } - -! CHECK-LABEL: acc.reduction.recipe @reduction_add_ref_100xf32 : !fir.ref> reduction_operator init { -! CHECK: ^bb0(%{{.*}}: !fir.ref>): -! CHECK: %[[INIT:.*]] = arith.constant 0.000000e+00 : f32 -! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1> -! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<100xf32> -! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.reduction.init"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref> -! CHECK: } combiner { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref>, %[[ARG1:.*]]: !fir.ref>): -! CHECK: %[[LB:.*]] = arith.constant 0 : index -! CHECK: %[[UB:.*]] = arith.constant 99 : index -! CHECK: %[[STEP:.*]] = arith.constant 1 : index -! CHECK: fir.do_loop %[[IV:.*]] = %[[LB]] to %[[UB]] step %[[STEP]] { -! CHECK: %[[COORD1:.*]] = fir.coordinate_of %[[ARG0]], %[[IV]] : (!fir.ref>, index) -> !fir.ref -! CHECK: %[[COORD2:.*]] = fir.coordinate_of %[[ARG1]], %[[IV]] : (!fir.ref>, index) -> !fir.ref -! CHECK: %[[LOAD1:.*]] = fir.load %[[COORD1]] : !fir.ref -! CHECK: %[[LOAD2:.*]] = fir.load %[[COORD2]] : !fir.ref -! CHECK: %[[COMBINED:.*]] = arith.addf %[[LOAD1]], %[[LOAD2]] fastmath : f32 -! CHECK: fir.store %[[COMBINED]] to %[[COORD1]] : !fir.ref -! CHECK: } -! CHECK: acc.yield %[[ARG0]] : !fir.ref> -! CHECK: } - -! CHECK-LABEL: acc.reduction.recipe @reduction_add_ref_f32 : !fir.ref reduction_operator init { -! CHECK: ^bb0(%{{.*}}: !fir.ref): -! CHECK: %[[INIT:.*]] = arith.constant 0.000000e+00 : f32 -! CHECK: %[[ALLOCA:.*]] = fir.alloca f32 -! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref) -> (!fir.ref, !fir.ref) -! CHECK: fir.store %[[INIT]] to %[[DECLARE]]#0 : !fir.ref -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref -! CHECK: } combiner { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref, %[[ARG1:.*]]: !fir.ref): -! CHECK: %[[LOAD0:.*]] = fir.load %[[ARG0]] : !fir.ref -! CHECK: %[[LOAD1:.*]] = fir.load %[[ARG1]] : !fir.ref -! CHECK: %[[COMBINED:.*]] = arith.addf %[[LOAD0]], %[[LOAD1]] fastmath : f32 -! CHECK: fir.store %[[COMBINED]] to %[[ARG0]] : !fir.ref -! CHECK: acc.yield %[[ARG0]] : !fir.ref -! CHECK: } - -! CHECK-LABEL: acc.reduction.recipe @reduction_add_ref_100x10x2xi32 : !fir.ref> reduction_operator init { -! CHECK: ^bb0(%{{.*}}: !fir.ref>): -! CHECK: %[[INIT:.*]] = arith.constant 0 : i32 -! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}}, %{{.*}}, %{{.*}} : (index, index, index) -> !fir.shape<3> -! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<100x10x2xi32> -! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.reduction.init"} : (!fir.ref>, !fir.shape<3>) -> (!fir.ref>, !fir.ref>) -! CHECK: %[[LB0:.*]] = arith.constant 0 : index -! CHECK: %[[UB0:.*]] = arith.constant 1 : index -! CHECK: %[[STEP0:.*]] = arith.constant 1 : index -! CHECK: fir.do_loop %[[IV0:.*]] = %[[LB0]] to %[[UB0]] step %[[STEP0]] { -! CHECK: %[[LB1:.*]] = arith.constant 0 : index -! CHECK: %[[UB1:.*]] = arith.constant 9 : index -! CHECK: %[[STEP1:.*]] = arith.constant 1 : index -! CHECK: fir.do_loop %[[IV1:.*]] = %[[LB1]] to %[[UB1]] step %[[STEP1]] { -! CHECK: %[[LB2:.*]] = arith.constant 0 : index -! CHECK: %[[UB2:.*]] = arith.constant 99 : index -! CHECK: %[[STEP2:.*]] = arith.constant 1 : index -! CHECK: fir.do_loop %[[IV2:.*]] = %[[LB2]] to %[[UB2]] step %[[STEP2]] { -! CHECK: %[[COORD]] = fir.coordinate_of %[[DECLARE]]#0, %[[IV2]], %[[IV1]], %[[IV0]] : (!fir.ref>, index, index, index) -> !fir.ref -! CHECK: fir.store %[[INIT]] to %[[COORD]] : !fir.ref -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref> -! CHECK: } combiner { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref>, %[[ARG1:.*]]: !fir.ref>): -! CHECK: %[[LB0:.*]] = arith.constant 0 : index -! CHECK: %[[UB0:.*]] = arith.constant 1 : index -! CHECK: %[[STEP0:.*]] = arith.constant 1 : index -! CHECK: fir.do_loop %[[IV0:.*]] = %[[LB0]] to %[[UB0]] step %[[STEP0]] { -! CHECK: %[[LB1:.*]] = arith.constant 0 : index -! CHECK: %[[UB1:.*]] = arith.constant 9 : index -! CHECK: %[[STEP1:.*]] = arith.constant 1 : index -! CHECK: fir.do_loop %[[IV1:.*]] = %[[LB1]] to %[[UB1]] step %[[STEP1]] { -! CHECK: %[[LB2:.*]] = arith.constant 0 : index -! CHECK: %[[UB2:.*]] = arith.constant 99 : index -! CHECK: %[[STEP2:.*]] = arith.constant 1 : index -! CHECK: fir.do_loop %[[IV2:.*]] = %[[LB2]] to %[[UB2]] step %[[STEP2]] { -! CHECK: %[[COORD1:.*]] = fir.coordinate_of %[[ARG0]], %[[IV2]], %[[IV1]], %[[IV0]] : (!fir.ref>, index, index, index) -> !fir.ref -! CHECK: %[[COORD2:.*]] = fir.coordinate_of %[[ARG1]], %[[IV2]], %[[IV1]], %[[IV0]] : (!fir.ref>, index, index, index) -> !fir.ref -! CHECK: %[[LOAD1:.*]] = fir.load %[[COORD1]] : !fir.ref -! CHECK: %[[LOAD2:.*]] = fir.load %[[COORD2]] : !fir.ref -! CHECK: %[[COMBINED:.*]] = arith.addi %[[LOAD1]], %[[LOAD2]] : i32 -! CHECK: fir.store %[[COMBINED]] to %[[COORD1]] : !fir.ref -! CHECK: } -! CHECK: } -! CHECK: } -! CHECK: acc.yield %[[ARG0]] : !fir.ref> -! CHECK: } - -! CHECK-LABEL: acc.reduction.recipe @reduction_add_ref_100x10xi32 : !fir.ref> reduction_operator init { -! CHECK: ^bb0(%{{.*}}: !fir.ref>): -! CHECK: %[[INIT:.*]] = arith.constant 0 : i32 -! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2> -! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<100x10xi32> -! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.reduction.init"} : (!fir.ref>, !fir.shape<2>) -> (!fir.ref>, !fir.ref>) -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref> -! CHECK: } combiner { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref>, %[[ARG1:.*]]: !fir.ref>): -! CHECK: %[[LB0:.*]] = arith.constant 0 : index -! CHECK: %[[UB0:.*]] = arith.constant 9 : index -! CHECK: %[[STEP0:.*]] = arith.constant 1 : index -! CHECK: fir.do_loop %[[IV0:.*]] = %[[LB0]] to %[[UB0]] step %[[STEP0]] { -! CHECK: %[[LB1:.*]] = arith.constant 0 : index -! CHECK: %[[UB1:.*]] = arith.constant 99 : index -! CHECK: %[[STEP1:.*]] = arith.constant 1 : index -! CHECK: fir.do_loop %[[IV1:.*]] = %[[LB1]] to %[[UB1]] step %[[STEP1]] { -! CHECK: %[[COORD1:.*]] = fir.coordinate_of %[[ARG0]], %[[IV1]], %[[IV0]] : (!fir.ref>, index, index) -> !fir.ref -! CHECK: %[[COORD2:.*]] = fir.coordinate_of %[[ARG1]], %[[IV1]], %[[IV0]] : (!fir.ref>, index, index) -> !fir.ref -! CHECK: %[[LOAD1]] = fir.load %[[COORD1]] : !fir.ref -! CHECK: %[[LOAD2]] = fir.load %[[COORD2]] : !fir.ref -! CHECK: %[[COMBINED:.*]] = arith.addi %[[LOAD1]], %[[LOAD2]] : i32 -! CHECK: fir.store %[[COMBINED]] to %[[COORD1]] : !fir.ref -! CHECK: } -! CHECK: } -! CHECK: acc.yield %[[ARG0]] : !fir.ref> -! CHECK: } - -! CHECK-LABEL: acc.reduction.recipe @reduction_add_ref_100xi32 : !fir.ref> reduction_operator init { -! CHECK: ^bb0(%{{.*}}: !fir.ref>): -! CHECK: %[[INIT:.*]] = arith.constant 0 : i32 -! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1> -! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.array<100xi32> -! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]](%[[SHAPE]]) {uniq_name = "acc.reduction.init"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) -! HFLIR: acc.yield %[[DECLARE]]#0 : !fir.ref> -! CHECK: } combiner { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref>, %[[ARG1:.*]]: !fir.ref>): -! CHECK: %[[LB:.*]] = arith.constant 0 : index -! CHECK: %[[UB:.*]] = arith.constant 99 : index -! CHECK: %[[STEP:.*]] = arith.constant 1 : index -! CHECK: fir.do_loop %[[IV:.*]] = %[[LB]] to %[[UB]] step %[[STEP]] { -! CHECK: %[[COORD1:.*]] = fir.coordinate_of %[[ARG0]], %[[IV]] : (!fir.ref>, index) -> !fir.ref -! CHECK: %[[COORD2:.*]] = fir.coordinate_of %[[ARG1]], %[[IV]] : (!fir.ref>, index) -> !fir.ref -! CHECK: %[[LOAD1:.*]] = fir.load %[[COORD1]] : !fir.ref -! CHECK: %[[LOAD2:.*]] = fir.load %[[COORD2]] : !fir.ref -! CHECK: %[[COMBINED:.*]] = arith.addi %[[LOAD1]], %[[LOAD2]] : i32 -! CHECK: fir.store %[[COMBINED]] to %[[COORD1]] : !fir.ref -! CHECK: } -! CHECK: acc.yield %[[ARG0]] : !fir.ref> -! CHECK: } - -! CHECK-LABEL: acc.reduction.recipe @reduction_add_ref_i32 : !fir.ref reduction_operator init { -! CHECK: ^bb0(%{{.*}}: !fir.ref): -! CHECK: %[[INIT:.*]] = arith.constant 0 : i32 -! CHECK: %[[ALLOCA:.*]] = fir.alloca i32 -! CHECK: %[[DECLARE:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "acc.reduction.init"} : (!fir.ref) -> (!fir.ref, !fir.ref) -! CHECK: fir.store %[[INIT]] to %[[DECLARE]]#0 : !fir.ref -! CHECK: acc.yield %[[DECLARE]]#0 : !fir.ref -! CHECK: } combiner { -! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref, %[[ARG1:.*]]: !fir.ref): -! CHECK: %[[LOAD0:.*]] = fir.load %[[ARG0]] : !fir.ref -! CHECK: %[[LOAD1:.*]] = fir.load %[[ARG1]] : !fir.ref -! CHECK: %[[COMBINED:.*]] = arith.addi %[[LOAD0]], %[[LOAD1]] : i32 -! CHECK: fir.store %[[COMBINED]] to %[[ARG0]] : !fir.ref -! CHECK: acc.yield %[[ARG0]] : !fir.ref -! CHECK: } +! CHECK-LABEL: acc.reduction.recipe @reduction_max_box_UxUxf32 : !fir.box> reduction_operator init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant -1.401300e-45 : f32 +! CHECK: %[[CONSTANT_1:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_1]] : (!fir.box>, index) -> (index, index, index) +! CHECK: %[[CONSTANT_2:.*]] = arith.constant 1 : index +! CHECK: %[[BOX_DIMS_1:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_2]] : (!fir.box>, index) -> (index, index, index) +! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[BOX_DIMS_0]]#1, %[[BOX_DIMS_1]]#1 : (index, index) -> !fir.shape<2> +! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array, %[[BOX_DIMS_0]]#1, %[[BOX_DIMS_1]]#1 {bindc_name = ".tmp", uniq_name = ""} +! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCMEM_0]](%[[SHAPE_0]]) {uniq_name = ".tmp"} : (!fir.heap>, !fir.shape<2>) -> (!fir.box>, !fir.heap>) +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : f32, !fir.box> +! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.box> + +! CHECK-LABEL: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box>, %[[VAL_1:.*]]: !fir.box>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_0]] : (!fir.box>, index) -> (index, index, index) +! CHECK: %[[CONSTANT_1:.*]] = arith.constant 1 : index +! CHECK: %[[BOX_DIMS_1:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_1]] : (!fir.box>, index) -> (index, index, index) +! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[BOX_DIMS_0]]#1, %[[BOX_DIMS_1]]#1 : (index, index) -> !fir.shape<2> +! CHECK: %[[CONSTANT_2:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_2:.*]]:3 = fir.box_dims %[[VAL_1]], %[[CONSTANT_2]] : (!fir.box>, index) -> (index, index, index) +! CHECK: %[[CONSTANT_3:.*]] = arith.constant 1 : index +! CHECK: %[[BOX_DIMS_3:.*]]:3 = fir.box_dims %[[VAL_1]], %[[CONSTANT_3]] : (!fir.box>, index) -> (index, index, index) +! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[BOX_DIMS_2]]#1, %[[BOX_DIMS_3]]#1 : (index, index) -> !fir.shape<2> +! CHECK: %[[CONSTANT_4:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_4]] to %[[BOX_DIMS_1]]#1 step %[[CONSTANT_4]] unordered { +! CHECK: fir.do_loop %[[VAL_3:.*]] = %[[CONSTANT_4]] to %[[BOX_DIMS_0]]#1 step %[[CONSTANT_4]] unordered { +! CHECK: %[[CONSTANT_5:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_4:.*]]:3 = fir.box_dims %[[VAL_1]], %[[CONSTANT_5]] : (!fir.box>, index) -> (index, index, index) +! CHECK: %[[CONSTANT_6:.*]] = arith.constant 1 : index +! CHECK: %[[BOX_DIMS_5:.*]]:3 = fir.box_dims %[[VAL_1]], %[[CONSTANT_6]] : (!fir.box>, index) -> (index, index, index) +! CHECK: %[[CONSTANT_7:.*]] = arith.constant 1 : index +! CHECK: %[[SUBI_0:.*]] = arith.subi %[[BOX_DIMS_4]]#0, %[[CONSTANT_7]] : index +! CHECK: %[[ADDI_0:.*]] = arith.addi %[[VAL_3]], %[[SUBI_0]] : index +! CHECK: %[[SUBI_1:.*]] = arith.subi %[[BOX_DIMS_5]]#0, %[[CONSTANT_7]] : index +! CHECK: %[[ADDI_1:.*]] = arith.addi %[[VAL_2]], %[[SUBI_1]] : index +! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_1]] (%[[ADDI_0]], %[[ADDI_1]]) : (!fir.box>, index, index) -> !fir.ref +! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_0]] : !fir.ref +! CHECK: %[[CONSTANT_8:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_6:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_8]] : (!fir.box>, index) -> (index, index, index) +! CHECK: %[[CONSTANT_9:.*]] = arith.constant 1 : index +! CHECK: %[[BOX_DIMS_7:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_9]] : (!fir.box>, index) -> (index, index, index) +! CHECK: %[[CONSTANT_10:.*]] = arith.constant 1 : index +! CHECK: %[[SUBI_2:.*]] = arith.subi %[[BOX_DIMS_6]]#0, %[[CONSTANT_10]] : index +! CHECK: %[[ADDI_2:.*]] = arith.addi %[[VAL_3]], %[[SUBI_2]] : index +! CHECK: %[[SUBI_3:.*]] = arith.subi %[[BOX_DIMS_7]]#0, %[[CONSTANT_10]] : index +! CHECK: %[[ADDI_3:.*]] = arith.addi %[[VAL_2]], %[[SUBI_3]] : index +! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%[[ADDI_2]], %[[ADDI_3]]) : (!fir.box>, index, index) -> !fir.ref +! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_1]] : !fir.ref +! CHECK: %[[CMPF_0:.*]] = arith.cmpf ogt, %[[LOAD_1]], %[[LOAD_0]] fastmath : f32 +! CHECK: %[[SELECT_0:.*]] = arith.select %[[CMPF_0]], %[[LOAD_1]], %[[LOAD_0]] : f32 +! CHECK: hlfir.assign %[[SELECT_0]] to %[[DESIGNATE_1]] : f32, !fir.ref +! CHECK: } +! CHECK: } +! CHECK: acc.yield %[[VAL_0]] : !fir.box> + +! CHECK-LABEL: } destroy { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box>, %[[VAL_1:.*]]: !fir.box>): +! CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>) -> !fir.ref> +! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[BOX_ADDR_0]] : (!fir.ref>) -> !fir.heap> +! CHECK: fir.freemem %[[CONVERT_0]] : !fir.heap> +! CHECK: acc.terminator +! CHECK: } + +! CHECK-LABEL: acc.reduction.recipe @reduction_max_ref_box_ptr_Uxf32 : !fir.ref>>> reduction_operator init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>>>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant -1.401300e-45 : f32 +! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_0]] : !fir.ref>>> +! CHECK: %[[CONSTANT_1:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[LOAD_0]], %[[CONSTANT_1]] : (!fir.box>>, index) -> (index, index, index) +! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[BOX_DIMS_0]]#1 : (index) -> !fir.shape<1> +! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array, %[[BOX_DIMS_0]]#1 {bindc_name = ".tmp", uniq_name = ""} +! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCMEM_0]](%[[SHAPE_0]]) {uniq_name = ".tmp"} : (!fir.heap>, !fir.shape<1>) -> (!fir.box>, !fir.heap>) +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.box>> +! CHECK: %[[DECLARE_1:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref>>>) -> (!fir.ref>>>, !fir.ref>>>) +! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[DECLARE_1]]#0 : (!fir.ref>>>) -> !fir.ref>> +! CHECK: fir.store %[[DECLARE_0]]#0 to %[[CONVERT_0]] : !fir.ref>> +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DECLARE_1]]#0 : f32, !fir.ref>>> +! CHECK: acc.yield %[[DECLARE_1]]#0 : !fir.ref>>> + +! CHECK-LABEL: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>>>, %[[VAL_1:.*]]: !fir.ref>>>): +! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref>>> +! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref>>> +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[LOAD_1]], %[[CONSTANT_0]] : (!fir.box>>, index) -> (index, index, index) +! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[BOX_DIMS_0]]#1 : (index) -> !fir.shape<1> +! CHECK: %[[CONSTANT_1:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_1:.*]]:3 = fir.box_dims %[[LOAD_0]], %[[CONSTANT_1]] : (!fir.box>>, index) -> (index, index, index) +! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[BOX_DIMS_1]]#1 : (index) -> !fir.shape<1> +! CHECK: %[[CONSTANT_2:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_2]] to %[[BOX_DIMS_0]]#1 step %[[CONSTANT_2]] unordered { +! CHECK: %[[CONSTANT_3:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_2:.*]]:3 = fir.box_dims %[[LOAD_0]], %[[CONSTANT_3]] : (!fir.box>>, index) -> (index, index, index) +! CHECK: %[[CONSTANT_4:.*]] = arith.constant 1 : index +! CHECK: %[[SUBI_0:.*]] = arith.subi %[[BOX_DIMS_2]]#0, %[[CONSTANT_4]] : index +! CHECK: %[[ADDI_0:.*]] = arith.addi %[[VAL_2]], %[[SUBI_0]] : index +! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[LOAD_0]] (%[[ADDI_0]]) : (!fir.box>>, index) -> !fir.ref +! CHECK: %[[LOAD_2:.*]] = fir.load %[[DESIGNATE_0]] : !fir.ref +! CHECK: %[[CONSTANT_5:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_3:.*]]:3 = fir.box_dims %[[LOAD_1]], %[[CONSTANT_5]] : (!fir.box>>, index) -> (index, index, index) +! CHECK: %[[CONSTANT_6:.*]] = arith.constant 1 : index +! CHECK: %[[SUBI_1:.*]] = arith.subi %[[BOX_DIMS_3]]#0, %[[CONSTANT_6]] : index +! CHECK: %[[ADDI_1:.*]] = arith.addi %[[VAL_2]], %[[SUBI_1]] : index +! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[LOAD_1]] (%[[ADDI_1]]) : (!fir.box>>, index) -> !fir.ref +! CHECK: %[[LOAD_3:.*]] = fir.load %[[DESIGNATE_1]] : !fir.ref +! CHECK: %[[CMPF_0:.*]] = arith.cmpf ogt, %[[LOAD_3]], %[[LOAD_2]] fastmath : f32 +! CHECK: %[[SELECT_0:.*]] = arith.select %[[CMPF_0]], %[[LOAD_3]], %[[LOAD_2]] : f32 +! CHECK: hlfir.assign %[[SELECT_0]] to %[[DESIGNATE_1]] : f32, !fir.ref +! CHECK: } +! CHECK: acc.yield %[[VAL_0]] : !fir.ref>>> + +! CHECK-LABEL: } destroy { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>>>, %[[VAL_1:.*]]: !fir.ref>>>): +! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref>>> +! CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_0]] : (!fir.box>>) -> !fir.ptr> +! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[BOX_ADDR_0]] : (!fir.ptr>) -> !fir.heap> +! CHECK: fir.freemem %[[CONVERT_0]] : !fir.heap> +! CHECK: acc.terminator +! CHECK: } + +! CHECK-LABEL: acc.reduction.recipe @reduction_max_ref_box_heap_Uxf32 : !fir.ref>>> reduction_operator init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>>>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant -1.401300e-45 : f32 +! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_0]] : !fir.ref>>> +! CHECK: %[[CONSTANT_1:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[LOAD_0]], %[[CONSTANT_1]] : (!fir.box>>, index) -> (index, index, index) +! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[BOX_DIMS_0]]#1 : (index) -> !fir.shape<1> +! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array, %[[BOX_DIMS_0]]#1 {bindc_name = ".tmp", uniq_name = ""} +! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCMEM_0]](%[[SHAPE_0]]) {uniq_name = ".tmp"} : (!fir.heap>, !fir.shape<1>) -> (!fir.box>, !fir.heap>) +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.box>> +! CHECK: %[[DECLARE_1:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref>>>) -> (!fir.ref>>>, !fir.ref>>>) +! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[DECLARE_1]]#0 : (!fir.ref>>>) -> !fir.ref>> +! CHECK: fir.store %[[DECLARE_0]]#0 to %[[CONVERT_0]] : !fir.ref>> +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DECLARE_1]]#0 : f32, !fir.ref>>> +! CHECK: acc.yield %[[DECLARE_1]]#0 : !fir.ref>>> + +! CHECK-LABEL: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>>>, %[[VAL_1:.*]]: !fir.ref>>>): +! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref>>> +! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref>>> +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[LOAD_1]], %[[CONSTANT_0]] : (!fir.box>>, index) -> (index, index, index) +! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[BOX_DIMS_0]]#1 : (index) -> !fir.shape<1> +! CHECK: %[[CONSTANT_1:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_1:.*]]:3 = fir.box_dims %[[LOAD_0]], %[[CONSTANT_1]] : (!fir.box>>, index) -> (index, index, index) +! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[BOX_DIMS_1]]#1 : (index) -> !fir.shape<1> +! CHECK: %[[CONSTANT_2:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_2]] to %[[BOX_DIMS_0]]#1 step %[[CONSTANT_2]] unordered { +! CHECK: %[[CONSTANT_3:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_2:.*]]:3 = fir.box_dims %[[LOAD_0]], %[[CONSTANT_3]] : (!fir.box>>, index) -> (index, index, index) +! CHECK: %[[CONSTANT_4:.*]] = arith.constant 1 : index +! CHECK: %[[SUBI_0:.*]] = arith.subi %[[BOX_DIMS_2]]#0, %[[CONSTANT_4]] : index +! CHECK: %[[ADDI_0:.*]] = arith.addi %[[VAL_2]], %[[SUBI_0]] : index +! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[LOAD_0]] (%[[ADDI_0]]) : (!fir.box>>, index) -> !fir.ref +! CHECK: %[[LOAD_2:.*]] = fir.load %[[DESIGNATE_0]] : !fir.ref +! CHECK: %[[CONSTANT_5:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_3:.*]]:3 = fir.box_dims %[[LOAD_1]], %[[CONSTANT_5]] : (!fir.box>>, index) -> (index, index, index) +! CHECK: %[[CONSTANT_6:.*]] = arith.constant 1 : index +! CHECK: %[[SUBI_1:.*]] = arith.subi %[[BOX_DIMS_3]]#0, %[[CONSTANT_6]] : index +! CHECK: %[[ADDI_1:.*]] = arith.addi %[[VAL_2]], %[[SUBI_1]] : index +! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[LOAD_1]] (%[[ADDI_1]]) : (!fir.box>>, index) -> !fir.ref +! CHECK: %[[LOAD_3:.*]] = fir.load %[[DESIGNATE_1]] : !fir.ref +! CHECK: %[[CMPF_0:.*]] = arith.cmpf ogt, %[[LOAD_3]], %[[LOAD_2]] fastmath : f32 +! CHECK: %[[SELECT_0:.*]] = arith.select %[[CMPF_0]], %[[LOAD_3]], %[[LOAD_2]] : f32 +! CHECK: hlfir.assign %[[SELECT_0]] to %[[DESIGNATE_1]] : f32, !fir.ref +! CHECK: } +! CHECK: acc.yield %[[VAL_0]] : !fir.ref>>> + +! CHECK-LABEL: } destroy { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>>>, %[[VAL_1:.*]]: !fir.ref>>>): +! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref>>> +! CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_0]] : (!fir.box>>) -> !fir.heap> +! CHECK: fir.freemem %[[BOX_ADDR_0]] : !fir.heap> +! CHECK: acc.terminator +! CHECK: } + +! CHECK-LABEL: acc.reduction.recipe @reduction_add_section_lb1.ub3_box_Uxi32 : !fir.box> reduction_operator init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : i32 +! CHECK: %[[CONSTANT_1:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_1]] : (!fir.box>, index) -> (index, index, index) +! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[BOX_DIMS_0]]#1 : (index) -> !fir.shape<1> +! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array, %[[BOX_DIMS_0]]#1 {bindc_name = ".tmp", uniq_name = ""} +! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCMEM_0]](%[[SHAPE_0]]) {uniq_name = ".tmp"} : (!fir.heap>, !fir.shape<1>) -> (!fir.box>, !fir.heap>) +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : i32, !fir.box> +! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.box> + +! CHECK-LABEL: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box>, %[[VAL_1:.*]]: !fir.box>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 1 : index +! CHECK: %[[CONSTANT_1:.*]] = arith.constant 3 : index +! CHECK: %[[CONSTANT_2:.*]] = arith.constant 1 : index +! CHECK: %[[CONSTANT_3:.*]] = arith.constant 0 : index +! CHECK: %[[SUBI_0:.*]] = arith.subi %[[CONSTANT_1]], %[[CONSTANT_0]] : index +! CHECK: %[[ADDI_0:.*]] = arith.addi %[[SUBI_0]], %[[CONSTANT_2]] : index +! CHECK: %[[DIVSI_0:.*]] = arith.divsi %[[ADDI_0]], %[[CONSTANT_2]] : index +! CHECK: %[[CMPI_0:.*]] = arith.cmpi sgt, %[[DIVSI_0]], %[[CONSTANT_3]] : index +! CHECK: %[[SELECT_0:.*]] = arith.select %[[CMPI_0]], %[[DIVSI_0]], %[[CONSTANT_3]] : index +! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[SELECT_0]] : (index) -> !fir.shape<1> +! CHECK: %[[BD_LHS:.*]]:3 = fir.box_dims %[[VAL_0]], %c0{{.*}} : (!fir.box>, index) -> (index, index, index) +! CHECK: %[[LB_LHS:.*]] = arith.addi %[[BD_LHS]]#0, %c1{{.*}} : index +! CHECK: %[[UB_LHS:.*]] = arith.addi %[[BD_LHS]]#0, %c3{{.*}} : index +! CHECK: %[[BD_RHS:.*]]:3 = fir.box_dims %[[VAL_1]], %c0{{.*}} : (!fir.box>, index) -> (index, index, index) +! CHECK: %[[LB_RHS:.*]] = arith.addi %[[BD_RHS]]#0, %c1{{.*}} : index +! CHECK: %[[UB_RHS:.*]] = arith.addi %[[BD_RHS]]#0, %c3{{.*}} : index +! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_1]] (%[[LB_RHS]]:%[[UB_RHS]]:%c1{{.*}}) shape %[[SHAPE_0]] : (!fir.box>, index, index, index, !fir.shape<1>) -> !fir.box> +! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%[[LB_LHS]]:%[[UB_LHS]]:%c1{{.*}}) shape %[[SHAPE_0]] : (!fir.box>, index, index, index, !fir.shape<1>) -> !fir.box> +! CHECK: %[[CONSTANT_4:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_4]] to %[[SELECT_0]] step %[[CONSTANT_4]] unordered { +! CHECK: %[[DESIGNATE_2:.*]] = hlfir.designate %[[DESIGNATE_0]] (%[[VAL_2]]) : (!fir.box>, index) -> !fir.ref +! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_2]] : !fir.ref +! CHECK: %[[DESIGNATE_3:.*]] = hlfir.designate %[[DESIGNATE_1]] (%[[VAL_2]]) : (!fir.box>, index) -> !fir.ref +! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_3]] : !fir.ref +! CHECK: %[[ADDI_1:.*]] = arith.addi %[[LOAD_1]], %[[LOAD_0]] : i32 +! CHECK: hlfir.assign %[[ADDI_1]] to %[[DESIGNATE_3]] : i32, !fir.ref +! CHECK: } +! CHECK: acc.yield %[[VAL_0]] : !fir.box> + +! CHECK-LABEL: } destroy { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box>, %[[VAL_1:.*]]: !fir.box>): +! CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>) -> !fir.ref> +! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[BOX_ADDR_0]] : (!fir.ref>) -> !fir.heap> +! CHECK: fir.freemem %[[CONVERT_0]] : !fir.heap> +! CHECK: acc.terminator +! CHECK: } + +! CHECK-LABEL: acc.reduction.recipe @reduction_max_box_Uxf32 : !fir.box> reduction_operator init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant -1.401300e-45 : f32 +! CHECK: %[[CONSTANT_1:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_1]] : (!fir.box>, index) -> (index, index, index) +! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[BOX_DIMS_0]]#1 : (index) -> !fir.shape<1> +! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array, %[[BOX_DIMS_0]]#1 {bindc_name = ".tmp", uniq_name = ""} +! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCMEM_0]](%[[SHAPE_0]]) {uniq_name = ".tmp"} : (!fir.heap>, !fir.shape<1>) -> (!fir.box>, !fir.heap>) +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : f32, !fir.box> +! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.box> + +! CHECK-LABEL: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box>, %[[VAL_1:.*]]: !fir.box>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_0]] : (!fir.box>, index) -> (index, index, index) +! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[BOX_DIMS_0]]#1 : (index) -> !fir.shape<1> +! CHECK: %[[CONSTANT_1:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_1:.*]]:3 = fir.box_dims %[[VAL_1]], %[[CONSTANT_1]] : (!fir.box>, index) -> (index, index, index) +! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[BOX_DIMS_1]]#1 : (index) -> !fir.shape<1> +! CHECK: %[[CONSTANT_2:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_2]] to %[[BOX_DIMS_0]]#1 step %[[CONSTANT_2]] unordered { +! CHECK: %[[CONSTANT_3:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_2:.*]]:3 = fir.box_dims %[[VAL_1]], %[[CONSTANT_3]] : (!fir.box>, index) -> (index, index, index) +! CHECK: %[[CONSTANT_4:.*]] = arith.constant 1 : index +! CHECK: %[[SUBI_0:.*]] = arith.subi %[[BOX_DIMS_2]]#0, %[[CONSTANT_4]] : index +! CHECK: %[[ADDI_0:.*]] = arith.addi %[[VAL_2]], %[[SUBI_0]] : index +! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_1]] (%[[ADDI_0]]) : (!fir.box>, index) -> !fir.ref +! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_0]] : !fir.ref +! CHECK: %[[CONSTANT_5:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_3:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_5]] : (!fir.box>, index) -> (index, index, index) +! CHECK: %[[CONSTANT_6:.*]] = arith.constant 1 : index +! CHECK: %[[SUBI_1:.*]] = arith.subi %[[BOX_DIMS_3]]#0, %[[CONSTANT_6]] : index +! CHECK: %[[ADDI_1:.*]] = arith.addi %[[VAL_2]], %[[SUBI_1]] : index +! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%[[ADDI_1]]) : (!fir.box>, index) -> !fir.ref +! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_1]] : !fir.ref +! CHECK: %[[CMPF_0:.*]] = arith.cmpf ogt, %[[LOAD_1]], %[[LOAD_0]] fastmath : f32 +! CHECK: %[[SELECT_0:.*]] = arith.select %[[CMPF_0]], %[[LOAD_1]], %[[LOAD_0]] : f32 +! CHECK: hlfir.assign %[[SELECT_0]] to %[[DESIGNATE_1]] : f32, !fir.ref +! CHECK: } +! CHECK: acc.yield %[[VAL_0]] : !fir.box> + +! CHECK-LABEL: } destroy { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box>, %[[VAL_1:.*]]: !fir.box>): +! CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>) -> !fir.ref> +! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[BOX_ADDR_0]] : (!fir.ref>) -> !fir.heap> +! CHECK: fir.freemem %[[CONVERT_0]] : !fir.heap> +! CHECK: acc.terminator +! CHECK: } + +! CHECK-LABEL: acc.reduction.recipe @reduction_add_box_Uxi32 : !fir.box> reduction_operator init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : i32 +! CHECK: %[[CONSTANT_1:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_1]] : (!fir.box>, index) -> (index, index, index) +! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[BOX_DIMS_0]]#1 : (index) -> !fir.shape<1> +! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array, %[[BOX_DIMS_0]]#1 {bindc_name = ".tmp", uniq_name = ""} +! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCMEM_0]](%[[SHAPE_0]]) {uniq_name = ".tmp"} : (!fir.heap>, !fir.shape<1>) -> (!fir.box>, !fir.heap>) +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : i32, !fir.box> +! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.box> + +! CHECK-LABEL: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box>, %[[VAL_1:.*]]: !fir.box>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_0]] : (!fir.box>, index) -> (index, index, index) +! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[BOX_DIMS_0]]#1 : (index) -> !fir.shape<1> +! CHECK: %[[CONSTANT_1:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_1:.*]]:3 = fir.box_dims %[[VAL_1]], %[[CONSTANT_1]] : (!fir.box>, index) -> (index, index, index) +! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[BOX_DIMS_1]]#1 : (index) -> !fir.shape<1> +! CHECK: %[[CONSTANT_2:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_2]] to %[[BOX_DIMS_0]]#1 step %[[CONSTANT_2]] unordered { +! CHECK: %[[CONSTANT_3:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_2:.*]]:3 = fir.box_dims %[[VAL_1]], %[[CONSTANT_3]] : (!fir.box>, index) -> (index, index, index) +! CHECK: %[[CONSTANT_4:.*]] = arith.constant 1 : index +! CHECK: %[[SUBI_0:.*]] = arith.subi %[[BOX_DIMS_2]]#0, %[[CONSTANT_4]] : index +! CHECK: %[[ADDI_0:.*]] = arith.addi %[[VAL_2]], %[[SUBI_0]] : index +! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_1]] (%[[ADDI_0]]) : (!fir.box>, index) -> !fir.ref +! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_0]] : !fir.ref +! CHECK: %[[CONSTANT_5:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS_3:.*]]:3 = fir.box_dims %[[VAL_0]], %[[CONSTANT_5]] : (!fir.box>, index) -> (index, index, index) +! CHECK: %[[CONSTANT_6:.*]] = arith.constant 1 : index +! CHECK: %[[SUBI_1:.*]] = arith.subi %[[BOX_DIMS_3]]#0, %[[CONSTANT_6]] : index +! CHECK: %[[ADDI_1:.*]] = arith.addi %[[VAL_2]], %[[SUBI_1]] : index +! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%[[ADDI_1]]) : (!fir.box>, index) -> !fir.ref +! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_1]] : !fir.ref +! CHECK: %[[ADDI_2:.*]] = arith.addi %[[LOAD_1]], %[[LOAD_0]] : i32 +! CHECK: hlfir.assign %[[ADDI_2]] to %[[DESIGNATE_1]] : i32, !fir.ref +! CHECK: } +! CHECK: acc.yield %[[VAL_0]] : !fir.box> + +! CHECK-LABEL: } destroy { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box>, %[[VAL_1:.*]]: !fir.box>): +! CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>) -> !fir.ref> +! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[BOX_ADDR_0]] : (!fir.ref>) -> !fir.heap> +! CHECK: fir.freemem %[[CONVERT_0]] : !fir.heap> +! CHECK: acc.terminator +! CHECK: } + +! CHECK-LABEL: acc.reduction.recipe @reduction_add_section_lb0.ub9xlb0.ub19_ref_10x20xi32 : !fir.ref> reduction_operator init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : i32 +! CHECK: %[[CONSTANT_1:.*]] = arith.constant 10 : index +! CHECK: %[[CONSTANT_2:.*]] = arith.constant 20 : index +! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_1]], %[[CONSTANT_2]] : (index, index) -> !fir.shape<2> +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<10x20xi32> +! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]](%[[SHAPE_0]]) {uniq_name = "acc.reduction.init"} : (!fir.ref>, !fir.shape<2>) -> (!fir.ref>, !fir.ref>) +! CHECK: %[[CONSTANT_3:.*]] = arith.constant 0 : index +! CHECK: %[[CONSTANT_4:.*]] = arith.constant 19 : index +! CHECK: %[[CONSTANT_5:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_3]] to %[[CONSTANT_4]] step %[[CONSTANT_5]] { +! CHECK: %[[CONSTANT_6:.*]] = arith.constant 0 : index +! CHECK: %[[CONSTANT_7:.*]] = arith.constant 9 : index +! CHECK: %[[CONSTANT_8:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_6]] to %[[CONSTANT_7]] step %[[CONSTANT_8]] { +! CHECK: %[[COORDINATE_OF_0:.*]] = fir.coordinate_of %[[DECLARE_0]]#0, %[[VAL_2]], %[[VAL_1]] : (!fir.ref>, index, index) -> !fir.ref +! CHECK: fir.store %[[CONSTANT_0]] to %[[COORDINATE_OF_0]] : !fir.ref +! CHECK: } +! CHECK: } +! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref> + +! CHECK-LABEL: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : index +! CHECK: %[[CONSTANT_1:.*]] = arith.constant 9 : index +! CHECK: %[[CONSTANT_2:.*]] = arith.constant 1 : index +! CHECK: %[[CONSTANT_3:.*]] = arith.constant 0 : index +! CHECK: %[[CONSTANT_4:.*]] = arith.constant 19 : index +! CHECK: %[[CONSTANT_5:.*]] = arith.constant 1 : index +! CHECK: %[[CONSTANT_6:.*]] = arith.constant 0 : index +! CHECK: %[[SUBI_0:.*]] = arith.subi %[[CONSTANT_1]], %[[CONSTANT_0]] : index +! CHECK: %[[ADDI_0:.*]] = arith.addi %[[SUBI_0]], %[[CONSTANT_2]] : index +! CHECK: %[[DIVSI_0:.*]] = arith.divsi %[[ADDI_0]], %[[CONSTANT_2]] : index +! CHECK: %[[CMPI_0:.*]] = arith.cmpi sgt, %[[DIVSI_0]], %[[CONSTANT_6]] : index +! CHECK: %[[SELECT_0:.*]] = arith.select %[[CMPI_0]], %[[DIVSI_0]], %[[CONSTANT_6]] : index +! CHECK: %[[CONSTANT_7:.*]] = arith.constant 0 : index +! CHECK: %[[SUBI_1:.*]] = arith.subi %[[CONSTANT_4]], %[[CONSTANT_3]] : index +! CHECK: %[[ADDI_1:.*]] = arith.addi %[[SUBI_1]], %[[CONSTANT_5]] : index +! CHECK: %[[DIVSI_1:.*]] = arith.divsi %[[ADDI_1]], %[[CONSTANT_5]] : index +! CHECK: %[[CMPI_1:.*]] = arith.cmpi sgt, %[[DIVSI_1]], %[[CONSTANT_7]] : index +! CHECK: %[[SELECT_1:.*]] = arith.select %[[CMPI_1]], %[[DIVSI_1]], %[[CONSTANT_7]] : index +! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[SELECT_0]], %[[SELECT_1]] : (index, index) -> !fir.shape<2> +! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_1]] (%c1{{.*}}:%c10{{.*}}:%c1{{.*}}, %c1{{.*}}:%c20{{.*}}:%c1{{.*}}) shape %[[SHAPE_0]] : (!fir.ref>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.ref> +! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%c1{{.*}}:%c10{{.*}}:%c1{{.*}}, %c1{{.*}}:%c20{{.*}}:%c1{{.*}}) shape %[[SHAPE_0]] : (!fir.ref>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.ref> +! CHECK: %[[CONSTANT_8:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_8]] to %[[SELECT_1]] step %[[CONSTANT_8]] unordered { +! CHECK: fir.do_loop %[[VAL_3:.*]] = %[[CONSTANT_8]] to %[[SELECT_0]] step %[[CONSTANT_8]] unordered { +! CHECK: %[[DESIGNATE_2:.*]] = hlfir.designate %[[DESIGNATE_0]] (%[[VAL_3]], %[[VAL_2]]) : (!fir.ref>, index, index) -> !fir.ref +! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_2]] : !fir.ref +! CHECK: %[[DESIGNATE_3:.*]] = hlfir.designate %[[DESIGNATE_1]] (%[[VAL_3]], %[[VAL_2]]) : (!fir.ref>, index, index) -> !fir.ref +! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_3]] : !fir.ref +! CHECK: %[[ADDI_2:.*]] = arith.addi %[[LOAD_1]], %[[LOAD_0]] : i32 +! CHECK: hlfir.assign %[[ADDI_2]] to %[[DESIGNATE_3]] : i32, !fir.ref +! CHECK: } +! CHECK: } +! CHECK: acc.yield %[[VAL_0]] : !fir.ref> +! CHECK: } + +! CHECK-LABEL: acc.reduction.recipe @reduction_add_section_lb10.ub19_ref_100xi32 : !fir.ref> reduction_operator init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : i32 +! CHECK: %[[CONSTANT_1:.*]] = arith.constant 100 : index +! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_1]] : (index) -> !fir.shape<1> +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<100xi32> +! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]](%[[SHAPE_0]]) {uniq_name = "acc.reduction.init"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) +! CHECK: %[[CONSTANT_2:.*]] = arith.constant 0 : index +! CHECK: %[[CONSTANT_3:.*]] = arith.constant 99 : index +! CHECK: %[[CONSTANT_4:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_2]] to %[[CONSTANT_3]] step %[[CONSTANT_4]] { +! CHECK: %[[COORDINATE_OF_0:.*]] = fir.coordinate_of %[[DECLARE_0]]#0, %[[VAL_1]] : (!fir.ref>, index) -> !fir.ref +! CHECK: fir.store %[[CONSTANT_0]] to %[[COORDINATE_OF_0]] : !fir.ref +! CHECK: } +! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref> + +! CHECK-LABEL: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 10 : index +! CHECK: %[[CONSTANT_1:.*]] = arith.constant 19 : index +! CHECK: %[[CONSTANT_2:.*]] = arith.constant 1 : index +! CHECK: %[[CONSTANT_3:.*]] = arith.constant 0 : index +! CHECK: %[[SUBI_0:.*]] = arith.subi %[[CONSTANT_1]], %[[CONSTANT_0]] : index +! CHECK: %[[ADDI_0:.*]] = arith.addi %[[SUBI_0]], %[[CONSTANT_2]] : index +! CHECK: %[[DIVSI_0:.*]] = arith.divsi %[[ADDI_0]], %[[CONSTANT_2]] : index +! CHECK: %[[CMPI_0:.*]] = arith.cmpi sgt, %[[DIVSI_0]], %[[CONSTANT_3]] : index +! CHECK: %[[SELECT_0:.*]] = arith.select %[[CMPI_0]], %[[DIVSI_0]], %[[CONSTANT_3]] : index +! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[SELECT_0]] : (index) -> !fir.shape<1> +! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_1]] (%c11{{.*}}:%c20{{.*}}:%c1{{.*}}) shape %[[SHAPE_0]] : (!fir.ref>, index, index, index, !fir.shape<1>) -> !fir.ref> +! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%c11{{.*}}:%c20{{.*}}:%c1{{.*}}) shape %[[SHAPE_0]] : (!fir.ref>, index, index, index, !fir.shape<1>) -> !fir.ref> +! CHECK: %[[CONSTANT_4:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_4]] to %[[SELECT_0]] step %[[CONSTANT_4]] unordered { +! CHECK: %[[DESIGNATE_2:.*]] = hlfir.designate %[[DESIGNATE_0]] (%[[VAL_2]]) : (!fir.ref>, index) -> !fir.ref +! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_2]] : !fir.ref +! CHECK: %[[DESIGNATE_3:.*]] = hlfir.designate %[[DESIGNATE_1]] (%[[VAL_2]]) : (!fir.ref>, index) -> !fir.ref +! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_3]] : !fir.ref +! CHECK: %[[ADDI_1:.*]] = arith.addi %[[LOAD_1]], %[[LOAD_0]] : i32 +! CHECK: hlfir.assign %[[ADDI_1]] to %[[DESIGNATE_3]] : i32, !fir.ref +! CHECK: } +! CHECK: acc.yield %[[VAL_0]] : !fir.ref> +! CHECK: } + +! CHECK-LABEL: acc.reduction.recipe @reduction_add_ref_box_ptr_i32 : !fir.ref>> reduction_operator init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : i32 +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.box> +! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref>>) -> (!fir.ref>>, !fir.ref>>) +! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem i32 +! CHECK: %[[EMBOX_0:.*]] = fir.embox %[[ALLOCMEM_0]] : (!fir.heap) -> !fir.box> +! CHECK: fir.store %[[EMBOX_0]] to %[[DECLARE_0]]#0 : !fir.ref>> +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : i32, !fir.ref>> +! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref>> + +! CHECK-LABEL: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>>, %[[VAL_1:.*]]: !fir.ref>>): +! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref>> +! CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_0]] : (!fir.box>) -> !fir.ptr +! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref>> +! CHECK: %[[BOX_ADDR_1:.*]] = fir.box_addr %[[LOAD_1]] : (!fir.box>) -> !fir.ptr +! CHECK: %[[LOAD_2:.*]] = fir.load %[[BOX_ADDR_0]] : !fir.ptr +! CHECK: %[[LOAD_3:.*]] = fir.load %[[BOX_ADDR_1]] : !fir.ptr +! CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_3]], %[[LOAD_2]] : i32 +! CHECK: hlfir.assign %[[ADDI_0]] to %[[BOX_ADDR_1]] : i32, !fir.ptr +! CHECK: acc.yield %[[VAL_0]] : !fir.ref>> + +! CHECK-LABEL: } destroy { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>>, %[[VAL_1:.*]]: !fir.ref>>): +! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref>> +! CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_0]] : (!fir.box>) -> !fir.ptr +! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[BOX_ADDR_0]] : (!fir.ptr) -> !fir.heap +! CHECK: fir.freemem %[[CONVERT_0]] : !fir.heap +! CHECK: acc.terminator +! CHECK: } + +! CHECK-LABEL: acc.reduction.recipe @reduction_add_ref_box_heap_i32 : !fir.ref>> reduction_operator init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : i32 +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.box> +! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref>>) -> (!fir.ref>>, !fir.ref>>) +! CHECK: %[[ALLOCMEM_0:.*]] = fir.allocmem i32 +! CHECK: %[[EMBOX_0:.*]] = fir.embox %[[ALLOCMEM_0]] : (!fir.heap) -> !fir.box> +! CHECK: fir.store %[[EMBOX_0]] to %[[DECLARE_0]]#0 : !fir.ref>> +! CHECK: hlfir.assign %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : i32, !fir.ref>> +! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref>> + +! CHECK-LABEL: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>>, %[[VAL_1:.*]]: !fir.ref>>): +! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref>> +! CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_0]] : (!fir.box>) -> !fir.heap +! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref>> +! CHECK: %[[BOX_ADDR_1:.*]] = fir.box_addr %[[LOAD_1]] : (!fir.box>) -> !fir.heap +! CHECK: %[[LOAD_2:.*]] = fir.load %[[BOX_ADDR_0]] : !fir.heap +! CHECK: %[[LOAD_3:.*]] = fir.load %[[BOX_ADDR_1]] : !fir.heap +! CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_3]], %[[LOAD_2]] : i32 +! CHECK: hlfir.assign %[[ADDI_0]] to %[[BOX_ADDR_1]] : i32, !fir.heap +! CHECK: acc.yield %[[VAL_0]] : !fir.ref>> + +! CHECK-LABEL: } destroy { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>>, %[[VAL_1:.*]]: !fir.ref>>): +! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref>> +! CHECK: %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_0]] : (!fir.box>) -> !fir.heap +! CHECK: fir.freemem %[[BOX_ADDR_0]] : !fir.heap +! CHECK: acc.terminator +! CHECK: } + +! CHECK-LABEL: acc.reduction.recipe @reduction_mul_ref_z32 : !fir.ref> reduction_operator init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 1.000000e+00 : f32 +! CHECK: %[[CONSTANT_1:.*]] = arith.constant 0.000000e+00 : f32 +! CHECK: %[[UNDEFINED_0:.*]] = fir.undefined complex +! CHECK: %[[INSERT_VALUE_0:.*]] = fir.insert_value %[[UNDEFINED_0]], %[[CONSTANT_0]], [0 : index] : (complex, f32) -> complex +! CHECK: %[[INSERT_VALUE_1:.*]] = fir.insert_value %[[INSERT_VALUE_0]], %[[CONSTANT_1]], [1 : index] : (complex, f32) -> complex +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca complex +! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) +! CHECK: fir.store %[[INSERT_VALUE_1]] to %[[DECLARE_0]]#0 : !fir.ref> +! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref> + +! CHECK-LABEL: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): +! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref> +! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref> +! CHECK: %[[MULC_0:.*]] = fir.mulc %[[LOAD_1]], %[[LOAD_0]] {fastmath = #arith.fastmath} : complex +! CHECK: hlfir.assign %[[MULC_0]] to %[[VAL_0]] : complex, !fir.ref> +! CHECK: acc.yield %[[VAL_0]] : !fir.ref> +! CHECK: } + +! CHECK-LABEL: acc.reduction.recipe @reduction_add_ref_z32 : !fir.ref> reduction_operator init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0.000000e+00 : f32 +! CHECK: %[[CONSTANT_1:.*]] = arith.constant 0.000000e+00 : f32 +! CHECK: %[[UNDEFINED_0:.*]] = fir.undefined complex +! CHECK: %[[INSERT_VALUE_0:.*]] = fir.insert_value %[[UNDEFINED_0]], %[[CONSTANT_0]], [0 : index] : (complex, f32) -> complex +! CHECK: %[[INSERT_VALUE_1:.*]] = fir.insert_value %[[INSERT_VALUE_0]], %[[CONSTANT_1]], [1 : index] : (complex, f32) -> complex +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca complex +! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) +! CHECK: fir.store %[[INSERT_VALUE_1]] to %[[DECLARE_0]]#0 : !fir.ref> +! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref> + +! CHECK-LABEL: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): +! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref> +! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref> +! CHECK: %[[ADDC_0:.*]] = fir.addc %[[LOAD_1]], %[[LOAD_0]] {fastmath = #arith.fastmath} : complex +! CHECK: hlfir.assign %[[ADDC_0]] to %[[VAL_0]] : complex, !fir.ref> +! CHECK: acc.yield %[[VAL_0]] : !fir.ref> +! CHECK: } + +! CHECK-LABEL: acc.reduction.recipe @reduction_neqv_ref_l32 : !fir.ref> reduction_operator init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant false +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.logical<4> +! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) +! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[CONSTANT_0]] : (i1) -> !fir.logical<4> +! CHECK: fir.store %[[CONVERT_0]] to %[[DECLARE_0]]#0 : !fir.ref> +! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref> + +! CHECK-LABEL: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): +! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref> +! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref> +! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[LOAD_1]] : (!fir.logical<4>) -> i1 +! CHECK: %[[CONVERT_1:.*]] = fir.convert %[[LOAD_0]] : (!fir.logical<4>) -> i1 +! CHECK: %[[CMPI_0:.*]] = arith.cmpi ne, %[[CONVERT_0]], %[[CONVERT_1]] : i1 +! CHECK: %[[CONVERT_2:.*]] = fir.convert %[[CMPI_0]] : (i1) -> !fir.logical<4> +! CHECK: hlfir.assign %[[CONVERT_2]] to %[[VAL_0]] : !fir.logical<4>, !fir.ref> +! CHECK: acc.yield %[[VAL_0]] : !fir.ref> +! CHECK: } + +! CHECK-LABEL: acc.reduction.recipe @reduction_eqv_ref_l32 : !fir.ref> reduction_operator init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant true +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.logical<4> +! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) +! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[CONSTANT_0]] : (i1) -> !fir.logical<4> +! CHECK: fir.store %[[CONVERT_0]] to %[[DECLARE_0]]#0 : !fir.ref> +! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref> + +! CHECK-LABEL: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): +! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref> +! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref> +! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[LOAD_1]] : (!fir.logical<4>) -> i1 +! CHECK: %[[CONVERT_1:.*]] = fir.convert %[[LOAD_0]] : (!fir.logical<4>) -> i1 +! CHECK: %[[CMPI_0:.*]] = arith.cmpi eq, %[[CONVERT_0]], %[[CONVERT_1]] : i1 +! CHECK: %[[CONVERT_2:.*]] = fir.convert %[[CMPI_0]] : (i1) -> !fir.logical<4> +! CHECK: hlfir.assign %[[CONVERT_2]] to %[[VAL_0]] : !fir.logical<4>, !fir.ref> +! CHECK: acc.yield %[[VAL_0]] : !fir.ref> +! CHECK: } + +! CHECK-LABEL: acc.reduction.recipe @reduction_lor_ref_l32 : !fir.ref> reduction_operator init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant false +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.logical<4> +! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) +! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[CONSTANT_0]] : (i1) -> !fir.logical<4> +! CHECK: fir.store %[[CONVERT_0]] to %[[DECLARE_0]]#0 : !fir.ref> +! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref> + +! CHECK-LABEL: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): +! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref> +! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref> +! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[LOAD_1]] : (!fir.logical<4>) -> i1 +! CHECK: %[[CONVERT_1:.*]] = fir.convert %[[LOAD_0]] : (!fir.logical<4>) -> i1 +! CHECK: %[[ORI_0:.*]] = arith.ori %[[CONVERT_0]], %[[CONVERT_1]] : i1 +! CHECK: %[[CONVERT_2:.*]] = fir.convert %[[ORI_0]] : (i1) -> !fir.logical<4> +! CHECK: hlfir.assign %[[CONVERT_2]] to %[[VAL_0]] : !fir.logical<4>, !fir.ref> +! CHECK: acc.yield %[[VAL_0]] : !fir.ref> +! CHECK: } + +! CHECK-LABEL: acc.reduction.recipe @reduction_land_ref_l32 : !fir.ref> reduction_operator init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant true +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.logical<4> +! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) +! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[CONSTANT_0]] : (i1) -> !fir.logical<4> +! CHECK: fir.store %[[CONVERT_0]] to %[[DECLARE_0]]#0 : !fir.ref> +! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref> + +! CHECK-LABEL: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): +! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref> +! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref> +! CHECK: %[[CONVERT_0:.*]] = fir.convert %[[LOAD_1]] : (!fir.logical<4>) -> i1 +! CHECK: %[[CONVERT_1:.*]] = fir.convert %[[LOAD_0]] : (!fir.logical<4>) -> i1 +! CHECK: %[[ANDI_0:.*]] = arith.andi %[[CONVERT_0]], %[[CONVERT_1]] : i1 +! CHECK: %[[CONVERT_2:.*]] = fir.convert %[[ANDI_0]] : (i1) -> !fir.logical<4> +! CHECK: hlfir.assign %[[CONVERT_2]] to %[[VAL_0]] : !fir.logical<4>, !fir.ref> +! CHECK: acc.yield %[[VAL_0]] : !fir.ref> +! CHECK: } + +! CHECK-LABEL: acc.reduction.recipe @reduction_xor_ref_i32 : !fir.ref reduction_operator init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : i32 +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 +! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: fir.store %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : !fir.ref +! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref + +! CHECK-LABEL: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref, %[[VAL_1:.*]]: !fir.ref): +! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref +! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref +! CHECK: %[[XORI_0:.*]] = arith.xori %[[LOAD_1]], %[[LOAD_0]] : i32 +! CHECK: hlfir.assign %[[XORI_0]] to %[[VAL_0]] : i32, !fir.ref +! CHECK: acc.yield %[[VAL_0]] : !fir.ref +! CHECK: } + +! CHECK-LABEL: acc.reduction.recipe @reduction_ior_ref_i32 : !fir.ref reduction_operator init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : i32 +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 +! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: fir.store %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : !fir.ref +! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref + +! CHECK-LABEL: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref, %[[VAL_1:.*]]: !fir.ref): +! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref +! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref +! CHECK: %[[ORI_0:.*]] = arith.ori %[[LOAD_1]], %[[LOAD_0]] : i32 +! CHECK: hlfir.assign %[[ORI_0]] to %[[VAL_0]] : i32, !fir.ref +! CHECK: acc.yield %[[VAL_0]] : !fir.ref +! CHECK: } + +! CHECK-LABEL: acc.reduction.recipe @reduction_iand_ref_i32 : !fir.ref reduction_operator init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant -1 : i32 +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 +! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: fir.store %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : !fir.ref +! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref + +! CHECK-LABEL: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref, %[[VAL_1:.*]]: !fir.ref): +! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref +! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref +! CHECK: %[[ANDI_0:.*]] = arith.andi %[[LOAD_1]], %[[LOAD_0]] : i32 +! CHECK: hlfir.assign %[[ANDI_0]] to %[[VAL_0]] : i32, !fir.ref +! CHECK: acc.yield %[[VAL_0]] : !fir.ref +! CHECK: } + +! CHECK-LABEL: acc.reduction.recipe @reduction_max_ref_100xf32 : !fir.ref> reduction_operator init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant -1.401300e-45 : f32 +! CHECK: %[[CONSTANT_1:.*]] = arith.constant 100 : index +! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_1]] : (index) -> !fir.shape<1> +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<100xf32> +! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]](%[[SHAPE_0]]) {uniq_name = "acc.reduction.init"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) +! CHECK: %[[CONSTANT_2:.*]] = arith.constant 0 : index +! CHECK: %[[CONSTANT_3:.*]] = arith.constant 99 : index +! CHECK: %[[CONSTANT_4:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_2]] to %[[CONSTANT_3]] step %[[CONSTANT_4]] { +! CHECK: %[[COORDINATE_OF_0:.*]] = fir.coordinate_of %[[DECLARE_0]]#0, %[[VAL_1]] : (!fir.ref>, index) -> !fir.ref +! CHECK: fir.store %[[CONSTANT_0]] to %[[COORDINATE_OF_0]] : !fir.ref +! CHECK: } +! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref> + +! CHECK-LABEL: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 100 : index +! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_0]] : (index) -> !fir.shape<1> +! CHECK: %[[CONSTANT_1:.*]] = arith.constant 100 : index +! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[CONSTANT_1]] : (index) -> !fir.shape<1> +! CHECK: %[[CONSTANT_2:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_2]] to %[[CONSTANT_0]] step %[[CONSTANT_2]] unordered { +! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_1]] (%[[VAL_2]]) : (!fir.ref>, index) -> !fir.ref +! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_0]] : !fir.ref +! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_2]]) : (!fir.ref>, index) -> !fir.ref +! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_1]] : !fir.ref +! CHECK: %[[CMPF_0:.*]] = arith.cmpf ogt, %[[LOAD_1]], %[[LOAD_0]] fastmath : f32 +! CHECK: %[[SELECT_0:.*]] = arith.select %[[CMPF_0]], %[[LOAD_1]], %[[LOAD_0]] : f32 +! CHECK: hlfir.assign %[[SELECT_0]] to %[[DESIGNATE_1]] : f32, !fir.ref +! CHECK: } +! CHECK: acc.yield %[[VAL_0]] : !fir.ref> +! CHECK: } + +! CHECK-LABEL: acc.reduction.recipe @reduction_max_ref_f32 : !fir.ref reduction_operator init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant -1.401300e-45 : f32 +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca f32 +! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: fir.store %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : !fir.ref +! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref + +! CHECK-LABEL: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref, %[[VAL_1:.*]]: !fir.ref): +! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref +! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref +! CHECK: %[[CMPF_0:.*]] = arith.cmpf ogt, %[[LOAD_1]], %[[LOAD_0]] fastmath : f32 +! CHECK: %[[SELECT_0:.*]] = arith.select %[[CMPF_0]], %[[LOAD_1]], %[[LOAD_0]] : f32 +! CHECK: hlfir.assign %[[SELECT_0]] to %[[VAL_0]] : f32, !fir.ref +! CHECK: acc.yield %[[VAL_0]] : !fir.ref +! CHECK: } + +! CHECK-LABEL: acc.reduction.recipe @reduction_max_ref_100x10xi32 : !fir.ref> reduction_operator init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant -2147483648 : i32 +! CHECK: %[[CONSTANT_1:.*]] = arith.constant 100 : index +! CHECK: %[[CONSTANT_2:.*]] = arith.constant 10 : index +! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_1]], %[[CONSTANT_2]] : (index, index) -> !fir.shape<2> +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<100x10xi32> +! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]](%[[SHAPE_0]]) {uniq_name = "acc.reduction.init"} : (!fir.ref>, !fir.shape<2>) -> (!fir.ref>, !fir.ref>) +! CHECK: %[[CONSTANT_3:.*]] = arith.constant 0 : index +! CHECK: %[[CONSTANT_4:.*]] = arith.constant 9 : index +! CHECK: %[[CONSTANT_5:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_3]] to %[[CONSTANT_4]] step %[[CONSTANT_5]] { +! CHECK: %[[CONSTANT_6:.*]] = arith.constant 0 : index +! CHECK: %[[CONSTANT_7:.*]] = arith.constant 99 : index +! CHECK: %[[CONSTANT_8:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_6]] to %[[CONSTANT_7]] step %[[CONSTANT_8]] { +! CHECK: %[[COORDINATE_OF_0:.*]] = fir.coordinate_of %[[DECLARE_0]]#0, %[[VAL_2]], %[[VAL_1]] : (!fir.ref>, index, index) -> !fir.ref +! CHECK: fir.store %[[CONSTANT_0]] to %[[COORDINATE_OF_0]] : !fir.ref +! CHECK: } +! CHECK: } +! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref> + +! CHECK-LABEL: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 100 : index +! CHECK: %[[CONSTANT_1:.*]] = arith.constant 10 : index +! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_0]], %[[CONSTANT_1]] : (index, index) -> !fir.shape<2> +! CHECK: %[[CONSTANT_2:.*]] = arith.constant 100 : index +! CHECK: %[[CONSTANT_3:.*]] = arith.constant 10 : index +! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[CONSTANT_2]], %[[CONSTANT_3]] : (index, index) -> !fir.shape<2> +! CHECK: %[[CONSTANT_4:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_4]] to %[[CONSTANT_1]] step %[[CONSTANT_4]] unordered { +! CHECK: fir.do_loop %[[VAL_3:.*]] = %[[CONSTANT_4]] to %[[CONSTANT_0]] step %[[CONSTANT_4]] unordered { +! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_1]] (%[[VAL_3]], %[[VAL_2]]) : (!fir.ref>, index, index) -> !fir.ref +! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_0]] : !fir.ref +! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_3]], %[[VAL_2]]) : (!fir.ref>, index, index) -> !fir.ref +! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_1]] : !fir.ref +! CHECK: %[[CMPI_0:.*]] = arith.cmpi sgt, %[[LOAD_1]], %[[LOAD_0]] : i32 +! CHECK: %[[SELECT_0:.*]] = arith.select %[[CMPI_0]], %[[LOAD_1]], %[[LOAD_0]] : i32 +! CHECK: hlfir.assign %[[SELECT_0]] to %[[DESIGNATE_1]] : i32, !fir.ref +! CHECK: } +! CHECK: } +! CHECK: acc.yield %[[VAL_0]] : !fir.ref> +! CHECK: } + +! CHECK-LABEL: acc.reduction.recipe @reduction_max_ref_i32 : !fir.ref reduction_operator init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant -2147483648 : i32 +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 +! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: fir.store %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : !fir.ref +! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref + +! CHECK-LABEL: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref, %[[VAL_1:.*]]: !fir.ref): +! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref +! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref +! CHECK: %[[CMPI_0:.*]] = arith.cmpi sgt, %[[LOAD_1]], %[[LOAD_0]] : i32 +! CHECK: %[[SELECT_0:.*]] = arith.select %[[CMPI_0]], %[[LOAD_1]], %[[LOAD_0]] : i32 +! CHECK: hlfir.assign %[[SELECT_0]] to %[[VAL_0]] : i32, !fir.ref +! CHECK: acc.yield %[[VAL_0]] : !fir.ref +! CHECK: } + +! CHECK-LABEL: acc.reduction.recipe @reduction_min_ref_100x10xf32 : !fir.ref> reduction_operator init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 3.40282347E+38 : f32 +! CHECK: %[[CONSTANT_1:.*]] = arith.constant 100 : index +! CHECK: %[[CONSTANT_2:.*]] = arith.constant 10 : index +! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_1]], %[[CONSTANT_2]] : (index, index) -> !fir.shape<2> +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<100x10xf32> +! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]](%[[SHAPE_0]]) {uniq_name = "acc.reduction.init"} : (!fir.ref>, !fir.shape<2>) -> (!fir.ref>, !fir.ref>) +! CHECK: %[[CONSTANT_3:.*]] = arith.constant 0 : index +! CHECK: %[[CONSTANT_4:.*]] = arith.constant 9 : index +! CHECK: %[[CONSTANT_5:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_3]] to %[[CONSTANT_4]] step %[[CONSTANT_5]] { +! CHECK: %[[CONSTANT_6:.*]] = arith.constant 0 : index +! CHECK: %[[CONSTANT_7:.*]] = arith.constant 99 : index +! CHECK: %[[CONSTANT_8:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_6]] to %[[CONSTANT_7]] step %[[CONSTANT_8]] { +! CHECK: %[[COORDINATE_OF_0:.*]] = fir.coordinate_of %[[DECLARE_0]]#0, %[[VAL_2]], %[[VAL_1]] : (!fir.ref>, index, index) -> !fir.ref +! CHECK: fir.store %[[CONSTANT_0]] to %[[COORDINATE_OF_0]] : !fir.ref +! CHECK: } +! CHECK: } +! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref> + +! CHECK-LABEL: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 100 : index +! CHECK: %[[CONSTANT_1:.*]] = arith.constant 10 : index +! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_0]], %[[CONSTANT_1]] : (index, index) -> !fir.shape<2> +! CHECK: %[[CONSTANT_2:.*]] = arith.constant 100 : index +! CHECK: %[[CONSTANT_3:.*]] = arith.constant 10 : index +! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[CONSTANT_2]], %[[CONSTANT_3]] : (index, index) -> !fir.shape<2> +! CHECK: %[[CONSTANT_4:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_4]] to %[[CONSTANT_1]] step %[[CONSTANT_4]] unordered { +! CHECK: fir.do_loop %[[VAL_3:.*]] = %[[CONSTANT_4]] to %[[CONSTANT_0]] step %[[CONSTANT_4]] unordered { +! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_1]] (%[[VAL_3]], %[[VAL_2]]) : (!fir.ref>, index, index) -> !fir.ref +! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_0]] : !fir.ref +! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_3]], %[[VAL_2]]) : (!fir.ref>, index, index) -> !fir.ref +! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_1]] : !fir.ref +! CHECK: %[[CMPF_0:.*]] = arith.cmpf olt, %[[LOAD_1]], %[[LOAD_0]] fastmath : f32 +! CHECK: %[[SELECT_0:.*]] = arith.select %[[CMPF_0]], %[[LOAD_1]], %[[LOAD_0]] : f32 +! CHECK: hlfir.assign %[[SELECT_0]] to %[[DESIGNATE_1]] : f32, !fir.ref +! CHECK: } +! CHECK: } +! CHECK: acc.yield %[[VAL_0]] : !fir.ref> +! CHECK: } + +! CHECK-LABEL: acc.reduction.recipe @reduction_min_ref_f32 : !fir.ref reduction_operator init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 3.40282347E+38 : f32 +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca f32 +! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: fir.store %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : !fir.ref +! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref + +! CHECK-LABEL: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref, %[[VAL_1:.*]]: !fir.ref): +! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref +! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref +! CHECK: %[[CMPF_0:.*]] = arith.cmpf olt, %[[LOAD_1]], %[[LOAD_0]] fastmath : f32 +! CHECK: %[[SELECT_0:.*]] = arith.select %[[CMPF_0]], %[[LOAD_1]], %[[LOAD_0]] : f32 +! CHECK: hlfir.assign %[[SELECT_0]] to %[[VAL_0]] : f32, !fir.ref +! CHECK: acc.yield %[[VAL_0]] : !fir.ref +! CHECK: } + +! CHECK-LABEL: acc.reduction.recipe @reduction_min_ref_100xi32 : !fir.ref> reduction_operator init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 2147483647 : i32 +! CHECK: %[[CONSTANT_1:.*]] = arith.constant 100 : index +! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_1]] : (index) -> !fir.shape<1> +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<100xi32> +! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]](%[[SHAPE_0]]) {uniq_name = "acc.reduction.init"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) +! CHECK: %[[CONSTANT_2:.*]] = arith.constant 0 : index +! CHECK: %[[CONSTANT_3:.*]] = arith.constant 99 : index +! CHECK: %[[CONSTANT_4:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_2]] to %[[CONSTANT_3]] step %[[CONSTANT_4]] { +! CHECK: %[[COORDINATE_OF_0:.*]] = fir.coordinate_of %[[DECLARE_0]]#0, %[[VAL_1]] : (!fir.ref>, index) -> !fir.ref +! CHECK: fir.store %[[CONSTANT_0]] to %[[COORDINATE_OF_0]] : !fir.ref +! CHECK: } +! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref> + +! CHECK-LABEL: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 100 : index +! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_0]] : (index) -> !fir.shape<1> +! CHECK: %[[CONSTANT_1:.*]] = arith.constant 100 : index +! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[CONSTANT_1]] : (index) -> !fir.shape<1> +! CHECK: %[[CONSTANT_2:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_2]] to %[[CONSTANT_0]] step %[[CONSTANT_2]] unordered { +! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_1]] (%[[VAL_2]]) : (!fir.ref>, index) -> !fir.ref +! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_0]] : !fir.ref +! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_2]]) : (!fir.ref>, index) -> !fir.ref +! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_1]] : !fir.ref +! CHECK: %[[CMPI_0:.*]] = arith.cmpi slt, %[[LOAD_1]], %[[LOAD_0]] : i32 +! CHECK: %[[SELECT_0:.*]] = arith.select %[[CMPI_0]], %[[LOAD_1]], %[[LOAD_0]] : i32 +! CHECK: hlfir.assign %[[SELECT_0]] to %[[DESIGNATE_1]] : i32, !fir.ref +! CHECK: } +! CHECK: acc.yield %[[VAL_0]] : !fir.ref> +! CHECK: } + +! CHECK-LABEL: acc.reduction.recipe @reduction_min_ref_i32 : !fir.ref reduction_operator init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 2147483647 : i32 +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 +! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: fir.store %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : !fir.ref +! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref + +! CHECK-LABEL: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref, %[[VAL_1:.*]]: !fir.ref): +! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref +! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref +! CHECK: %[[CMPI_0:.*]] = arith.cmpi slt, %[[LOAD_1]], %[[LOAD_0]] : i32 +! CHECK: %[[SELECT_0:.*]] = arith.select %[[CMPI_0]], %[[LOAD_1]], %[[LOAD_0]] : i32 +! CHECK: hlfir.assign %[[SELECT_0]] to %[[VAL_0]] : i32, !fir.ref +! CHECK: acc.yield %[[VAL_0]] : !fir.ref +! CHECK: } + +! CHECK-LABEL: acc.reduction.recipe @reduction_mul_ref_100xf32 : !fir.ref> reduction_operator init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 1.000000e+00 : f32 +! CHECK: %[[CONSTANT_1:.*]] = arith.constant 100 : index +! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_1]] : (index) -> !fir.shape<1> +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<100xf32> +! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]](%[[SHAPE_0]]) {uniq_name = "acc.reduction.init"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) +! CHECK: %[[CONSTANT_2:.*]] = arith.constant 0 : index +! CHECK: %[[CONSTANT_3:.*]] = arith.constant 99 : index +! CHECK: %[[CONSTANT_4:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_2]] to %[[CONSTANT_3]] step %[[CONSTANT_4]] { +! CHECK: %[[COORDINATE_OF_0:.*]] = fir.coordinate_of %[[DECLARE_0]]#0, %[[VAL_1]] : (!fir.ref>, index) -> !fir.ref +! CHECK: fir.store %[[CONSTANT_0]] to %[[COORDINATE_OF_0]] : !fir.ref +! CHECK: } +! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref> + +! CHECK-LABEL: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 100 : index +! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_0]] : (index) -> !fir.shape<1> +! CHECK: %[[CONSTANT_1:.*]] = arith.constant 100 : index +! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[CONSTANT_1]] : (index) -> !fir.shape<1> +! CHECK: %[[CONSTANT_2:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_2]] to %[[CONSTANT_0]] step %[[CONSTANT_2]] unordered { +! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_1]] (%[[VAL_2]]) : (!fir.ref>, index) -> !fir.ref +! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_0]] : !fir.ref +! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_2]]) : (!fir.ref>, index) -> !fir.ref +! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_1]] : !fir.ref +! CHECK: %[[MULF_0:.*]] = arith.mulf %[[LOAD_1]], %[[LOAD_0]] fastmath : f32 +! CHECK: hlfir.assign %[[MULF_0]] to %[[DESIGNATE_1]] : f32, !fir.ref +! CHECK: } +! CHECK: acc.yield %[[VAL_0]] : !fir.ref> +! CHECK: } + +! CHECK-LABEL: acc.reduction.recipe @reduction_mul_ref_f32 : !fir.ref reduction_operator init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 1.000000e+00 : f32 +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca f32 +! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: fir.store %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : !fir.ref +! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref + +! CHECK-LABEL: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref, %[[VAL_1:.*]]: !fir.ref): +! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref +! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref +! CHECK: %[[MULF_0:.*]] = arith.mulf %[[LOAD_1]], %[[LOAD_0]] fastmath : f32 +! CHECK: hlfir.assign %[[MULF_0]] to %[[VAL_0]] : f32, !fir.ref +! CHECK: acc.yield %[[VAL_0]] : !fir.ref +! CHECK: } + +! CHECK-LABEL: acc.reduction.recipe @reduction_mul_ref_100xi32 : !fir.ref> reduction_operator init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 1 : i32 +! CHECK: %[[CONSTANT_1:.*]] = arith.constant 100 : index +! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_1]] : (index) -> !fir.shape<1> +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<100xi32> +! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]](%[[SHAPE_0]]) {uniq_name = "acc.reduction.init"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) +! CHECK: %[[CONSTANT_2:.*]] = arith.constant 0 : index +! CHECK: %[[CONSTANT_3:.*]] = arith.constant 99 : index +! CHECK: %[[CONSTANT_4:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_2]] to %[[CONSTANT_3]] step %[[CONSTANT_4]] { +! CHECK: %[[COORDINATE_OF_0:.*]] = fir.coordinate_of %[[DECLARE_0]]#0, %[[VAL_1]] : (!fir.ref>, index) -> !fir.ref +! CHECK: fir.store %[[CONSTANT_0]] to %[[COORDINATE_OF_0]] : !fir.ref +! CHECK: } +! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref> + +! CHECK-LABEL: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 100 : index +! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_0]] : (index) -> !fir.shape<1> +! CHECK: %[[CONSTANT_1:.*]] = arith.constant 100 : index +! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[CONSTANT_1]] : (index) -> !fir.shape<1> +! CHECK: %[[CONSTANT_2:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_2]] to %[[CONSTANT_0]] step %[[CONSTANT_2]] unordered { +! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_1]] (%[[VAL_2]]) : (!fir.ref>, index) -> !fir.ref +! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_0]] : !fir.ref +! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_2]]) : (!fir.ref>, index) -> !fir.ref +! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_1]] : !fir.ref +! CHECK: %[[MULI_0:.*]] = arith.muli %[[LOAD_1]], %[[LOAD_0]] : i32 +! CHECK: hlfir.assign %[[MULI_0]] to %[[DESIGNATE_1]] : i32, !fir.ref +! CHECK: } +! CHECK: acc.yield %[[VAL_0]] : !fir.ref> +! CHECK: } + +! CHECK-LABEL: acc.reduction.recipe @reduction_mul_ref_i32 : !fir.ref reduction_operator init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 1 : i32 +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 +! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: fir.store %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : !fir.ref +! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref + +! CHECK-LABEL: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref, %[[VAL_1:.*]]: !fir.ref): +! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref +! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref +! CHECK: %[[MULI_0:.*]] = arith.muli %[[LOAD_1]], %[[LOAD_0]] : i32 +! CHECK: hlfir.assign %[[MULI_0]] to %[[VAL_0]] : i32, !fir.ref +! CHECK: acc.yield %[[VAL_0]] : !fir.ref +! CHECK: } + +! CHECK-LABEL: acc.reduction.recipe @reduction_add_ref_100xf32 : !fir.ref> reduction_operator init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0.000000e+00 : f32 +! CHECK: %[[CONSTANT_1:.*]] = arith.constant 100 : index +! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_1]] : (index) -> !fir.shape<1> +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<100xf32> +! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]](%[[SHAPE_0]]) {uniq_name = "acc.reduction.init"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) +! CHECK: %[[CONSTANT_2:.*]] = arith.constant 0 : index +! CHECK: %[[CONSTANT_3:.*]] = arith.constant 99 : index +! CHECK: %[[CONSTANT_4:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_2]] to %[[CONSTANT_3]] step %[[CONSTANT_4]] { +! CHECK: %[[COORDINATE_OF_0:.*]] = fir.coordinate_of %[[DECLARE_0]]#0, %[[VAL_1]] : (!fir.ref>, index) -> !fir.ref +! CHECK: fir.store %[[CONSTANT_0]] to %[[COORDINATE_OF_0]] : !fir.ref +! CHECK: } +! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref> + +! CHECK-LABEL: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 100 : index +! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_0]] : (index) -> !fir.shape<1> +! CHECK: %[[CONSTANT_1:.*]] = arith.constant 100 : index +! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[CONSTANT_1]] : (index) -> !fir.shape<1> +! CHECK: %[[CONSTANT_2:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_2]] to %[[CONSTANT_0]] step %[[CONSTANT_2]] unordered { +! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_1]] (%[[VAL_2]]) : (!fir.ref>, index) -> !fir.ref +! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_0]] : !fir.ref +! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_2]]) : (!fir.ref>, index) -> !fir.ref +! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_1]] : !fir.ref +! CHECK: %[[ADDF_0:.*]] = arith.addf %[[LOAD_1]], %[[LOAD_0]] fastmath : f32 +! CHECK: hlfir.assign %[[ADDF_0]] to %[[DESIGNATE_1]] : f32, !fir.ref +! CHECK: } +! CHECK: acc.yield %[[VAL_0]] : !fir.ref> +! CHECK: } + +! CHECK-LABEL: acc.reduction.recipe @reduction_add_ref_f32 : !fir.ref reduction_operator init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0.000000e+00 : f32 +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca f32 +! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: fir.store %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : !fir.ref +! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref + +! CHECK-LABEL: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref, %[[VAL_1:.*]]: !fir.ref): +! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref +! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref +! CHECK: %[[ADDF_0:.*]] = arith.addf %[[LOAD_1]], %[[LOAD_0]] fastmath : f32 +! CHECK: hlfir.assign %[[ADDF_0]] to %[[VAL_0]] : f32, !fir.ref +! CHECK: acc.yield %[[VAL_0]] : !fir.ref +! CHECK: } + +! CHECK-LABEL: acc.reduction.recipe @reduction_add_ref_100x10x2xi32 : !fir.ref> reduction_operator init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : i32 +! CHECK: %[[CONSTANT_1:.*]] = arith.constant 100 : index +! CHECK: %[[CONSTANT_2:.*]] = arith.constant 10 : index +! CHECK: %[[CONSTANT_3:.*]] = arith.constant 2 : index +! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_1]], %[[CONSTANT_2]], %[[CONSTANT_3]] : (index, index, index) -> !fir.shape<3> +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<100x10x2xi32> +! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]](%[[SHAPE_0]]) {uniq_name = "acc.reduction.init"} : (!fir.ref>, !fir.shape<3>) -> (!fir.ref>, !fir.ref>) +! CHECK: %[[CONSTANT_4:.*]] = arith.constant 0 : index +! CHECK: %[[CONSTANT_5:.*]] = arith.constant 1 : index +! CHECK: %[[CONSTANT_6:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_4]] to %[[CONSTANT_5]] step %[[CONSTANT_6]] { +! CHECK: %[[CONSTANT_7:.*]] = arith.constant 0 : index +! CHECK: %[[CONSTANT_8:.*]] = arith.constant 9 : index +! CHECK: %[[CONSTANT_9:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_7]] to %[[CONSTANT_8]] step %[[CONSTANT_9]] { +! CHECK: %[[CONSTANT_10:.*]] = arith.constant 0 : index +! CHECK: %[[CONSTANT_11:.*]] = arith.constant 99 : index +! CHECK: %[[CONSTANT_12:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_3:.*]] = %[[CONSTANT_10]] to %[[CONSTANT_11]] step %[[CONSTANT_12]] { +! CHECK: %[[COORDINATE_OF_0:.*]] = fir.coordinate_of %[[DECLARE_0]]#0, %[[VAL_3]], %[[VAL_2]], %[[VAL_1]] : (!fir.ref>, index, index, index) -> !fir.ref +! CHECK: fir.store %[[CONSTANT_0]] to %[[COORDINATE_OF_0]] : !fir.ref +! CHECK: } +! CHECK: } +! CHECK: } +! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref> + +! CHECK-LABEL: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 100 : index +! CHECK: %[[CONSTANT_1:.*]] = arith.constant 10 : index +! CHECK: %[[CONSTANT_2:.*]] = arith.constant 2 : index +! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_0]], %[[CONSTANT_1]], %[[CONSTANT_2]] : (index, index, index) -> !fir.shape<3> +! CHECK: %[[CONSTANT_3:.*]] = arith.constant 100 : index +! CHECK: %[[CONSTANT_4:.*]] = arith.constant 10 : index +! CHECK: %[[CONSTANT_5:.*]] = arith.constant 2 : index +! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[CONSTANT_3]], %[[CONSTANT_4]], %[[CONSTANT_5]] : (index, index, index) -> !fir.shape<3> +! CHECK: %[[CONSTANT_6:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_6]] to %[[CONSTANT_2]] step %[[CONSTANT_6]] unordered { +! CHECK: fir.do_loop %[[VAL_3:.*]] = %[[CONSTANT_6]] to %[[CONSTANT_1]] step %[[CONSTANT_6]] unordered { +! CHECK: fir.do_loop %[[VAL_4:.*]] = %[[CONSTANT_6]] to %[[CONSTANT_0]] step %[[CONSTANT_6]] unordered { +! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_1]] (%[[VAL_4]], %[[VAL_3]], %[[VAL_2]]) : (!fir.ref>, index, index, index) -> !fir.ref +! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_0]] : !fir.ref +! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_4]], %[[VAL_3]], %[[VAL_2]]) : (!fir.ref>, index, index, index) -> !fir.ref +! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_1]] : !fir.ref +! CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_1]], %[[LOAD_0]] : i32 +! CHECK: hlfir.assign %[[ADDI_0]] to %[[DESIGNATE_1]] : i32, !fir.ref +! CHECK: } +! CHECK: } +! CHECK: } +! CHECK: acc.yield %[[VAL_0]] : !fir.ref> +! CHECK: } + +! CHECK-LABEL: acc.reduction.recipe @reduction_add_ref_100x10xi32 : !fir.ref> reduction_operator init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : i32 +! CHECK: %[[CONSTANT_1:.*]] = arith.constant 100 : index +! CHECK: %[[CONSTANT_2:.*]] = arith.constant 10 : index +! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_1]], %[[CONSTANT_2]] : (index, index) -> !fir.shape<2> +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<100x10xi32> +! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]](%[[SHAPE_0]]) {uniq_name = "acc.reduction.init"} : (!fir.ref>, !fir.shape<2>) -> (!fir.ref>, !fir.ref>) +! CHECK: %[[CONSTANT_3:.*]] = arith.constant 0 : index +! CHECK: %[[CONSTANT_4:.*]] = arith.constant 9 : index +! CHECK: %[[CONSTANT_5:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_3]] to %[[CONSTANT_4]] step %[[CONSTANT_5]] { +! CHECK: %[[CONSTANT_6:.*]] = arith.constant 0 : index +! CHECK: %[[CONSTANT_7:.*]] = arith.constant 99 : index +! CHECK: %[[CONSTANT_8:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_6]] to %[[CONSTANT_7]] step %[[CONSTANT_8]] { +! CHECK: %[[COORDINATE_OF_0:.*]] = fir.coordinate_of %[[DECLARE_0]]#0, %[[VAL_2]], %[[VAL_1]] : (!fir.ref>, index, index) -> !fir.ref +! CHECK: fir.store %[[CONSTANT_0]] to %[[COORDINATE_OF_0]] : !fir.ref +! CHECK: } +! CHECK: } +! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref> + +! CHECK-LABEL: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 100 : index +! CHECK: %[[CONSTANT_1:.*]] = arith.constant 10 : index +! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_0]], %[[CONSTANT_1]] : (index, index) -> !fir.shape<2> +! CHECK: %[[CONSTANT_2:.*]] = arith.constant 100 : index +! CHECK: %[[CONSTANT_3:.*]] = arith.constant 10 : index +! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[CONSTANT_2]], %[[CONSTANT_3]] : (index, index) -> !fir.shape<2> +! CHECK: %[[CONSTANT_4:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_4]] to %[[CONSTANT_1]] step %[[CONSTANT_4]] unordered { +! CHECK: fir.do_loop %[[VAL_3:.*]] = %[[CONSTANT_4]] to %[[CONSTANT_0]] step %[[CONSTANT_4]] unordered { +! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_1]] (%[[VAL_3]], %[[VAL_2]]) : (!fir.ref>, index, index) -> !fir.ref +! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_0]] : !fir.ref +! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_3]], %[[VAL_2]]) : (!fir.ref>, index, index) -> !fir.ref +! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_1]] : !fir.ref +! CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_1]], %[[LOAD_0]] : i32 +! CHECK: hlfir.assign %[[ADDI_0]] to %[[DESIGNATE_1]] : i32, !fir.ref +! CHECK: } +! CHECK: } +! CHECK: acc.yield %[[VAL_0]] : !fir.ref> +! CHECK: } + +! CHECK-LABEL: acc.reduction.recipe @reduction_add_ref_100xi32 : !fir.ref> reduction_operator init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : i32 +! CHECK: %[[CONSTANT_1:.*]] = arith.constant 100 : index +! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_1]] : (index) -> !fir.shape<1> +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca !fir.array<100xi32> +! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]](%[[SHAPE_0]]) {uniq_name = "acc.reduction.init"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) +! CHECK: %[[CONSTANT_2:.*]] = arith.constant 0 : index +! CHECK: %[[CONSTANT_3:.*]] = arith.constant 99 : index +! CHECK: %[[CONSTANT_4:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_2]] to %[[CONSTANT_3]] step %[[CONSTANT_4]] { +! CHECK: %[[COORDINATE_OF_0:.*]] = fir.coordinate_of %[[DECLARE_0]]#0, %[[VAL_1]] : (!fir.ref>, index) -> !fir.ref +! CHECK: fir.store %[[CONSTANT_0]] to %[[COORDINATE_OF_0]] : !fir.ref +! CHECK: } +! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref> + +! CHECK-LABEL: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>, %[[VAL_1:.*]]: !fir.ref>): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 100 : index +! CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_0]] : (index) -> !fir.shape<1> +! CHECK: %[[CONSTANT_1:.*]] = arith.constant 100 : index +! CHECK: %[[SHAPE_1:.*]] = fir.shape %[[CONSTANT_1]] : (index) -> !fir.shape<1> +! CHECK: %[[CONSTANT_2:.*]] = arith.constant 1 : index +! CHECK: fir.do_loop %[[VAL_2:.*]] = %[[CONSTANT_2]] to %[[CONSTANT_0]] step %[[CONSTANT_2]] unordered { +! CHECK: %[[DESIGNATE_0:.*]] = hlfir.designate %[[VAL_1]] (%[[VAL_2]]) : (!fir.ref>, index) -> !fir.ref +! CHECK: %[[LOAD_0:.*]] = fir.load %[[DESIGNATE_0]] : !fir.ref +! CHECK: %[[DESIGNATE_1:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_2]]) : (!fir.ref>, index) -> !fir.ref +! CHECK: %[[LOAD_1:.*]] = fir.load %[[DESIGNATE_1]] : !fir.ref +! CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_1]], %[[LOAD_0]] : i32 +! CHECK: hlfir.assign %[[ADDI_0]] to %[[DESIGNATE_1]] : i32, !fir.ref +! CHECK: } +! CHECK: acc.yield %[[VAL_0]] : !fir.ref> +! CHECK: } + +! CHECK-LABEL: acc.private.recipe @privatization_ref_i32 : !fir.ref init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref): +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 +! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.private.init"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref +! CHECK: } + +! CHECK-LABEL: acc.reduction.recipe @reduction_add_ref_i32 : !fir.ref reduction_operator init { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref): +! CHECK: %[[CONSTANT_0:.*]] = arith.constant 0 : i32 +! CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 +! CHECK: %[[DECLARE_0:.*]]:2 = hlfir.declare %[[ALLOCA_0]] {uniq_name = "acc.reduction.init"} : (!fir.ref) -> (!fir.ref, !fir.ref) +! CHECK: fir.store %[[CONSTANT_0]] to %[[DECLARE_0]]#0 : !fir.ref +! CHECK: acc.yield %[[DECLARE_0]]#0 : !fir.ref + +! CHECK-LABEL: } combiner { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref, %[[VAL_1:.*]]: !fir.ref): +! CHECK: %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref +! CHECK: %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref +! CHECK: %[[ADDI_0:.*]] = arith.addi %[[LOAD_1]], %[[LOAD_0]] : i32 +! CHECK: hlfir.assign %[[ADDI_0]] to %[[VAL_0]] : i32, !fir.ref +! CHECK: acc.yield %[[VAL_0]] : !fir.ref +! CHECK: } subroutine acc_reduction_add_int(a, b) integer :: a(100)