diff --git a/flang/include/flang/Optimizer/Builder/HLFIRTools.h b/flang/include/flang/Optimizer/Builder/HLFIRTools.h index cd259b9dc6071..ac80873dc374f 100644 --- a/flang/include/flang/Optimizer/Builder/HLFIRTools.h +++ b/flang/include/flang/Optimizer/Builder/HLFIRTools.h @@ -301,11 +301,6 @@ mlir::Value genExtent(mlir::Location loc, fir::FirOpBuilder &builder, mlir::Value genLBound(mlir::Location loc, fir::FirOpBuilder &builder, hlfir::Entity entity, unsigned dim); -/// Compute the lower bounds of \p entity, which is an array of known rank. -llvm::SmallVector genLBounds(mlir::Location loc, - fir::FirOpBuilder &builder, - hlfir::Entity entity); - /// Generate a vector of extents with index type from a fir.shape /// of fir.shape_shift value. llvm::SmallVector getIndexExtents(mlir::Location loc, diff --git a/flang/lib/Optimizer/Builder/HLFIRTools.cpp b/flang/lib/Optimizer/Builder/HLFIRTools.cpp index 2a5e136c57c62..558ebcb876ddb 100644 --- a/flang/lib/Optimizer/Builder/HLFIRTools.cpp +++ b/flang/lib/Optimizer/Builder/HLFIRTools.cpp @@ -659,33 +659,6 @@ mlir::Value hlfir::genLBound(mlir::Location loc, fir::FirOpBuilder &builder, return dimInfo.getLowerBound(); } -llvm::SmallVector hlfir::genLBounds(mlir::Location loc, - fir::FirOpBuilder &builder, - hlfir::Entity entity) { - assert(!entity.isAssumedRank() && - "cannot compute all lower bounds for assumed rank"); - assert(!entity.isScalar() && "expected an array entity"); - int rank = entity.getRank(); - mlir::Type idxTy = builder.getIndexType(); - if (!entity.mayHaveNonDefaultLowerBounds()) - return {static_cast(rank), - builder.createIntegerConstant(loc, idxTy, 1)}; - - if (auto shape = tryRetrievingShapeOrShift(entity)) { - auto lbounds = getExplicitLboundsFromShape(shape); - if (!lbounds.empty()) - return lbounds; - } - - if (entity.isMutableBox()) - entity = hlfir::derefPointersAndAllocatables(loc, builder, entity); - - llvm::SmallVector lbounds; - fir::factory::genDimInfoFromBox(builder, loc, entity, &lbounds, - /*extents=*/nullptr, /*strides=*/nullptr); - return lbounds; -} - void hlfir::genLengthParameters(mlir::Location loc, fir::FirOpBuilder &builder, Entity entity, llvm::SmallVectorImpl &result) { diff --git a/flang/lib/Optimizer/HLFIR/Transforms/OptimizedBufferization.cpp b/flang/lib/Optimizer/HLFIR/Transforms/OptimizedBufferization.cpp index 79aabd2981e1a..c489450384a35 100644 --- a/flang/lib/Optimizer/HLFIR/Transforms/OptimizedBufferization.cpp +++ b/flang/lib/Optimizer/HLFIR/Transforms/OptimizedBufferization.cpp @@ -772,6 +772,458 @@ llvm::LogicalResult BroadcastAssignBufferization::matchAndRewrite( return mlir::success(); } +using GenBodyFn = + std::function &)>; +static mlir::Value generateReductionLoop(fir::FirOpBuilder &builder, + mlir::Location loc, mlir::Value init, + mlir::Value shape, GenBodyFn genBody) { + auto extents = hlfir::getIndexExtents(loc, builder, shape); + mlir::Value reduction = init; + mlir::IndexType idxTy = builder.getIndexType(); + mlir::Value oneIdx = builder.createIntegerConstant(loc, idxTy, 1); + + // Create a reduction loop nest. We use one-based indices so that they can be + // passed to the elemental, and reverse the order so that they can be + // generated in column-major order for better performance. + llvm::SmallVector indices(extents.size(), mlir::Value{}); + for (unsigned i = 0; i < extents.size(); ++i) { + auto loop = builder.create( + loc, oneIdx, extents[extents.size() - i - 1], oneIdx, false, + /*finalCountValue=*/false, reduction); + reduction = loop.getRegionIterArgs()[0]; + indices[extents.size() - i - 1] = loop.getInductionVar(); + // Set insertion point to the loop body so that the next loop + // is inserted inside the current one. + builder.setInsertionPointToStart(loop.getBody()); + } + + // Generate the body + reduction = genBody(builder, loc, reduction, indices); + + // Unwind the loop nest. + for (unsigned i = 0; i < extents.size(); ++i) { + auto result = builder.create(loc, reduction); + auto loop = mlir::cast(result->getParentOp()); + reduction = loop.getResult(0); + // Set insertion point after the loop operation that we have + // just processed. + builder.setInsertionPointAfter(loop.getOperation()); + } + + return reduction; +} + +auto makeMinMaxInitValGenerator(bool isMax) { + return [isMax](fir::FirOpBuilder builder, mlir::Location loc, + mlir::Type elementType) -> mlir::Value { + if (auto ty = mlir::dyn_cast(elementType)) { + const llvm::fltSemantics &sem = ty.getFloatSemantics(); + llvm::APFloat limit = llvm::APFloat::getInf(sem, /*Negative=*/isMax); + return builder.createRealConstant(loc, elementType, limit); + } + unsigned bits = elementType.getIntOrFloatBitWidth(); + int64_t limitInt = + isMax ? llvm::APInt::getSignedMinValue(bits).getSExtValue() + : llvm::APInt::getSignedMaxValue(bits).getSExtValue(); + return builder.createIntegerConstant(loc, elementType, limitInt); + }; +} + +mlir::Value generateMinMaxComparison(fir::FirOpBuilder builder, + mlir::Location loc, mlir::Value elem, + mlir::Value reduction, bool isMax) { + if (mlir::isa(reduction.getType())) { + // For FP reductions we want the first smallest value to be used, that + // is not NaN. A OGL/OLT condition will usually work for this unless all + // the values are Nan or Inf. This follows the same logic as + // NumericCompare for Minloc/Maxlox in extrema.cpp. + mlir::Value cmp = builder.create( + loc, + isMax ? mlir::arith::CmpFPredicate::OGT + : mlir::arith::CmpFPredicate::OLT, + elem, reduction); + mlir::Value cmpNan = builder.create( + loc, mlir::arith::CmpFPredicate::UNE, reduction, reduction); + mlir::Value cmpNan2 = builder.create( + loc, mlir::arith::CmpFPredicate::OEQ, elem, elem); + cmpNan = builder.create(loc, cmpNan, cmpNan2); + return builder.create(loc, cmp, cmpNan); + } else if (mlir::isa(reduction.getType())) { + return builder.create( + loc, + isMax ? mlir::arith::CmpIPredicate::sgt + : mlir::arith::CmpIPredicate::slt, + elem, reduction); + } + llvm_unreachable("unsupported type"); +} + +/// Given a reduction operation with an elemental/designate source, attempt to +/// generate a do-loop to perform the operation inline. +/// %e = hlfir.elemental %shape unordered +/// %r = hlfir.count %e +/// => +/// %r = for.do_loop %arg = 1 to bound(%shape) step 1 iter_args(%arg2 = init) +/// %i = +/// %c = %i +/// fir.result %c +template +class ReductionConversion : public mlir::OpRewritePattern { +public: + using mlir::OpRewritePattern::OpRewritePattern; + + llvm::LogicalResult + matchAndRewrite(Op op, mlir::PatternRewriter &rewriter) const override { + mlir::Location loc = op.getLoc(); + // Select source and validate its arguments. + mlir::Value source; + bool valid = false; + if constexpr (std::is_same_v || + std::is_same_v || + std::is_same_v) { + source = op.getMask(); + valid = !op.getDim(); + } else if constexpr (std::is_same_v || + std::is_same_v) { + source = op.getArray(); + valid = !op.getDim() && !op.getMask(); + } else if constexpr (std::is_same_v || + std::is_same_v) { + source = op.getArray(); + valid = !op.getDim() && !op.getMask() && !op.getBack(); + } + if (!valid) + return rewriter.notifyMatchFailure( + op, "Currently does not accept optional arguments"); + + hlfir::ElementalOp elemental; + hlfir::DesignateOp designate; + mlir::Value shape; + if ((elemental = source.template getDefiningOp())) { + shape = elemental.getOperand(0); + } else if ((designate = + source.template getDefiningOp())) { + shape = designate.getShape(); + } else { + return rewriter.notifyMatchFailure(op, "Did not find valid argument"); + } + + auto inlineSource = + [elemental, + &designate](fir::FirOpBuilder builder, mlir::Location loc, + const llvm::SmallVectorImpl &oneBasedIndices) + -> mlir::Value { + if (elemental) { + // Inline the elemental and get the value from it. + auto yield = + inlineElementalOp(loc, builder, elemental, oneBasedIndices); + auto tmp = yield.getElementValue(); + yield->erase(); + return tmp; + } + if (designate) { + // Create a designator over the array designator, then load the + // reference. + mlir::Value elementAddr = hlfir::getElementAt( + loc, builder, hlfir::Entity{designate.getResult()}, + oneBasedIndices); + return builder.create(loc, elementAddr); + } + llvm_unreachable("unsupported type"); + }; + + fir::FirOpBuilder builder{rewriter, op.getOperation()}; + + mlir::Value init; + GenBodyFn genBodyFn; + if constexpr (std::is_same_v) { + init = builder.createIntegerConstant(loc, builder.getI1Type(), 0); + genBodyFn = [inlineSource]( + fir::FirOpBuilder builder, mlir::Location loc, + mlir::Value reduction, + const llvm::SmallVectorImpl &oneBasedIndices) + -> mlir::Value { + // Conditionally set the reduction variable. + mlir::Value cond = builder.create( + loc, builder.getI1Type(), + inlineSource(builder, loc, oneBasedIndices)); + return builder.create(loc, reduction, cond); + }; + } else if constexpr (std::is_same_v) { + init = builder.createIntegerConstant(loc, builder.getI1Type(), 1); + genBodyFn = [inlineSource]( + fir::FirOpBuilder builder, mlir::Location loc, + mlir::Value reduction, + const llvm::SmallVectorImpl &oneBasedIndices) + -> mlir::Value { + // Conditionally set the reduction variable. + mlir::Value cond = builder.create( + loc, builder.getI1Type(), + inlineSource(builder, loc, oneBasedIndices)); + return builder.create(loc, reduction, cond); + }; + } else if constexpr (std::is_same_v) { + init = builder.createIntegerConstant(loc, op.getType(), 0); + genBodyFn = [inlineSource]( + fir::FirOpBuilder builder, mlir::Location loc, + mlir::Value reduction, + const llvm::SmallVectorImpl &oneBasedIndices) + -> mlir::Value { + // Conditionally add one to the current value + mlir::Value cond = builder.create( + loc, builder.getI1Type(), + inlineSource(builder, loc, oneBasedIndices)); + mlir::Value one = + builder.createIntegerConstant(loc, reduction.getType(), 1); + mlir::Value add1 = + builder.create(loc, reduction, one); + return builder.create(loc, cond, add1, + reduction); + }; + } else if constexpr (std::is_same_v || + std::is_same_v) { + // TODO: implement minloc/maxloc conversion. + return rewriter.notifyMatchFailure( + op, "Currently minloc/maxloc is not handled"); + } else if constexpr (std::is_same_v || + std::is_same_v) { + mlir::Type ty = op.getType(); + if (!(mlir::isa(ty) || + mlir::isa(ty))) { + return rewriter.notifyMatchFailure( + op, "Type is not supported for Maxval or Minval yet"); + } + + bool isMax = std::is_same_v; + init = makeMinMaxInitValGenerator(isMax)(builder, loc, ty); + genBodyFn = [inlineSource, isMax]( + fir::FirOpBuilder builder, mlir::Location loc, + mlir::Value reduction, + const llvm::SmallVectorImpl &oneBasedIndices) + -> mlir::Value { + mlir::Value val = inlineSource(builder, loc, oneBasedIndices); + mlir::Value cmp = + generateMinMaxComparison(builder, loc, val, reduction, isMax); + return builder.create(loc, cmp, val, reduction); + }; + } else { + llvm_unreachable("unsupported type"); + } + + mlir::Value res = + generateReductionLoop(builder, loc, init, shape, genBodyFn); + if (res.getType() != op.getType()) + res = builder.create(loc, op.getType(), res); + + // Check if the op was the only user of the source (apart from a destroy), + // and remove it if so. + mlir::Operation *sourceOp = source.getDefiningOp(); + mlir::Operation::user_range srcUsers = sourceOp->getUsers(); + hlfir::DestroyOp srcDestroy; + if (std::distance(srcUsers.begin(), srcUsers.end()) == 2) { + srcDestroy = mlir::dyn_cast(*srcUsers.begin()); + if (!srcDestroy) + srcDestroy = mlir::dyn_cast(*++srcUsers.begin()); + } + + rewriter.replaceOp(op, res); + if (srcDestroy) { + rewriter.eraseOp(srcDestroy); + rewriter.eraseOp(sourceOp); + } + return mlir::success(); + } +}; + +// Look for minloc(mask=elemental) and generate the minloc loop with +// inlined elemental. +// %e = hlfir.elemental %shape ({ ... }) +// %m = hlfir.minloc %array mask %e +template +class ReductionMaskConversion : public mlir::OpRewritePattern { +public: + using mlir::OpRewritePattern::OpRewritePattern; + + llvm::LogicalResult + matchAndRewrite(Op mloc, mlir::PatternRewriter &rewriter) const override { + if (!mloc.getMask() || mloc.getDim() || mloc.getBack()) + return rewriter.notifyMatchFailure(mloc, + "Did not find valid minloc/maxloc"); + + bool isMax = std::is_same_v; + + auto elemental = + mloc.getMask().template getDefiningOp(); + if (!elemental || hlfir::elementalOpMustProduceTemp(elemental)) + return rewriter.notifyMatchFailure(mloc, "Did not find elemental"); + + mlir::Value array = mloc.getArray(); + + unsigned rank = mlir::cast(mloc.getType()).getShape()[0]; + mlir::Type arrayType = array.getType(); + if (!mlir::isa(arrayType)) + return rewriter.notifyMatchFailure( + mloc, "Currently requires a boxed type input"); + mlir::Type elementType = hlfir::getFortranElementType(arrayType); + if (!fir::isa_trivial(elementType)) + return rewriter.notifyMatchFailure( + mloc, "Character arrays are currently not handled"); + + mlir::Location loc = mloc.getLoc(); + fir::FirOpBuilder builder{rewriter, mloc.getOperation()}; + mlir::Value resultArr = builder.createTemporary( + loc, fir::SequenceType::get( + rank, hlfir::getFortranElementType(mloc.getType()))); + + auto init = makeMinMaxInitValGenerator(isMax); + + auto genBodyOp = + [&rank, &resultArr, &elemental, isMax]( + fir::FirOpBuilder builder, mlir::Location loc, + mlir::Type elementType, mlir::Value array, mlir::Value flagRef, + mlir::Value reduction, + const llvm::SmallVectorImpl &indices) -> mlir::Value { + // We are in the innermost loop: generate the elemental inline + mlir::Value oneIdx = + builder.createIntegerConstant(loc, builder.getIndexType(), 1); + llvm::SmallVector oneBasedIndices; + llvm::transform( + indices, std::back_inserter(oneBasedIndices), [&](mlir::Value V) { + return builder.create(loc, V, oneIdx); + }); + hlfir::YieldElementOp yield = + hlfir::inlineElementalOp(loc, builder, elemental, oneBasedIndices); + mlir::Value maskElem = yield.getElementValue(); + yield->erase(); + + mlir::Type ifCompatType = builder.getI1Type(); + mlir::Value ifCompatElem = + builder.create(loc, ifCompatType, maskElem); + + llvm::SmallVector resultsTy = {elementType, elementType}; + fir::IfOp maskIfOp = + builder.create(loc, elementType, ifCompatElem, + /*withElseRegion=*/true); + builder.setInsertionPointToStart(&maskIfOp.getThenRegion().front()); + + // Set flag that mask was true at some point + mlir::Value flagSet = builder.createIntegerConstant( + loc, mlir::cast(flagRef.getType()).getEleTy(), 1); + mlir::Value isFirst = builder.create(loc, flagRef); + mlir::Value addr = hlfir::getElementAt(loc, builder, hlfir::Entity{array}, + oneBasedIndices); + mlir::Value elem = builder.create(loc, addr); + + // Compare with the max reduction value + mlir::Value cmp = + generateMinMaxComparison(builder, loc, elem, reduction, isMax); + + // The condition used for the loop is isFirst || . + isFirst = builder.create(loc, cmp.getType(), isFirst); + isFirst = builder.create( + loc, isFirst, builder.createIntegerConstant(loc, cmp.getType(), 1)); + cmp = builder.create(loc, cmp, isFirst); + + // Set the new coordinate to the result + fir::IfOp ifOp = builder.create(loc, elementType, cmp, + /*withElseRegion*/ true); + + builder.setInsertionPointToStart(&ifOp.getThenRegion().front()); + builder.create(loc, flagSet, flagRef); + mlir::Type resultElemTy = + hlfir::getFortranElementType(resultArr.getType()); + mlir::Type returnRefTy = builder.getRefType(resultElemTy); + mlir::IndexType idxTy = builder.getIndexType(); + + for (unsigned int i = 0; i < rank; ++i) { + mlir::Value index = builder.createIntegerConstant(loc, idxTy, i + 1); + mlir::Value resultElemAddr = builder.create( + loc, returnRefTy, resultArr, index); + mlir::Value fortranIndex = builder.create( + loc, resultElemTy, oneBasedIndices[i]); + builder.create(loc, fortranIndex, resultElemAddr); + } + builder.create(loc, elem); + builder.setInsertionPointToStart(&ifOp.getElseRegion().front()); + builder.create(loc, reduction); + builder.setInsertionPointAfter(ifOp); + + // Close the mask if + builder.create(loc, ifOp.getResult(0)); + builder.setInsertionPointToStart(&maskIfOp.getElseRegion().front()); + builder.create(loc, reduction); + builder.setInsertionPointAfter(maskIfOp); + + return maskIfOp.getResult(0); + }; + auto getAddrFn = [](fir::FirOpBuilder builder, mlir::Location loc, + const mlir::Type &resultElemType, mlir::Value resultArr, + mlir::Value index) { + mlir::Type resultRefTy = builder.getRefType(resultElemType); + mlir::Value oneIdx = + builder.createIntegerConstant(loc, builder.getIndexType(), 1); + index = builder.create(loc, index, oneIdx); + return builder.create(loc, resultRefTy, resultArr, + index); + }; + + // Initialize the result + mlir::Type resultElemTy = hlfir::getFortranElementType(resultArr.getType()); + mlir::Type resultRefTy = builder.getRefType(resultElemTy); + mlir::Value returnValue = + builder.createIntegerConstant(loc, resultElemTy, 0); + for (unsigned int i = 0; i < rank; ++i) { + mlir::Value index = + builder.createIntegerConstant(loc, builder.getIndexType(), i + 1); + mlir::Value resultElemAddr = builder.create( + loc, resultRefTy, resultArr, index); + builder.create(loc, returnValue, resultElemAddr); + } + + fir::genMinMaxlocReductionLoop(builder, array, init, genBodyOp, getAddrFn, + rank, elementType, loc, builder.getI1Type(), + resultArr, false); + + mlir::Value asExpr = builder.create( + loc, resultArr, builder.createBool(loc, false)); + + // Check all the users - the destroy is no longer required, and any assign + // can use resultArr directly so that InlineHLFIRAssign pass + // can optimize the results. Other operations are replaced with an AsExpr + // for the temporary resultArr. + llvm::SmallVector destroys; + llvm::SmallVector assigns; + for (auto user : mloc->getUsers()) { + if (auto destroy = mlir::dyn_cast(user)) + destroys.push_back(destroy); + else if (auto assign = mlir::dyn_cast(user)) + assigns.push_back(assign); + } + + // Check if the minloc/maxloc was the only user of the elemental (apart from + // a destroy), and remove it if so. + mlir::Operation::user_range elemUsers = elemental->getUsers(); + hlfir::DestroyOp elemDestroy; + if (std::distance(elemUsers.begin(), elemUsers.end()) == 2) { + elemDestroy = mlir::dyn_cast(*elemUsers.begin()); + if (!elemDestroy) + elemDestroy = mlir::dyn_cast(*++elemUsers.begin()); + } + + for (auto d : destroys) + rewriter.eraseOp(d); + for (auto a : assigns) + a.setOperand(0, resultArr); + rewriter.replaceOp(mloc, asExpr); + if (elemDestroy) { + rewriter.eraseOp(elemDestroy); + rewriter.eraseOp(elemental); + } + return mlir::success(); + } +}; + class EvaluateIntoMemoryAssignBufferization : public mlir::OpRewritePattern { @@ -888,6 +1340,19 @@ class OptimizedBufferizationPass patterns.insert(context); patterns.insert(context); patterns.insert(context); + patterns.insert>(context); + patterns.insert>(context); + patterns.insert>(context); + // TODO: implement basic minloc/maxloc conversion. + // patterns.insert>(context); + // patterns.insert>(context); + patterns.insert>(context); + patterns.insert>(context); + patterns.insert>(context); + patterns.insert>(context); + // TODO: implement masked minval/maxval conversion. + // patterns.insert>(context); + // patterns.insert>(context); if (mlir::failed(mlir::applyPatternsGreedily( getOperation(), std::move(patterns), config))) { diff --git a/flang/lib/Optimizer/HLFIR/Transforms/SimplifyHLFIRIntrinsics.cpp b/flang/lib/Optimizer/HLFIR/Transforms/SimplifyHLFIRIntrinsics.cpp index d660cf3845f9a..bac10121a881b 100644 --- a/flang/lib/Optimizer/HLFIR/Transforms/SimplifyHLFIRIntrinsics.cpp +++ b/flang/lib/Optimizer/HLFIR/Transforms/SimplifyHLFIRIntrinsics.cpp @@ -173,882 +173,245 @@ class TransposeAsElementalConversion } }; -/// Base class for converting reduction-like operations into -/// a reduction loop[-nest] optionally wrapped into hlfir.elemental. -/// It is used to handle operations produced for ALL, ANY, COUNT, -/// MAXLOC, MAXVAL, MINLOC, MINVAL, SUM intrinsics. -/// -/// All of these operations take an input array, and optional -/// dim, mask arguments. ALL, ANY, COUNT do not have mask argument. -class ReductionAsElementalConverter { +// Expand the SUM(DIM=CONSTANT) operation into . +class SumAsElementalConversion : public mlir::OpRewritePattern { public: - ReductionAsElementalConverter(mlir::Operation *op, - mlir::PatternRewriter &rewriter) - : op{op}, rewriter{rewriter}, loc{op->getLoc()}, builder{rewriter, op} { - assert(op->getNumResults() == 1); - } - virtual ~ReductionAsElementalConverter() {} - - /// Do the actual conversion or return mlir::failure(), - /// if conversion is not possible. - mlir::LogicalResult convert(); + using mlir::OpRewritePattern::OpRewritePattern; -private: - // Return fir.shape specifying the shape of the result - // of a reduction with DIM=dimVal. The second return value - // is the extent of the DIM dimension. - std::tuple - genResultShapeForPartialReduction(hlfir::Entity array, int64_t dimVal); - - /// \p mask is a scalar or array logical mask. - /// If \p isPresentPred is not nullptr, it is a dynamic predicate value - /// identifying whether the mask's variable is present. - /// \p indices is a range of one-based indices to access \p mask - /// when it is an array. - /// - /// The method returns the scalar mask value to guard the access - /// to a single element of the input array. - mlir::Value genMaskValue(mlir::Value mask, mlir::Value isPresentPred, - mlir::ValueRange indices); - -protected: - /// Return the input array. - virtual mlir::Value getSource() const = 0; - - /// Return DIM or nullptr, if it is not present. - virtual mlir::Value getDim() const = 0; - - /// Return MASK or nullptr, if it is not present. - virtual mlir::Value getMask() const { return nullptr; } - - /// Return FastMathFlags attached to the operation - /// or arith::FastMathFlags::none, if the operation - /// does not support FastMathFlags (e.g. ALL, ANY, COUNT). - virtual mlir::arith::FastMathFlags getFastMath() const { - return mlir::arith::FastMathFlags::none; - } - - /// Generates initial values for the reduction values used - /// by the reduction loop. In general, there is a single - /// loop-carried reduction value (e.g. for SUM), but, for example, - /// MAXLOC/MINLOC implementation uses multiple reductions. - virtual llvm::SmallVector genReductionInitValues() = 0; - - /// Perform reduction(s) update given a single input array's element - /// identified by \p array and \p oneBasedIndices coordinates. - /// \p currentValue specifies the current value(s) of the reduction(s) - /// inside the reduction loop body. - virtual llvm::SmallVector - reduceOneElement(const llvm::SmallVectorImpl ¤tValue, - hlfir::Entity array, mlir::ValueRange oneBasedIndices) = 0; - - /// Given reduction value(s) in \p reductionResults produced - /// by the reduction loop, apply any required updates and return - /// new reduction value(s) to be used after the reduction loop - /// (e.g. as the result yield of the wrapping hlfir.elemental). - /// NOTE: if the reduction loop is wrapped in hlfir.elemental, - /// the insertion point of any generated code is inside hlfir.elemental. - virtual hlfir::Entity - genFinalResult(const llvm::SmallVectorImpl &reductionResults) { - assert(reductionResults.size() == 1 && - "default implementation of genFinalResult expect a single reduction " - "value"); - return hlfir::Entity{reductionResults[0]}; - } - - /// Return mlir::success(), if the operation can be converted. - /// The default implementation always returns mlir::success(). - /// The derived type may override the default implementation - /// with its own definition. - virtual mlir::LogicalResult isConvertible() const { return mlir::success(); } - - // Default implementation of isTotalReduction() just checks - // if the result of the operation is a scalar. - // True result indicates that the reduction has to be done - // across all elements, false result indicates that - // the result is an array expression produced by an hlfir.elemental - // operation with a single reduction loop across the DIM dimension. - // - // MAXLOC/MINLOC must override this. - virtual bool isTotalReduction() const { return getResultRank() == 0; } - - // Return true, if the reduction loop[-nest] may be unordered. - // In general, FP reductions may only be unordered when - // FastMathFlags::reassoc transformations are allowed. - // - // Some dervied types may need to override this. - virtual bool isUnordered() const { - mlir::Type elemType = getSourceElementType(); - if (mlir::isa( - elemType)) - return true; - return static_cast(getFastMath() & - mlir::arith::FastMathFlags::reassoc); - } - - /// Return 0, if DIM is not present or its values does not matter - /// (for example, a reduction of 1D array does not care about - /// the DIM value, assuming that it is a valid program). - /// Return mlir::failure(), if DIM is a constant known - /// to be invalid for the given array. - /// Otherwise, return DIM constant value. - mlir::FailureOr getConstDim() const { + llvm::LogicalResult + matchAndRewrite(hlfir::SumOp sum, + mlir::PatternRewriter &rewriter) const override { + hlfir::Entity array = hlfir::Entity{sum.getArray()}; + bool isTotalReduction = hlfir::Entity{sum}.getRank() == 0; + mlir::Value dim = sum.getDim(); int64_t dimVal = 0; - if (!isTotalReduction()) { + if (!isTotalReduction) { // In case of partial reduction we should ignore the operations // with invalid DIM values. They may appear in dead code // after constant propagation. - auto constDim = fir::getIntIfConstant(getDim()); + auto constDim = fir::getIntIfConstant(dim); if (!constDim) - return rewriter.notifyMatchFailure(op, "Nonconstant DIM"); + return rewriter.notifyMatchFailure(sum, "Nonconstant DIM for SUM"); dimVal = *constDim; - if ((dimVal <= 0 || dimVal > getSourceRank())) - return rewriter.notifyMatchFailure(op, - "Invalid DIM for partial reduction"); + if ((dimVal <= 0 || dimVal > array.getRank())) + return rewriter.notifyMatchFailure( + sum, "Invalid DIM for partial SUM reduction"); } - return dimVal; - } - - /// Return hlfir::Entity of the result. - hlfir::Entity getResultEntity() const { - return hlfir::Entity{op->getResult(0)}; - } - - /// Return type of the result (e.g. !hlfir.expr). - mlir::Type getResultType() const { return getResultEntity().getType(); } - /// Return the element type of the result (e.g. i32). - mlir::Type getResultElementType() const { - return hlfir::getFortranElementType(getResultType()); - } - - /// Return rank of the result. - unsigned getResultRank() const { return getResultEntity().getRank(); } - - /// Return the element type of the source. - mlir::Type getSourceElementType() const { - return hlfir::getFortranElementType(getSource().getType()); - } - - /// Return rank of the input array. - unsigned getSourceRank() const { - return hlfir::Entity{getSource()}.getRank(); - } - - /// The reduction operation. - mlir::Operation *op; - - mlir::PatternRewriter &rewriter; - mlir::Location loc; - fir::FirOpBuilder builder; -}; - -/// Generate initialization value for MIN or MAX reduction -/// of the given \p type. -template -static mlir::Value genMinMaxInitValue(mlir::Location loc, - fir::FirOpBuilder &builder, - mlir::Type type) { - if (auto ty = mlir::dyn_cast(type)) { - const llvm::fltSemantics &sem = ty.getFloatSemantics(); - // We must not use +/-INF here. If the reduction input is empty, - // the result of reduction must be +/-LARGEST. - llvm::APFloat limit = llvm::APFloat::getLargest(sem, /*Negative=*/IS_MAX); - return builder.createRealConstant(loc, type, limit); - } - unsigned bits = type.getIntOrFloatBitWidth(); - int64_t limitInt = IS_MAX - ? llvm::APInt::getSignedMinValue(bits).getSExtValue() - : llvm::APInt::getSignedMaxValue(bits).getSExtValue(); - return builder.createIntegerConstant(loc, type, limitInt); -} - -/// Generate a comparison of an array element value \p elem -/// and the current reduction value \p reduction for MIN/MAX reduction. -template -static mlir::Value -genMinMaxComparison(mlir::Location loc, fir::FirOpBuilder &builder, - mlir::Value elem, mlir::Value reduction) { - if (mlir::isa(reduction.getType())) { - // For FP reductions we want the first smallest value to be used, that - // is not NaN. A OGL/OLT condition will usually work for this unless all - // the values are Nan or Inf. This follows the same logic as - // NumericCompare for Minloc/Maxloc in extrema.cpp. - mlir::Value cmp = builder.create( - loc, - IS_MAX ? mlir::arith::CmpFPredicate::OGT - : mlir::arith::CmpFPredicate::OLT, - elem, reduction); - mlir::Value cmpNan = builder.create( - loc, mlir::arith::CmpFPredicate::UNE, reduction, reduction); - mlir::Value cmpNan2 = builder.create( - loc, mlir::arith::CmpFPredicate::OEQ, elem, elem); - cmpNan = builder.create(loc, cmpNan, cmpNan2); - return builder.create(loc, cmp, cmpNan); - } else if (mlir::isa(reduction.getType())) { - return builder.create( - loc, - IS_MAX ? mlir::arith::CmpIPredicate::sgt - : mlir::arith::CmpIPredicate::slt, - elem, reduction); - } - llvm_unreachable("unsupported type"); -} - -/// Implementation of ReductionAsElementalConverter interface -/// for MAXLOC/MINLOC. -template -class MinMaxlocAsElementalConverter : public ReductionAsElementalConverter { - static_assert(std::is_same_v || - std::is_same_v); - static constexpr unsigned maxRank = Fortran::common::maxRank; - // We have the following reduction values in the reduction loop: - // * N integer coordinates, where N is: - // - RANK(ARRAY) for total reductions. - // - 1 for partial reductions. - // * 1 reduction value holding the current MIN/MAX. - // * 1 boolean indicating whether it is the first time - // the mask is true. - static constexpr unsigned maxNumReductions = Fortran::common::maxRank + 2; - static constexpr bool isMax = std::is_same_v; - using Base = ReductionAsElementalConverter; - -public: - MinMaxlocAsElementalConverter(T op, mlir::PatternRewriter &rewriter) - : Base{op.getOperation(), rewriter} {} - -private: - virtual mlir::Value getSource() const final { return getOp().getArray(); } - virtual mlir::Value getDim() const final { return getOp().getDim(); } - virtual mlir::Value getMask() const final { return getOp().getMask(); } - virtual mlir::arith::FastMathFlags getFastMath() const final { - return getOp().getFastmath(); - } - - virtual mlir::LogicalResult isConvertible() const final { - if (getOp().getBack()) - return rewriter.notifyMatchFailure( - getOp(), "BACK is not supported for MINLOC/MAXLOC inlining"); - if (mlir::isa(getSourceElementType())) - return rewriter.notifyMatchFailure( - getOp(), - "CHARACTER type is not supported for MINLOC/MAXLOC inlining"); - return mlir::success(); - } + mlir::Location loc = sum.getLoc(); + fir::FirOpBuilder builder{rewriter, sum.getOperation()}; + mlir::Type elementType = hlfir::getFortranElementType(sum.getType()); + mlir::Value mask = sum.getMask(); - // If the result is scalar, then DIM does not matter, - // and this is a total reduction. - // If DIM is not present, this is a total reduction. - virtual bool isTotalReduction() const final { - return getResultRank() == 0 || !getDim(); - } + mlir::Value resultShape, dimExtent; + llvm::SmallVector arrayExtents; + if (isTotalReduction) + arrayExtents = hlfir::genExtentsVector(loc, builder, array); + else + std::tie(resultShape, dimExtent) = + genResultShapeForPartialReduction(loc, builder, array, dimVal); + + // If the mask is present and is a scalar, then we'd better load its value + // outside of the reduction loop making the loop unswitching easier. + mlir::Value isPresentPred, maskValue; + if (mask) { + if (mlir::isa(mask.getType())) { + // MASK represented by a box might be dynamically optional, + // so we have to check for its presence before accessing it. + isPresentPred = + builder.create(loc, builder.getI1Type(), mask); + } - virtual llvm::SmallVector genReductionInitValues() final; - virtual llvm::SmallVector - reduceOneElement(const llvm::SmallVectorImpl ¤tValue, - hlfir::Entity array, mlir::ValueRange oneBasedIndices) final; - virtual hlfir::Entity genFinalResult( - const llvm::SmallVectorImpl &reductionResults) final; + if (hlfir::Entity{mask}.isScalar()) + maskValue = genMaskValue(loc, builder, mask, isPresentPred, {}); + } -private: - T getOp() const { return mlir::cast(op); } + auto genKernel = [&](mlir::Location loc, fir::FirOpBuilder &builder, + mlir::ValueRange inputIndices) -> hlfir::Entity { + // Loop over all indices in the DIM dimension, and reduce all values. + // If DIM is not present, do total reduction. + + // Initial value for the reduction. + mlir::Value reductionInitValue = + fir::factory::createZeroValue(builder, loc, elementType); + + // The reduction loop may be unordered if FastMathFlags::reassoc + // transformations are allowed. The integer reduction is always + // unordered. + bool isUnordered = mlir::isa(elementType) || + static_cast(sum.getFastmath() & + mlir::arith::FastMathFlags::reassoc); - unsigned getNumCoors() const { - return isTotalReduction() ? getSourceRank() : 1; - } + llvm::SmallVector extents; + if (isTotalReduction) + extents = arrayExtents; + else + extents.push_back( + builder.createConvert(loc, builder.getIndexType(), dimExtent)); - void - checkReductions(const llvm::SmallVectorImpl &reductions) const { - assert(reductions.size() == getNumCoors() + 2 && - "invalid number of reductions for MINLOC/MAXLOC"); - } + auto genBody = [&](mlir::Location loc, fir::FirOpBuilder &builder, + mlir::ValueRange oneBasedIndices, + mlir::ValueRange reductionArgs) + -> llvm::SmallVector { + // Generate the reduction loop-nest body. + // The initial reduction value in the innermost loop + // is passed via reductionArgs[0]. + llvm::SmallVector indices; + if (isTotalReduction) { + indices = oneBasedIndices; + } else { + indices = inputIndices; + indices.insert(indices.begin() + dimVal - 1, oneBasedIndices[0]); + } - mlir::Value - getCurrentMinMax(const llvm::SmallVectorImpl &reductions) const { - checkReductions(reductions); - return reductions[getNumCoors()]; - } + mlir::Value reductionValue = reductionArgs[0]; + fir::IfOp ifOp; + if (mask) { + // Make the reduction value update conditional on the value + // of the mask. + if (!maskValue) { + // If the mask is an array, use the elemental and the loop indices + // to address the proper mask element. + maskValue = + genMaskValue(loc, builder, mask, isPresentPred, indices); + } + mlir::Value isUnmasked = builder.create( + loc, builder.getI1Type(), maskValue); + ifOp = builder.create(loc, elementType, isUnmasked, + /*withElseRegion=*/true); + // In the 'else' block return the current reduction value. + builder.setInsertionPointToStart(&ifOp.getElseRegion().front()); + builder.create(loc, reductionValue); + + // In the 'then' block do the actual addition. + builder.setInsertionPointToStart(&ifOp.getThenRegion().front()); + } - mlir::Value - getIsFirst(const llvm::SmallVectorImpl &reductions) const { - checkReductions(reductions); - return reductions[getNumCoors() + 1]; - } -}; + hlfir::Entity element = + hlfir::getElementAt(loc, builder, array, indices); + hlfir::Entity elementValue = + hlfir::loadTrivialScalar(loc, builder, element); + // NOTE: we can use "Kahan summation" same way as the runtime + // (e.g. when fast-math is not allowed), but let's start with + // the simple version. + reductionValue = + genScalarAdd(loc, builder, reductionValue, elementValue); + + if (ifOp) { + builder.create(loc, reductionValue); + builder.setInsertionPointAfter(ifOp); + reductionValue = ifOp.getResult(0); + } -template -llvm::SmallVector -MinMaxlocAsElementalConverter::genReductionInitValues() { - // Initial value for the coordinate(s) is zero. - mlir::Value zeroCoor = - fir::factory::createZeroValue(builder, loc, getResultElementType()); - llvm::SmallVector result(getNumCoors(), - zeroCoor); - - // Initial value for the MIN/MAX value. - mlir::Value minMaxInit = - genMinMaxInitValue(loc, builder, getSourceElementType()); - result.push_back(minMaxInit); - - // Initial value for isFirst predicate. It is switched to false, - // when the reduction update dynamically happens inside the reduction - // loop. - mlir::Value trueVal = builder.createBool(loc, true); - result.push_back(trueVal); - - return result; -} - -template -llvm::SmallVector -MinMaxlocAsElementalConverter::reduceOneElement( - const llvm::SmallVectorImpl ¤tValue, hlfir::Entity array, - mlir::ValueRange oneBasedIndices) { - checkReductions(currentValue); - hlfir::Entity elementValue = - hlfir::loadElementAt(loc, builder, array, oneBasedIndices); - mlir::Value cmp = genMinMaxComparison(loc, builder, elementValue, - getCurrentMinMax(currentValue)); - // If isFirst is true, then do the reduction update regardless - // of the FP comparison. - cmp = builder.create(loc, cmp, getIsFirst(currentValue)); - - llvm::SmallVector newIndices; - int64_t dim = 1; - if (!isTotalReduction()) { - auto dimVal = getConstDim(); - assert(mlir::succeeded(dimVal) && - "partial MINLOC/MAXLOC reduction with invalid DIM"); - dim = *dimVal; - assert(getNumCoors() == 1 && - "partial MAXLOC/MINLOC reduction must compute one coordinate"); - } + return {reductionValue}; + }; - for (unsigned coorIdx = 0; coorIdx < getNumCoors(); ++coorIdx) { - mlir::Value currentCoor = currentValue[coorIdx]; - mlir::Value newCoor = builder.createConvert( - loc, currentCoor.getType(), oneBasedIndices[coorIdx + dim - 1]); - mlir::Value update = - builder.create(loc, cmp, newCoor, currentCoor); - newIndices.push_back(update); - } + llvm::SmallVector reductionFinalValues = + hlfir::genLoopNestWithReductions(loc, builder, extents, + {reductionInitValue}, genBody, + isUnordered); + return hlfir::Entity{reductionFinalValues[0]}; + }; - mlir::Value newMinMax = builder.create( - loc, cmp, elementValue, getCurrentMinMax(currentValue)); - newIndices.push_back(newMinMax); - - mlir::Value newIsFirst = builder.createBool(loc, false); - newIndices.push_back(newIsFirst); - - assert(currentValue.size() == newIndices.size() && - "invalid number of updated reductions"); - - return newIndices; -} - -template -hlfir::Entity MinMaxlocAsElementalConverter::genFinalResult( - const llvm::SmallVectorImpl &reductionResults) { - // Identification of the final result of MINLOC/MAXLOC: - // * If DIM is absent, the result is rank-one array. - // * If DIM is present: - // - The result is scalar for rank-one input. - // - The result is an array of rank RANK(ARRAY)-1. - checkReductions(reductionResults); - - // We need to adjust the one-based indices to real array indices. - // The adjustment must only be done, if there was an actual update - // of the coordinates in the reduction loop. For this check we only - // need to compare if any of the reduction results is not zero. - mlir::Value zero = fir::factory::createZeroValue( - builder, loc, reductionResults[0].getType()); - mlir::Value doAdjust = builder.create( - loc, mlir::arith::CmpIPredicate::ne, reductionResults[0], zero); - mlir::Type indexType = builder.getIndexType(); - mlir::Value one = builder.createIntegerConstant(loc, indexType, 1); - - auto adjustCoor = [&](mlir::Value coor, mlir::Value lbound) { - assert(mlir::isa(lbound.getType())); - mlir::Value coorAsIndex = builder.createConvert(loc, indexType, coor); - mlir::Value tmp = - builder.create(loc, coorAsIndex, lbound); - tmp = builder.create(loc, tmp, one); - tmp = - builder.create(loc, doAdjust, tmp, coorAsIndex); - return builder.createConvert(loc, coor.getType(), tmp); - }; - - // For partial reductions, the final result of the reduction - // loop is just a scalar - the coordinate within DIM dimension. - if (getResultRank() == 0 || !isTotalReduction()) { - // The result is a scalar, so just return the scalar. - assert(getNumCoors() == 1 && - "unpexpected number of coordinates for scalar result"); - - int64_t dim = 1; - if (!isTotalReduction()) { - auto dimVal = getConstDim(); - assert(mlir::succeeded(dimVal) && - "partial MINLOC/MAXLOC reduction with invalid DIM"); - dim = *dimVal; + if (isTotalReduction) { + hlfir::Entity result = genKernel(loc, builder, mlir::ValueRange{}); + rewriter.replaceOp(sum, result); + return mlir::success(); } - mlir::Value dimLbound = - hlfir::genLBound(loc, builder, hlfir::Entity{getSource()}, dim - 1); - return hlfir::Entity{adjustCoor(reductionResults[0], dimLbound)}; - } - // This is a total reduction, and there is no wrapping hlfir.elemental. - // We have to pack the reduced coordinates into a rank-one array. - unsigned rank = getSourceRank(); - // TODO: in order to avoid introducing new memory effects - // we should not use a temporary in memory. - // We can use hlfir.elemental with a switch to pack all the coordinates - // into an array expression, or we can have a dedicated HLFIR operation - // for this. - mlir::Value tempArray = builder.createTemporary( - loc, fir::SequenceType::get(rank, getResultElementType())); - llvm::SmallVector arrayLbounds = - hlfir::genLBounds(loc, builder, hlfir::Entity(getSource())); - for (unsigned i = 0; i < rank; ++i) { - mlir::Value coor = adjustCoor(reductionResults[i], arrayLbounds[i]); - mlir::Value idx = builder.createIntegerConstant(loc, indexType, i + 1); - mlir::Value resultElement = - hlfir::getElementAt(loc, builder, hlfir::Entity{tempArray}, {idx}); - builder.create(loc, coor, resultElement); - } - mlir::Value tempExpr = builder.create( - loc, tempArray, builder.createBool(loc, false)); - return hlfir::Entity{tempExpr}; -} - -/// Base class for numeric reductions like MAXVAl, MINVAL, SUM. -template -class NumericReductionAsElementalConverterBase - : public ReductionAsElementalConverter { - using Base = ReductionAsElementalConverter; - -protected: - NumericReductionAsElementalConverterBase(OpT op, - mlir::PatternRewriter &rewriter) - : Base{op.getOperation(), rewriter} {} - - virtual mlir::Value getSource() const final { return getOp().getArray(); } - virtual mlir::Value getDim() const final { return getOp().getDim(); } - virtual mlir::Value getMask() const final { return getOp().getMask(); } - virtual mlir::arith::FastMathFlags getFastMath() const final { - return getOp().getFastmath(); - } - OpT getOp() const { return mlir::cast(op); } - - void checkReductions(const llvm::SmallVectorImpl &reductions) { - assert(reductions.size() == 1 && "reduction must produce single value"); - } -}; - -/// Reduction converter for MAXMAL/MINVAL. -template -class MinMaxvalAsElementalConverter - : public NumericReductionAsElementalConverterBase { - static_assert(std::is_same_v || - std::is_same_v); - static constexpr bool isMax = std::is_same_v; - using Base = NumericReductionAsElementalConverterBase; + hlfir::ElementalOp elementalOp = hlfir::genElementalOp( + loc, builder, elementType, resultShape, {}, genKernel, + /*isUnordered=*/true, /*polymorphicMold=*/nullptr, + sum.getResult().getType()); -public: - MinMaxvalAsElementalConverter(T op, mlir::PatternRewriter &rewriter) - : Base{op, rewriter} {} + // it wouldn't be safe to replace block arguments with a different + // hlfir.expr type. Types can differ due to differing amounts of shape + // information + assert(elementalOp.getResult().getType() == sum.getResult().getType()); -private: - virtual mlir::LogicalResult isConvertible() const final { - if (mlir::isa(this->getSourceElementType())) - return this->rewriter.notifyMatchFailure( - this->getOp(), - "CHARACTER type is not supported for MINVAL/MAXVAL inlining"); + rewriter.replaceOp(sum, elementalOp); return mlir::success(); } - virtual llvm::SmallVector genReductionInitValues() final { - return {genMinMaxInitValue(this->loc, this->builder, - this->getResultElementType())}; - } - virtual llvm::SmallVector - reduceOneElement(const llvm::SmallVectorImpl ¤tValue, - hlfir::Entity array, - mlir::ValueRange oneBasedIndices) final { - this->checkReductions(currentValue); - fir::FirOpBuilder &builder = this->builder; - mlir::Location loc = this->loc; - hlfir::Entity elementValue = - hlfir::loadElementAt(loc, builder, array, oneBasedIndices); - mlir::Value cmp = - genMinMaxComparison(loc, builder, elementValue, currentValue[0]); - return {builder.create(loc, cmp, elementValue, - currentValue[0])}; - } -}; - -/// Reduction converter for SUM. -class SumAsElementalConverter - : public NumericReductionAsElementalConverterBase { - using Base = NumericReductionAsElementalConverterBase; - -public: - SumAsElementalConverter(hlfir::SumOp op, mlir::PatternRewriter &rewriter) - : Base{op, rewriter} {} - -private: - virtual llvm::SmallVector genReductionInitValues() final { - return { - fir::factory::createZeroValue(builder, loc, getResultElementType())}; - } - virtual llvm::SmallVector - reduceOneElement(const llvm::SmallVectorImpl ¤tValue, - hlfir::Entity array, - mlir::ValueRange oneBasedIndices) final { - checkReductions(currentValue); - hlfir::Entity elementValue = - hlfir::loadElementAt(loc, builder, array, oneBasedIndices); - // NOTE: we can use "Kahan summation" same way as the runtime - // (e.g. when fast-math is not allowed), but let's start with - // the simple version. - return {genScalarAdd(currentValue[0], elementValue)}; - } - - // Generate scalar addition of the two values (of the same data type). - mlir::Value genScalarAdd(mlir::Value value1, mlir::Value value2); -}; - -/// Base class for logical reductions like ALL, ANY, COUNT. -/// They do not have MASK and FastMathFlags. -template -class LogicalReductionAsElementalConverterBase - : public ReductionAsElementalConverter { - using Base = ReductionAsElementalConverter; - -public: - LogicalReductionAsElementalConverterBase(OpT op, - mlir::PatternRewriter &rewriter) - : Base{op.getOperation(), rewriter} {} - -protected: - OpT getOp() const { return mlir::cast(op); } - - void checkReductions(const llvm::SmallVectorImpl &reductions) { - assert(reductions.size() == 1 && "reduction must produce single value"); - } - - virtual mlir::Value getSource() const final { return getOp().getMask(); } - virtual mlir::Value getDim() const final { return getOp().getDim(); } - - virtual hlfir::Entity genFinalResult( - const llvm::SmallVectorImpl &reductionResults) override { - checkReductions(reductionResults); - return hlfir::Entity{reductionResults[0]}; - } -}; - -/// Reduction converter for ALL/ANY. -template -class AllAnyAsElementalConverter - : public LogicalReductionAsElementalConverterBase { - static_assert(std::is_same_v || - std::is_same_v); - static constexpr bool isAll = std::is_same_v; - using Base = LogicalReductionAsElementalConverterBase; - -public: - AllAnyAsElementalConverter(T op, mlir::PatternRewriter &rewriter) - : Base{op, rewriter} {} - private: - virtual llvm::SmallVector genReductionInitValues() final { - return {this->builder.createBool(this->loc, isAll ? true : false)}; - } - virtual llvm::SmallVector - reduceOneElement(const llvm::SmallVectorImpl ¤tValue, - hlfir::Entity array, - mlir::ValueRange oneBasedIndices) final { - this->checkReductions(currentValue); - fir::FirOpBuilder &builder = this->builder; - mlir::Location loc = this->loc; - hlfir::Entity elementValue = - hlfir::loadElementAt(loc, builder, array, oneBasedIndices); - mlir::Value mask = - builder.createConvert(loc, builder.getI1Type(), elementValue); - if constexpr (isAll) - return {builder.create(loc, mask, currentValue[0])}; - else - return {builder.create(loc, mask, currentValue[0])}; - } + // Return fir.shape specifying the shape of the result + // of a SUM reduction with DIM=dimVal. The second return value + // is the extent of the DIM dimension. + static std::tuple + genResultShapeForPartialReduction(mlir::Location loc, + fir::FirOpBuilder &builder, + hlfir::Entity array, int64_t dimVal) { + llvm::SmallVector inExtents = + hlfir::genExtentsVector(loc, builder, array); + assert(dimVal > 0 && dimVal <= static_cast(inExtents.size()) && + "DIM must be present and a positive constant not exceeding " + "the array's rank"); - virtual hlfir::Entity genFinalResult( - const llvm::SmallVectorImpl &reductionValues) final { - this->checkReductions(reductionValues); - return hlfir::Entity{this->builder.createConvert( - this->loc, this->getResultElementType(), reductionValues[0])}; + mlir::Value dimExtent = inExtents[dimVal - 1]; + inExtents.erase(inExtents.begin() + dimVal - 1); + return {builder.create(loc, inExtents), dimExtent}; } -}; -/// Reduction converter for COUNT. -class CountAsElementalConverter - : public LogicalReductionAsElementalConverterBase { - using Base = LogicalReductionAsElementalConverterBase; - -public: - CountAsElementalConverter(hlfir::CountOp op, mlir::PatternRewriter &rewriter) - : Base{op, rewriter} {} - -private: - virtual llvm::SmallVector genReductionInitValues() final { - return { - fir::factory::createZeroValue(builder, loc, getResultElementType())}; - } - virtual llvm::SmallVector - reduceOneElement(const llvm::SmallVectorImpl ¤tValue, - hlfir::Entity array, - mlir::ValueRange oneBasedIndices) final { - checkReductions(currentValue); - hlfir::Entity elementValue = - hlfir::loadElementAt(loc, builder, array, oneBasedIndices); - mlir::Value cond = - builder.createConvert(loc, builder.getI1Type(), elementValue); - mlir::Value one = - builder.createIntegerConstant(loc, getResultElementType(), 1); - mlir::Value add1 = - builder.create(loc, currentValue[0], one); - return {builder.create(loc, cond, add1, - currentValue[0])}; + // Generate scalar addition of the two values (of the same data type). + static mlir::Value genScalarAdd(mlir::Location loc, + fir::FirOpBuilder &builder, + mlir::Value value1, mlir::Value value2) { + mlir::Type ty = value1.getType(); + assert(ty == value2.getType() && "reduction values' types do not match"); + if (mlir::isa(ty)) + return builder.create(loc, value1, value2); + else if (mlir::isa(ty)) + return builder.create(loc, value1, value2); + else if (mlir::isa(ty)) + return builder.create(loc, value1, value2); + + llvm_unreachable("unsupported SUM reduction type"); } -}; -mlir::LogicalResult ReductionAsElementalConverter::convert() { - mlir::LogicalResult canConvert(isConvertible()); - - if (mlir::failed(canConvert)) - return canConvert; - - hlfir::Entity array = hlfir::Entity{getSource()}; - bool isTotalReduce = isTotalReduction(); - auto dimVal = getConstDim(); - if (mlir::failed(dimVal)) - return dimVal; - mlir::Value mask = getMask(); - mlir::Value resultShape, dimExtent; - llvm::SmallVector arrayExtents; - if (isTotalReduce) - arrayExtents = hlfir::genExtentsVector(loc, builder, array); - else - std::tie(resultShape, dimExtent) = - genResultShapeForPartialReduction(array, *dimVal); - - // If the mask is present and is a scalar, then we'd better load its value - // outside of the reduction loop making the loop unswitching easier. - mlir::Value isPresentPred, maskValue; - if (mask) { - if (mlir::isa(mask.getType())) { - // MASK represented by a box might be dynamically optional, - // so we have to check for its presence before accessing it. - isPresentPred = - builder.create(loc, builder.getI1Type(), mask); + static mlir::Value genMaskValue(mlir::Location loc, + fir::FirOpBuilder &builder, mlir::Value mask, + mlir::Value isPresentPred, + mlir::ValueRange indices) { + mlir::OpBuilder::InsertionGuard guard(builder); + fir::IfOp ifOp; + mlir::Type maskType = + hlfir::getFortranElementType(fir::unwrapPassByRefType(mask.getType())); + if (isPresentPred) { + ifOp = builder.create(loc, maskType, isPresentPred, + /*withElseRegion=*/true); + + // Use 'true', if the mask is not present. + builder.setInsertionPointToStart(&ifOp.getElseRegion().front()); + mlir::Value trueValue = builder.createBool(loc, true); + trueValue = builder.createConvert(loc, maskType, trueValue); + builder.create(loc, trueValue); + + // Load the mask value, if the mask is present. + builder.setInsertionPointToStart(&ifOp.getThenRegion().front()); } - if (hlfir::Entity{mask}.isScalar()) - maskValue = genMaskValue(mask, isPresentPred, {}); - } - - auto genKernel = [&](mlir::Location loc, fir::FirOpBuilder &builder, - mlir::ValueRange inputIndices) -> hlfir::Entity { - // Loop over all indices in the DIM dimension, and reduce all values. - // If DIM is not present, do total reduction. - - // Initial value for the reduction. - llvm::SmallVector reductionInitValues = - genReductionInitValues(); - - llvm::SmallVector extents; - if (isTotalReduce) - extents = arrayExtents; - else - extents.push_back( - builder.createConvert(loc, builder.getIndexType(), dimExtent)); - - auto genBody = [&](mlir::Location loc, fir::FirOpBuilder &builder, - mlir::ValueRange oneBasedIndices, - mlir::ValueRange reductionArgs) - -> llvm::SmallVector { - // Generate the reduction loop-nest body. - // The initial reduction value in the innermost loop - // is passed via reductionArgs[0]. - llvm::SmallVector indices; - if (isTotalReduce) { - indices = oneBasedIndices; + hlfir::Entity maskVar{mask}; + if (maskVar.isScalar()) { + if (mlir::isa(mask.getType())) { + // MASK may be a boxed scalar. + mlir::Value addr = hlfir::genVariableRawAddress(loc, builder, maskVar); + mask = builder.create(loc, hlfir::Entity{addr}); } else { - indices = inputIndices; - indices.insert(indices.begin() + *dimVal - 1, oneBasedIndices[0]); - } - - llvm::SmallVector reductionValues = reductionArgs; - llvm::SmallVector reductionTypes; - llvm::transform(reductionValues, std::back_inserter(reductionTypes), - [](mlir::Value v) { return v.getType(); }); - fir::IfOp ifOp; - if (mask) { - // Make the reduction value update conditional on the value - // of the mask. - if (!maskValue) { - // If the mask is an array, use the elemental and the loop indices - // to address the proper mask element. - maskValue = genMaskValue(mask, isPresentPred, indices); - } - mlir::Value isUnmasked = - builder.create(loc, builder.getI1Type(), maskValue); - ifOp = builder.create(loc, reductionTypes, isUnmasked, - /*withElseRegion=*/true); - // In the 'else' block return the current reduction value. - builder.setInsertionPointToStart(&ifOp.getElseRegion().front()); - builder.create(loc, reductionValues); - - // In the 'then' block do the actual addition. - builder.setInsertionPointToStart(&ifOp.getThenRegion().front()); + mask = hlfir::loadTrivialScalar(loc, builder, maskVar); } - reductionValues = reduceOneElement(reductionValues, array, indices); - if (ifOp) { - builder.create(loc, reductionValues); - builder.setInsertionPointAfter(ifOp); - reductionValues = ifOp.getResults(); - } - - return reductionValues; - }; - - llvm::SmallVector reductionFinalValues = - hlfir::genLoopNestWithReductions( - loc, builder, extents, reductionInitValues, genBody, isUnordered()); - return genFinalResult(reductionFinalValues); - }; - - if (isTotalReduce) { - hlfir::Entity result = genKernel(loc, builder, mlir::ValueRange{}); - rewriter.replaceOp(op, result); - return mlir::success(); - } - - hlfir::ElementalOp elementalOp = hlfir::genElementalOp( - loc, builder, getResultElementType(), resultShape, /*typeParams=*/{}, - genKernel, - /*isUnordered=*/true, /*polymorphicMold=*/nullptr, getResultType()); - - // it wouldn't be safe to replace block arguments with a different - // hlfir.expr type. Types can differ due to differing amounts of shape - // information - assert(elementalOp.getResult().getType() == op->getResult(0).getType()); - - rewriter.replaceOp(op, elementalOp); - return mlir::success(); -} - -std::tuple -ReductionAsElementalConverter::genResultShapeForPartialReduction( - hlfir::Entity array, int64_t dimVal) { - llvm::SmallVector inExtents = - hlfir::genExtentsVector(loc, builder, array); - assert(dimVal > 0 && dimVal <= static_cast(inExtents.size()) && - "DIM must be present and a positive constant not exceeding " - "the array's rank"); - - mlir::Value dimExtent = inExtents[dimVal - 1]; - inExtents.erase(inExtents.begin() + dimVal - 1); - return {builder.create(loc, inExtents), dimExtent}; -} - -mlir::Value SumAsElementalConverter::genScalarAdd(mlir::Value value1, - mlir::Value value2) { - mlir::Type ty = value1.getType(); - assert(ty == value2.getType() && "reduction values' types do not match"); - if (mlir::isa(ty)) - return builder.create(loc, value1, value2); - else if (mlir::isa(ty)) - return builder.create(loc, value1, value2); - else if (mlir::isa(ty)) - return builder.create(loc, value1, value2); - - llvm_unreachable("unsupported SUM reduction type"); -} - -mlir::Value ReductionAsElementalConverter::genMaskValue( - mlir::Value mask, mlir::Value isPresentPred, mlir::ValueRange indices) { - mlir::OpBuilder::InsertionGuard guard(builder); - fir::IfOp ifOp; - mlir::Type maskType = - hlfir::getFortranElementType(fir::unwrapPassByRefType(mask.getType())); - if (isPresentPred) { - ifOp = builder.create(loc, maskType, isPresentPred, - /*withElseRegion=*/true); - - // Use 'true', if the mask is not present. - builder.setInsertionPointToStart(&ifOp.getElseRegion().front()); - mlir::Value trueValue = builder.createBool(loc, true); - trueValue = builder.createConvert(loc, maskType, trueValue); - builder.create(loc, trueValue); - - // Load the mask value, if the mask is present. - builder.setInsertionPointToStart(&ifOp.getThenRegion().front()); - } - - hlfir::Entity maskVar{mask}; - if (maskVar.isScalar()) { - if (mlir::isa(mask.getType())) { - // MASK may be a boxed scalar. - mlir::Value addr = hlfir::genVariableRawAddress(loc, builder, maskVar); - mask = builder.create(loc, hlfir::Entity{addr}); } else { + // Load from the mask array. + assert(!indices.empty() && "no indices for addressing the mask array"); + maskVar = hlfir::getElementAt(loc, builder, maskVar, indices); mask = hlfir::loadTrivialScalar(loc, builder, maskVar); } - } else { - // Load from the mask array. - assert(!indices.empty() && "no indices for addressing the mask array"); - maskVar = hlfir::getElementAt(loc, builder, maskVar, indices); - mask = hlfir::loadTrivialScalar(loc, builder, maskVar); - } - - if (!isPresentPred) - return mask; - builder.create(loc, mask); - return ifOp.getResult(0); -} - -/// Convert an operation that is a partial or total reduction -/// over an array of values into a reduction loop[-nest] -/// optionally wrapped into hlfir.elemental. -template -class ReductionConversion : public mlir::OpRewritePattern { -public: - using mlir::OpRewritePattern::OpRewritePattern; + if (!isPresentPred) + return mask; - llvm::LogicalResult - matchAndRewrite(Op op, mlir::PatternRewriter &rewriter) const override { - if constexpr (std::is_same_v || - std::is_same_v) { - MinMaxlocAsElementalConverter converter(op, rewriter); - return converter.convert(); - } else if constexpr (std::is_same_v || - std::is_same_v) { - MinMaxvalAsElementalConverter converter(op, rewriter); - return converter.convert(); - } else if constexpr (std::is_same_v) { - CountAsElementalConverter converter(op, rewriter); - return converter.convert(); - } else if constexpr (std::is_same_v || - std::is_same_v) { - AllAnyAsElementalConverter converter(op, rewriter); - return converter.convert(); - } else if constexpr (std::is_same_v) { - SumAsElementalConverter converter{op, rewriter}; - return converter.convert(); - } - return rewriter.notifyMatchFailure(op, "unexpected reduction operation"); + builder.create(loc, mask); + return ifOp.getResult(0); } }; @@ -2118,18 +1481,10 @@ class SimplifyHLFIRIntrinsics mlir::RewritePatternSet patterns(context); patterns.insert(context); - patterns.insert>(context); + patterns.insert(context); patterns.insert(context); patterns.insert>(context); - patterns.insert>(context); - patterns.insert>(context); - patterns.insert>(context); - patterns.insert>(context); - patterns.insert>(context); - patterns.insert>(context); - patterns.insert>(context); - // If forceMatmulAsElemental is false, then hlfir.matmul inlining // will introduce hlfir.eval_in_mem operation with new memory side // effects. This conflicts with CSE and optimized bufferization, e.g.: diff --git a/flang/test/HLFIR/all-elemental.fir b/flang/test/HLFIR/all-elemental.fir new file mode 100644 index 0000000000000..1ba8bb1b7a5fb --- /dev/null +++ b/flang/test/HLFIR/all-elemental.fir @@ -0,0 +1,91 @@ +// RUN: fir-opt %s -opt-bufferization | FileCheck %s + +func.func @_QFPtest(%arg0: !fir.ref> {fir.bindc_name = "b"}, %arg1: !fir.ref {fir.bindc_name = "row"}, %arg2: !fir.ref {fir.bindc_name = "val"}) -> !fir.logical<4> { + %c1 = arith.constant 1 : index + %c4 = arith.constant 4 : index + %c7 = arith.constant 7 : index + %0 = fir.shape %c4, %c7 : (index, index) -> !fir.shape<2> + %1:2 = hlfir.declare %arg0(%0) {uniq_name = "_QFFtestEb"} : (!fir.ref>, !fir.shape<2>) -> (!fir.ref>, !fir.ref>) + %2:2 = hlfir.declare %arg1 {uniq_name = "_QFFtestErow"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %3 = fir.alloca !fir.logical<4> {bindc_name = "test", uniq_name = "_QFFtestEtest"} + %4:2 = hlfir.declare %3 {uniq_name = "_QFFtestEtest"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) + %5:2 = hlfir.declare %arg2 {uniq_name = "_QFFtestEval"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %6 = fir.load %2#0 : !fir.ref + %7 = fir.convert %6 : (i32) -> i64 + %8 = fir.shape %c7 : (index) -> !fir.shape<1> + %9 = hlfir.designate %1#0 (%7, %c1:%c7:%c1) shape %8 : (!fir.ref>, i64, index, index, index, !fir.shape<1>) -> !fir.box> + %10 = fir.load %5#0 : !fir.ref + %11 = hlfir.elemental %8 unordered : (!fir.shape<1>) -> !hlfir.expr<7x!fir.logical<4>> { + ^bb0(%arg3: index): + %14 = hlfir.designate %9 (%arg3) : (!fir.box>, index) -> !fir.ref + %15 = fir.load %14 : !fir.ref + %16 = arith.cmpi sge, %15, %10 : i32 + %17 = fir.convert %16 : (i1) -> !fir.logical<4> + hlfir.yield_element %17 : !fir.logical<4> + } + %12 = hlfir.all %11 : (!hlfir.expr<7x!fir.logical<4>>) -> !fir.logical<4> + hlfir.assign %12 to %4#0 : !fir.logical<4>, !fir.ref> + hlfir.destroy %11 : !hlfir.expr<7x!fir.logical<4>> + %13 = fir.load %4#1 : !fir.ref> + return %13 : !fir.logical<4> +} +// CHECK-LABEL: func.func @_QFPtest(%arg0: !fir.ref> {fir.bindc_name = "b"}, %arg1: !fir.ref {fir.bindc_name = "row"}, %arg2: !fir.ref {fir.bindc_name = "val"}) -> !fir.logical<4> { +// CHECK-NEXT: %true = arith.constant true +// CHECK-NEXT: %c1 = arith.constant 1 : index +// CHECK-NEXT: %c4 = arith.constant 4 : index +// CHECK-NEXT: %c7 = arith.constant 7 : index +// CHECK-NEXT: %[[V0:.*]] = fir.shape %c4, %c7 : (index, index) -> !fir.shape<2> +// CHECK-NEXT: %[[V1:.*]]:2 = hlfir.declare %arg0(%[[V0]]) +// CHECK-NEXT: %[[V2:.*]]:2 = hlfir.declare %arg1 +// CHECK-NEXT: %[[V3:.*]] = fir.alloca !fir.logical<4> +// CHECK-NEXT: %[[V4:.*]]:2 = hlfir.declare %[[V3]] +// CHECK-NEXT: %[[V5:.*]]:2 = hlfir.declare %arg2 +// CHECK-NEXT: %[[V6:.*]] = fir.load %[[V2]]#0 : !fir.ref +// CHECK-NEXT: %[[V7:.*]] = fir.convert %[[V6]] : (i32) -> i64 +// CHECK-NEXT: %[[V8:.*]] = fir.shape %c7 : (index) -> !fir.shape<1> +// CHECK-NEXT: %[[V9:.*]] = hlfir.designate %[[V1]]#0 (%[[V7]], %c1:%c7:%c1) shape %[[V8]] : (!fir.ref>, i64, index, index, index, !fir.shape<1>) -> !fir.box> +// CHECK-NEXT: %[[V10:.*]] = fir.load %[[V5]]#0 : !fir.ref +// CHECK-NEXT: %[[V11:.*]] = fir.do_loop %arg3 = %c1 to %c7 step %c1 iter_args(%arg4 = %true) -> (i1) { +// CHECK-NEXT: %[[V14:.*]] = hlfir.designate %[[V9]] (%arg3) : (!fir.box>, index) -> !fir.ref +// CHECK-NEXT: %[[V15:.*]] = fir.load %[[V14]] : !fir.ref +// CHECK-NEXT: %[[V16:.*]] = arith.cmpi sge, %[[V15]], %[[V10]] : i32 +// CHECK-NEXT: %[[V17:.*]] = arith.andi %arg4, %[[V16]] : i1 +// CHECK-NEXT: fir.result %[[V17]] : i1 +// CHECK-NEXT: } +// CHECK-NEXT: %[[V12:.*]] = fir.convert %[[V11]] : (i1) -> !fir.logical<4> +// CHECK-NEXT: hlfir.assign %[[V12]] to %[[V4]]#0 : !fir.logical<4>, !fir.ref> +// CHECK-NEXT: %[[V13:.*]] = fir.load %[[V4]]#1 : !fir.ref> +// CHECK-NEXT: return %[[V13]] : !fir.logical<4> + + +func.func @_QFPtest_dim(%arg0: !fir.ref> {fir.bindc_name = "b"}, %arg1: !fir.ref {fir.bindc_name = "row"}, %arg2: !fir.ref {fir.bindc_name = "val"}) -> !fir.array<4x!fir.logical<4>> { + %c2_i32 = arith.constant 2 : i32 + %c1 = arith.constant 1 : index + %c4 = arith.constant 4 : index + %c7 = arith.constant 7 : index + %0 = fir.shape %c4, %c7 : (index, index) -> !fir.shape<2> + %1:2 = hlfir.declare %arg0(%0) {uniq_name = "_QFFtestEb"} : (!fir.ref>, !fir.shape<2>) -> (!fir.ref>, !fir.ref>) + %2:2 = hlfir.declare %arg1 {uniq_name = "_QFFtestErow"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %3 = fir.alloca !fir.array<4x!fir.logical<4>> {bindc_name = "test", uniq_name = "_QFFtestEtest"} + %4 = fir.shape %c4 : (index) -> !fir.shape<1> + %5:2 = hlfir.declare %3(%4) {uniq_name = "_QFFtestEtest"} : (!fir.ref>>, !fir.shape<1>) -> (!fir.ref>>, !fir.ref>>) + %6:2 = hlfir.declare %arg2 {uniq_name = "_QFFtestEval"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %7 = hlfir.designate %1#0 (%c1:%c4:%c1, %c1:%c7:%c1) shape %0 : (!fir.ref>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.ref> + %8 = fir.load %6#0 : !fir.ref + %9 = hlfir.elemental %0 unordered : (!fir.shape<2>) -> !hlfir.expr<4x7x!fir.logical<4>> { + ^bb0(%arg3: index, %arg4: index): + %12 = hlfir.designate %7 (%arg3, %arg4) : (!fir.ref>, index, index) -> !fir.ref + %13 = fir.load %12 : !fir.ref + %14 = arith.cmpi sge, %13, %8 : i32 + %15 = fir.convert %14 : (i1) -> !fir.logical<4> + hlfir.yield_element %15 : !fir.logical<4> + } + %10 = hlfir.all %9 dim %c2_i32 : (!hlfir.expr<4x7x!fir.logical<4>>, i32) -> !hlfir.expr<4x!fir.logical<4>> + hlfir.assign %10 to %5#0 : !hlfir.expr<4x!fir.logical<4>>, !fir.ref>> + hlfir.destroy %10 : !hlfir.expr<4x!fir.logical<4>> + hlfir.destroy %9 : !hlfir.expr<4x7x!fir.logical<4>> + %11 = fir.load %5#1 : !fir.ref>> + return %11 : !fir.array<4x!fir.logical<4>> +} +// CHECK-LABEL: func.func @_QFPtest_dim( +// CHECK: %10 = hlfir.all %9 dim %c2_i32 \ No newline at end of file diff --git a/flang/test/HLFIR/any-elemental.fir b/flang/test/HLFIR/any-elemental.fir new file mode 100644 index 0000000000000..a7c559679d965 --- /dev/null +++ b/flang/test/HLFIR/any-elemental.fir @@ -0,0 +1,190 @@ +// RUN: fir-opt %s -opt-bufferization | FileCheck %s + +func.func @_QFPtest(%arg0: !fir.ref> {fir.bindc_name = "b"}, %arg1: !fir.ref {fir.bindc_name = "row"}, %arg2: !fir.ref {fir.bindc_name = "val"}) -> !fir.logical<4> { + %c1 = arith.constant 1 : index + %c4 = arith.constant 4 : index + %c7 = arith.constant 7 : index + %0 = fir.shape %c4, %c7 : (index, index) -> !fir.shape<2> + %1:2 = hlfir.declare %arg0(%0) {uniq_name = "_QFFtestEb"} : (!fir.ref>, !fir.shape<2>) -> (!fir.ref>, !fir.ref>) + %2:2 = hlfir.declare %arg1 {uniq_name = "_QFFtestErow"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %3 = fir.alloca !fir.logical<4> {bindc_name = "test", uniq_name = "_QFFtestEtest"} + %4:2 = hlfir.declare %3 {uniq_name = "_QFFtestEtest"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) + %5:2 = hlfir.declare %arg2 {uniq_name = "_QFFtestEval"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %6 = fir.load %2#0 : !fir.ref + %7 = fir.convert %6 : (i32) -> i64 + %8 = fir.shape %c7 : (index) -> !fir.shape<1> + %9 = hlfir.designate %1#0 (%7, %c1:%c7:%c1) shape %8 : (!fir.ref>, i64, index, index, index, !fir.shape<1>) -> !fir.box> + %10 = fir.load %5#0 : !fir.ref + %11 = hlfir.elemental %8 unordered : (!fir.shape<1>) -> !hlfir.expr<7x!fir.logical<4>> { + ^bb0(%arg3: index): + %14 = hlfir.designate %9 (%arg3) : (!fir.box>, index) -> !fir.ref + %15 = fir.load %14 : !fir.ref + %16 = arith.cmpi sge, %15, %10 : i32 + %17 = fir.convert %16 : (i1) -> !fir.logical<4> + hlfir.yield_element %17 : !fir.logical<4> + } + %12 = hlfir.any %11 : (!hlfir.expr<7x!fir.logical<4>>) -> !fir.logical<4> + hlfir.assign %12 to %4#0 : !fir.logical<4>, !fir.ref> + hlfir.destroy %11 : !hlfir.expr<7x!fir.logical<4>> + %13 = fir.load %4#1 : !fir.ref> + return %13 : !fir.logical<4> +} +// CHECK-LABEL: func.func @_QFPtest(%arg0: !fir.ref> {fir.bindc_name = "b"}, %arg1: !fir.ref {fir.bindc_name = "row"}, %arg2: !fir.ref {fir.bindc_name = "val"}) -> !fir.logical<4> { +// CHECK-NEXT: %false = arith.constant false +// CHECK-NEXT: %c1 = arith.constant 1 : index +// CHECK-NEXT: %c4 = arith.constant 4 : index +// CHECK-NEXT: %c7 = arith.constant 7 : index +// CHECK-NEXT: %[[V0:.*]] = fir.shape %c4, %c7 : (index, index) -> !fir.shape<2> +// CHECK-NEXT: %[[V1:.*]]:2 = hlfir.declare %arg0(%[[V0]]) +// CHECK-NEXT: %[[V2:.*]]:2 = hlfir.declare %arg1 +// CHECK-NEXT: %[[V3:.*]] = fir.alloca !fir.logical<4> +// CHECK-NEXT: %[[V4:.*]]:2 = hlfir.declare %[[V3]] +// CHECK-NEXT: %[[V5:.*]]:2 = hlfir.declare %arg2 +// CHECK-NEXT: %[[V6:.*]] = fir.load %[[V2]]#0 : !fir.ref +// CHECK-NEXT: %[[V7:.*]] = fir.convert %[[V6]] : (i32) -> i64 +// CHECK-NEXT: %[[V8:.*]] = fir.shape %c7 : (index) -> !fir.shape<1> +// CHECK-NEXT: %[[V9:.*]] = hlfir.designate %[[V1]]#0 (%[[V7]], %c1:%c7:%c1) shape %[[V8]] : (!fir.ref>, i64, index, index, index, !fir.shape<1>) -> !fir.box> +// CHECK-NEXT: %[[V10:.*]] = fir.load %[[V5]]#0 : !fir.ref +// CHECK-NEXT: %[[V11:.*]] = fir.do_loop %arg3 = %c1 to %c7 step %c1 iter_args(%arg4 = %false) -> (i1) { +// CHECK-NEXT: %[[V14:.*]] = hlfir.designate %[[V9]] (%arg3) : (!fir.box>, index) -> !fir.ref +// CHECK-NEXT: %[[V15:.*]] = fir.load %[[V14]] : !fir.ref +// CHECK-NEXT: %[[V16:.*]] = arith.cmpi sge, %[[V15]], %[[V10]] : i32 +// CHECK-NEXT: %[[V17:.*]] = arith.ori %arg4, %[[V16]] : i1 +// CHECK-NEXT: fir.result %[[V17]] : i1 +// CHECK-NEXT: } +// CHECK-NEXT: %[[V12:.*]] = fir.convert %[[V11]] : (i1) -> !fir.logical<4> +// CHECK-NEXT: hlfir.assign %[[V12]] to %[[V4]]#0 : !fir.logical<4>, !fir.ref> +// CHECK-NEXT: %[[V13:.*]] = fir.load %[[V4]]#1 : !fir.ref> +// CHECK-NEXT: return %[[V13]] : !fir.logical<4> + + +func.func @_QFPtest_dim(%arg0: !fir.ref> {fir.bindc_name = "b"}, %arg1: !fir.ref {fir.bindc_name = "row"}, %arg2: !fir.ref {fir.bindc_name = "val"}) -> !fir.array<4x!fir.logical<4>> { + %c2_i32 = arith.constant 2 : i32 + %c1 = arith.constant 1 : index + %c4 = arith.constant 4 : index + %c7 = arith.constant 7 : index + %0 = fir.shape %c4, %c7 : (index, index) -> !fir.shape<2> + %1:2 = hlfir.declare %arg0(%0) {uniq_name = "_QFFtestEb"} : (!fir.ref>, !fir.shape<2>) -> (!fir.ref>, !fir.ref>) + %2:2 = hlfir.declare %arg1 {uniq_name = "_QFFtestErow"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %3 = fir.alloca !fir.array<4x!fir.logical<4>> {bindc_name = "test", uniq_name = "_QFFtestEtest"} + %4 = fir.shape %c4 : (index) -> !fir.shape<1> + %5:2 = hlfir.declare %3(%4) {uniq_name = "_QFFtestEtest"} : (!fir.ref>>, !fir.shape<1>) -> (!fir.ref>>, !fir.ref>>) + %6:2 = hlfir.declare %arg2 {uniq_name = "_QFFtestEval"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %7 = hlfir.designate %1#0 (%c1:%c4:%c1, %c1:%c7:%c1) shape %0 : (!fir.ref>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.ref> + %8 = fir.load %6#0 : !fir.ref + %9 = hlfir.elemental %0 unordered : (!fir.shape<2>) -> !hlfir.expr<4x7x!fir.logical<4>> { + ^bb0(%arg3: index, %arg4: index): + %12 = hlfir.designate %7 (%arg3, %arg4) : (!fir.ref>, index, index) -> !fir.ref + %13 = fir.load %12 : !fir.ref + %14 = arith.cmpi sge, %13, %8 : i32 + %15 = fir.convert %14 : (i1) -> !fir.logical<4> + hlfir.yield_element %15 : !fir.logical<4> + } + %10 = hlfir.any %9 dim %c2_i32 : (!hlfir.expr<4x7x!fir.logical<4>>, i32) -> !hlfir.expr<4x!fir.logical<4>> + hlfir.assign %10 to %5#0 : !hlfir.expr<4x!fir.logical<4>>, !fir.ref>> + hlfir.destroy %10 : !hlfir.expr<4x!fir.logical<4>> + hlfir.destroy %9 : !hlfir.expr<4x7x!fir.logical<4>> + %11 = fir.load %5#1 : !fir.ref>> + return %11 : !fir.array<4x!fir.logical<4>> +} +// CHECK-LABEL: func.func @_QFPtest_dim( +// CHECK: {{.*}} = hlfir.any {{.*}} dim %c2_i32 + + +func.func @_Qtest_recursive() attributes {fir.bindc_name = "test"} { + %c1 = arith.constant 1 : index + %true = arith.constant true + %false = arith.constant false + %c0_i64 = arith.constant 0 : i64 + %c2_i32 = arith.constant 2 : i32 + %c0 = arith.constant 0 : index + %c1_i32 = arith.constant 1 : i32 + %0 = fir.address_of(@_QFEa) : !fir.ref>>> + %1:2 = hlfir.declare %0 {fortran_attrs = #fir.var_attrs, uniq_name = "_QFEa"} : (!fir.ref>>>) -> (!fir.ref>>>, !fir.ref>>>) + %2 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFEi"} + %3:2 = hlfir.declare %2 {uniq_name = "_QFEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %4 = fir.alloca i32 {bindc_name = "n", uniq_name = "_QFEn"} + %5:2 = hlfir.declare %4 {uniq_name = "_QFEn"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %6 = fir.alloca !fir.array<1x!fir.logical<4>> {bindc_name = "ra", uniq_name = "_QFEra"} + %7 = fir.shape %c1 : (index) -> !fir.shape<1> + %8:2 = hlfir.declare %6(%7) {uniq_name = "_QFEra"} : (!fir.ref>>, !fir.shape<1>) -> (!fir.ref>>, !fir.ref>>) + %9 = fir.alloca !fir.logical<4> {bindc_name = "rs", uniq_name = "_QFErs"} + %10:2 = hlfir.declare %9 {uniq_name = "_QFErs"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) + %11 = fir.allocmem !fir.array, %c1 {fir.must_be_heap = true, uniq_name = "_QFEa.alloc"} + %12 = fir.embox %11(%7) : (!fir.heap>, !fir.shape<1>) -> !fir.box>> + fir.store %12 to %1#1 : !fir.ref>>> + hlfir.assign %c1_i32 to %5#0 : i32, !fir.ref + %13 = fir.load %1#0 : !fir.ref>>> + %14:3 = fir.box_dims %13, %c0 : (!fir.box>>, index) -> (index, index, index) + fir.do_loop %arg0 = %c1 to %14#1 step %c1 unordered { + %27:3 = fir.box_dims %13, %c0 : (!fir.box>>, index) -> (index, index, index) + %28 = arith.subi %27#0, %c1 : index + %29 = arith.addi %arg0, %28 : index + %30 = hlfir.designate %13 (%29) : (!fir.box>>, index) -> !fir.ref + hlfir.assign %c2_i32 to %30 : i32, !fir.ref + } + %15 = fir.load %5#0 : !fir.ref + %16 = fir.convert %15 : (i32) -> i64 + %17 = arith.cmpi sgt, %16, %c0_i64 : i64 + %18 = arith.select %17, %16, %c0_i64 : i64 + %19 = fir.convert %18 : (i64) -> index + %20 = fir.shape %19 : (index) -> !fir.shape<1> + %21 = hlfir.elemental %20 unordered : (!fir.shape<1>) -> !hlfir.expr> { + ^bb0(%arg0: index): + %27 = fir.load %1#0 : !fir.ref>>> + %28:3 = fir.box_dims %27, %c0 : (!fir.box>>, index) -> (index, index, index) + %29 = arith.addi %28#0, %28#1 : index + %30 = arith.subi %29, %c1 : index + %31 = arith.subi %30, %28#0 : index + %32 = arith.addi %31, %c1 : index + %33 = arith.cmpi sgt, %32, %c0 : index + %34 = arith.select %33, %32, %c0 : index + %35 = fir.shape %34 : (index) -> !fir.shape<1> + %36 = hlfir.designate %27 (%28#0:%30:%c1) shape %35 : (!fir.box>>, index, index, index, !fir.shape<1>) -> !fir.box> + %37 = hlfir.elemental %35 unordered : (!fir.shape<1>) -> !hlfir.expr> { + ^bb0(%arg1: index): + %39 = hlfir.designate %36 (%arg1) : (!fir.box>, index) -> !fir.ref + %40 = fir.load %39 : !fir.ref + %41 = arith.cmpi eq, %40, %c1_i32 : i32 + %42 = fir.convert %41 : (i1) -> !fir.logical<4> + hlfir.yield_element %42 : !fir.logical<4> + } + %38 = hlfir.any %37 : (!hlfir.expr>) -> !fir.logical<4> + hlfir.destroy %37 : !hlfir.expr> + hlfir.yield_element %38 : !fir.logical<4> + } + %22 = hlfir.any %21 : (!hlfir.expr>) -> !fir.logical<4> + hlfir.assign %22 to %10#0 : !fir.logical<4>, !fir.ref> + hlfir.destroy %21 : !hlfir.expr> + %23 = fir.load %10#0 : !fir.ref> + %24 = fir.convert %23 : (!fir.logical<4>) -> i1 + %25 = arith.xori %24, %true : i1 + cf.cond_br %25, ^bb1, ^bb2 +^bb1: // pred: ^bb0 + fir.call @_FortranAStopStatement(%c2_i32, %false, %false) fastmath : (i32, i1, i1) -> () + fir.unreachable +^bb2: // pred: ^bb0 + return +} +// CHECK-LABEL: func.func @_Qtest_recursive() +// CHECK: %[[V20:.*]] = fir.do_loop %arg0 = %c1 to %{{.*}} step %c1 iter_args(%arg1 = %false) -> (i1) { +// CHECK: %[[V26:.*]] = fir.load %[[V1]]#0 : !fir.ref>>> +// CHECK: %[[V27:.*]]:3 = fir.box_dims %[[V26]], %c0 : (!fir.box>>, index) -> (index, index, index) +// CHECK: %[[V28:.*]] = arith.addi %[[V27]]#0, %[[V27]]#1 : index +// CHECK: %[[V29:.*]] = arith.subi %[[V28]], %c1 : index +// CHECK: %[[V30:.*]] = arith.subi %[[V29]], %[[V27]]#0 : index +// CHECK: %[[V31:.*]] = arith.addi %[[V30]], %c1 : index +// CHECK: %[[V32:.*]] = arith.cmpi sgt, %[[V31]], %c0 : index +// CHECK: %[[V33:.*]] = arith.select %[[V32]], %[[V31]], %c0 : index +// CHECK: %[[V34:.*]] = fir.shape %[[V33]] : (index) -> !fir.shape<1> +// CHECK: %[[V35:.*]] = hlfir.designate %[[V26]] (%[[V27]]#0:%[[V29]]:%c1) shape %[[V34]] : (!fir.box>>, index, index, index, !fir.shape<1>) -> !fir.box> +// CHECK: %[[V36:.*]] = fir.do_loop %arg2 = %c1 to %[[V33]] step %c1 iter_args(%arg3 = %false) -> (i1) { +// CHECK: %[[V38:.*]] = hlfir.designate %[[V35]] (%arg2) : (!fir.box>, index) -> !fir.ref +// CHECK: %[[V39:.*]] = fir.load %[[V38]] : !fir.ref +// CHECK: %[[V40:.*]] = arith.cmpi eq, %[[V39]], %c1_i32 : i32 +// CHECK: %[[V41:.*]] = arith.ori %arg3, %[[V40]] : i1 +// CHECK: fir.result %[[V41]] : i1 +// CHECK: } +// CHECK: %[[V37:.*]] = arith.ori %arg1, %[[V36]] : i1 +// CHECK: fir.result %[[V37]] : i1 +// CHECK: } diff --git a/flang/test/HLFIR/count-elemental.fir b/flang/test/HLFIR/count-elemental.fir new file mode 100644 index 0000000000000..0df5cc3c031ea --- /dev/null +++ b/flang/test/HLFIR/count-elemental.fir @@ -0,0 +1,314 @@ +// RUN: fir-opt %s -opt-bufferization | FileCheck %s + +func.func @_QFPtest(%arg0: !fir.ref> {fir.bindc_name = "b"}, %arg1: !fir.ref {fir.bindc_name = "row"}, %arg2: !fir.ref {fir.bindc_name = "val"}) -> i32 { + %c1 = arith.constant 1 : index + %c4 = arith.constant 4 : index + %c7 = arith.constant 7 : index + %0 = fir.shape %c4, %c7 : (index, index) -> !fir.shape<2> + %1:2 = hlfir.declare %arg0(%0) {uniq_name = "_QFFtestEb"} : (!fir.ref>, !fir.shape<2>) -> (!fir.ref>, !fir.ref>) + %2:2 = hlfir.declare %arg1 {uniq_name = "_QFFtestErow"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %3 = fir.alloca i32 {bindc_name = "test", uniq_name = "_QFFtestEtest"} + %4:2 = hlfir.declare %3 {uniq_name = "_QFFtestEtest"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %5:2 = hlfir.declare %arg2 {uniq_name = "_QFFtestEval"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %6 = fir.load %2#0 : !fir.ref + %7 = fir.convert %6 : (i32) -> i64 + %8 = fir.shape %c7 : (index) -> !fir.shape<1> + %9 = hlfir.designate %1#0 (%7, %c1:%c7:%c1) shape %8 : (!fir.ref>, i64, index, index, index, !fir.shape<1>) -> !fir.box> + %10 = fir.load %5#0 : !fir.ref + %11 = hlfir.elemental %8 unordered : (!fir.shape<1>) -> !hlfir.expr<7x!fir.logical<4>> { + ^bb0(%arg3: index): + %14 = hlfir.designate %9 (%arg3) : (!fir.box>, index) -> !fir.ref + %15 = fir.load %14 : !fir.ref + %16 = arith.cmpi sge, %15, %10 : i32 + %17 = fir.convert %16 : (i1) -> !fir.logical<4> + hlfir.yield_element %17 : !fir.logical<4> + } + %12 = hlfir.count %11 : (!hlfir.expr<7x!fir.logical<4>>) -> i32 + hlfir.assign %12 to %4#0 : i32, !fir.ref + hlfir.destroy %11 : !hlfir.expr<7x!fir.logical<4>> + %13 = fir.load %4#1 : !fir.ref + return %13 : i32 +} +// CHECK-LABEL: func.func @_QFPtest(%arg0: !fir.ref> {fir.bindc_name = "b"}, %arg1: !fir.ref {fir.bindc_name = "row"}, %arg2: !fir.ref {fir.bindc_name = "val"}) -> i32 { +// CHECK-NEXT: %c1_i32 = arith.constant 1 : i32 +// CHECK-NEXT: %c0_i32 = arith.constant 0 : i32 +// CHECK-NEXT: %c1 = arith.constant 1 : index +// CHECK-NEXT: %c4 = arith.constant 4 : index +// CHECK-NEXT: %c7 = arith.constant 7 : index +// CHECK-NEXT: %[[V0:.*]] = fir.shape %c4, %c7 : (index, index) -> !fir.shape<2> +// CHECK-NEXT: %[[V1:.*]]:2 = hlfir.declare %arg0(%[[V0]]) +// CHECK-NEXT: %[[V2:.*]]:2 = hlfir.declare %arg1 +// CHECK-NEXT: %[[V3:.*]] = fir.alloca i32 +// CHECK-NEXT: %[[V4:.*]]:2 = hlfir.declare %[[V3]] +// CHECK-NEXT: %[[V5:.*]]:2 = hlfir.declare %arg2 +// CHECK-NEXT: %[[V6:.*]] = fir.load %[[V2]]#0 : !fir.ref +// CHECK-NEXT: %[[V7:.*]] = fir.convert %[[V6]] : (i32) -> i64 +// CHECK-NEXT: %[[V8:.*]] = fir.shape %c7 : (index) -> !fir.shape<1> +// CHECK-NEXT: %[[V9:.*]] = hlfir.designate %[[V1]]#0 (%[[V7]], %c1:%c7:%c1) shape %[[V8]] : (!fir.ref>, i64, index, index, index, !fir.shape<1>) -> !fir.box> +// CHECK-NEXT: %[[V10:.*]] = fir.load %[[V5]]#0 : !fir.ref +// CHECK-NEXT: %[[V11:.*]] = fir.do_loop %arg3 = %c1 to %c7 step %c1 iter_args(%arg4 = %c0_i32) -> (i32) { +// CHECK-NEXT: %[[V13:.*]] = hlfir.designate %[[V9]] (%arg3) : (!fir.box>, index) -> !fir.ref +// CHECK-NEXT: %[[V14:.*]] = fir.load %[[V13]] : !fir.ref +// CHECK-NEXT: %[[V15:.*]] = arith.cmpi sge, %[[V14]], %[[V10]] : i32 +// CHECK-NEXT: %[[V16:.*]] = arith.addi %arg4, %c1_i32 : i32 +// CHECK-NEXT: %[[V17:.*]] = arith.select %[[V15]], %[[V16]], %arg4 : i32 +// CHECK-NEXT: fir.result %[[V17]] : i32 +// CHECK-NEXT: } +// CHECK-NEXT: hlfir.assign %[[V11]] to %[[V4]]#0 : i32, !fir.ref +// CHECK-NEXT: %[[V12:.*]] = fir.load %[[V4]]#1 : !fir.ref +// CHECK-NEXT: return %[[V12]] : i32 + +func.func @_QFPtest_kind2(%arg0: !fir.ref> {fir.bindc_name = "b"}, %arg1: !fir.ref {fir.bindc_name = "row"}, %arg2: !fir.ref {fir.bindc_name = "val"}) -> i16 { + %c1 = arith.constant 1 : index + %c4 = arith.constant 4 : index + %c7 = arith.constant 7 : index + %0 = fir.shape %c4, %c7 : (index, index) -> !fir.shape<2> + %1:2 = hlfir.declare %arg0(%0) {uniq_name = "_QFFtestEb"} : (!fir.ref>, !fir.shape<2>) -> (!fir.ref>, !fir.ref>) + %2:2 = hlfir.declare %arg1 {uniq_name = "_QFFtestErow"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %3 = fir.alloca i16 {bindc_name = "test", uniq_name = "_QFFtestEtest"} + %4:2 = hlfir.declare %3 {uniq_name = "_QFFtestEtest"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %5:2 = hlfir.declare %arg2 {uniq_name = "_QFFtestEval"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %6 = fir.load %2#0 : !fir.ref + %7 = fir.convert %6 : (i32) -> i64 + %8 = fir.shape %c7 : (index) -> !fir.shape<1> + %9 = hlfir.designate %1#0 (%7, %c1:%c7:%c1) shape %8 : (!fir.ref>, i64, index, index, index, !fir.shape<1>) -> !fir.box> + %10 = fir.load %5#0 : !fir.ref + %11 = hlfir.elemental %8 unordered : (!fir.shape<1>) -> !hlfir.expr<7x!fir.logical<4>> { + ^bb0(%arg3: index): + %14 = hlfir.designate %9 (%arg3) : (!fir.box>, index) -> !fir.ref + %15 = fir.load %14 : !fir.ref + %16 = arith.cmpi sge, %15, %10 : i32 + %17 = fir.convert %16 : (i1) -> !fir.logical<4> + hlfir.yield_element %17 : !fir.logical<4> + } + %12 = hlfir.count %11 : (!hlfir.expr<7x!fir.logical<4>>) -> i16 + hlfir.assign %12 to %4#0 : i16, !fir.ref + hlfir.destroy %11 : !hlfir.expr<7x!fir.logical<4>> + %13 = fir.load %4#1 : !fir.ref + return %13 : i16 +} +// CHECK-LABEL: func.func @_QFPtest_kind2(%arg0: !fir.ref> {fir.bindc_name = "b"}, %arg1: !fir.ref {fir.bindc_name = "row"}, %arg2: !fir.ref {fir.bindc_name = "val"}) -> i16 { +// CHECK-NEXT: %c1_i16 = arith.constant 1 : i16 +// CHECK-NEXT: %c0_i16 = arith.constant 0 : i16 +// CHECK-NEXT: %c1 = arith.constant 1 : index +// CHECK-NEXT: %c4 = arith.constant 4 : index +// CHECK-NEXT: %c7 = arith.constant 7 : index +// CHECK-NEXT: %[[V0:.*]] = fir.shape %c4, %c7 : (index, index) -> !fir.shape<2> +// CHECK-NEXT: %[[V1:.*]]:2 = hlfir.declare %arg0(%[[V0]]) +// CHECK-NEXT: %[[V2:.*]]:2 = hlfir.declare %arg1 +// CHECK-NEXT: %[[V3:.*]] = fir.alloca i16 +// CHECK-NEXT: %[[V4:.*]]:2 = hlfir.declare %[[V3]] +// CHECK-NEXT: %[[V5:.*]]:2 = hlfir.declare %arg2 +// CHECK-NEXT: %[[V6:.*]] = fir.load %[[V2]]#0 : !fir.ref +// CHECK-NEXT: %[[V7:.*]] = fir.convert %[[V6]] : (i32) -> i64 +// CHECK-NEXT: %[[V8:.*]] = fir.shape %c7 : (index) -> !fir.shape<1> +// CHECK-NEXT: %[[V9:.*]] = hlfir.designate %[[V1]]#0 (%[[V7]], %c1:%c7:%c1) shape %[[V8]] : (!fir.ref>, i64, index, index, index, !fir.shape<1>) -> !fir.box> +// CHECK-NEXT: %[[V10:.*]] = fir.load %[[V5]]#0 : !fir.ref +// CHECK-NEXT: %[[V11:.*]] = fir.do_loop %arg3 = %c1 to %c7 step %c1 iter_args(%arg4 = %c0_i16) -> (i16) { +// CHECK-NEXT: %[[V13:.*]] = hlfir.designate %[[V9]] (%arg3) : (!fir.box>, index) -> !fir.ref +// CHECK-NEXT: %[[V14:.*]] = fir.load %[[V13]] : !fir.ref +// CHECK-NEXT: %[[V15:.*]] = arith.cmpi sge, %[[V14]], %[[V10]] : i32 +// CHECK-NEXT: %[[V16:.*]] = arith.addi %arg4, %c1_i16 : i16 +// CHECK-NEXT: %[[V17:.*]] = arith.select %[[V15]], %[[V16]], %arg4 : i16 +// CHECK-NEXT: fir.result %[[V17]] : i16 +// CHECK-NEXT: } +// CHECK-NEXT: hlfir.assign %[[V11]] to %[[V4]]#0 : i16, !fir.ref +// CHECK-NEXT: %[[V12:.*]] = fir.load %[[V4]]#1 : !fir.ref +// CHECK-NEXT: return %[[V12]] : i16 + +func.func @_QFPtest_dim(%arg0: !fir.ref> {fir.bindc_name = "b"}, %arg1: !fir.ref {fir.bindc_name = "row"}, %arg2: !fir.ref {fir.bindc_name = "val"}) -> !fir.array<7xi32> { + %c1_i32 = arith.constant 1 : i32 + %c1 = arith.constant 1 : index + %c4 = arith.constant 4 : index + %c7 = arith.constant 7 : index + %0 = fir.shape %c4, %c7 : (index, index) -> !fir.shape<2> + %1:2 = hlfir.declare %arg0(%0) {uniq_name = "_QFFtestEb"} : (!fir.ref>, !fir.shape<2>) -> (!fir.ref>, !fir.ref>) + %2:2 = hlfir.declare %arg1 {uniq_name = "_QFFtestErow"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %3 = fir.alloca !fir.array<7xi32> {bindc_name = "test", uniq_name = "_QFFtestEtest"} + %4 = fir.shape %c7 : (index) -> !fir.shape<1> + %5:2 = hlfir.declare %3(%4) {uniq_name = "_QFFtestEtest"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) + %6:2 = hlfir.declare %arg2 {uniq_name = "_QFFtestEval"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %7 = hlfir.designate %1#0 (%c1:%c4:%c1, %c1:%c7:%c1) shape %0 : (!fir.ref>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.ref> + %8 = fir.load %6#0 : !fir.ref + %9 = hlfir.elemental %0 unordered : (!fir.shape<2>) -> !hlfir.expr<4x7x!fir.logical<4>> { + ^bb0(%arg3: index, %arg4: index): + %12 = hlfir.designate %7 (%arg3, %arg4) : (!fir.ref>, index, index) -> !fir.ref + %13 = fir.load %12 : !fir.ref + %14 = arith.cmpi sge, %13, %8 : i32 + %15 = fir.convert %14 : (i1) -> !fir.logical<4> + hlfir.yield_element %15 : !fir.logical<4> + } + %10 = hlfir.count %9 dim %c1_i32 : (!hlfir.expr<4x7x!fir.logical<4>>, i32) -> !hlfir.expr<7xi32> + hlfir.assign %10 to %5#0 : !hlfir.expr<7xi32>, !fir.ref> + hlfir.destroy %10 : !hlfir.expr<7xi32> + hlfir.destroy %9 : !hlfir.expr<4x7x!fir.logical<4>> + %11 = fir.load %5#1 : !fir.ref> + return %11 : !fir.array<7xi32> +} +// CHECK-LABEL: func.func @_QFPtest_dim( +// CHECK: %{{.*}} = hlfir.count %{{.*}} dim %c1_i32 + + +func.func @_QFPtest_multi(%arg0: !fir.ref> {fir.bindc_name = "b"}, %arg1: !fir.ref {fir.bindc_name = "row"}, %arg2: !fir.ref {fir.bindc_name = "val"}) -> i32 { + %c1 = arith.constant 1 : index + %c4 = arith.constant 4 : index + %c7 = arith.constant 7 : index + %c2 = arith.constant 2 : index + %0 = fir.shape %c4, %c7, %c2 : (index, index, index) -> !fir.shape<3> + %1:2 = hlfir.declare %arg0(%0) {uniq_name = "_QFFtestEb"} : (!fir.ref>, !fir.shape<3>) -> (!fir.ref>, !fir.ref>) + %2:2 = hlfir.declare %arg1 {uniq_name = "_QFFtestErow"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %3 = fir.alloca i32 {bindc_name = "test", uniq_name = "_QFFtestEtest"} + %4:2 = hlfir.declare %3 {uniq_name = "_QFFtestEtest"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %5:2 = hlfir.declare %arg2 {uniq_name = "_QFFtestEval"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %6 = hlfir.designate %1#0 (%c1:%c4:%c1, %c1:%c7:%c1, %c1:%c2:%c1) shape %0 : (!fir.ref>, index, index, index, index, index, index, index, index, index, !fir.shape<3>) -> !fir.ref> + %7 = fir.load %5#0 : !fir.ref + %8 = hlfir.elemental %0 unordered : (!fir.shape<3>) -> !hlfir.expr<4x7x2x!fir.logical<4>> { + ^bb0(%arg3: index, %arg4: index, %arg5: index): + %11 = hlfir.designate %6 (%arg3, %arg4, %arg5) : (!fir.ref>, index, index, index) -> !fir.ref + %12 = fir.load %11 : !fir.ref + %13 = arith.cmpi sge, %12, %7 : i32 + %14 = fir.convert %13 : (i1) -> !fir.logical<4> + hlfir.yield_element %14 : !fir.logical<4> + } + %9 = hlfir.count %8 : (!hlfir.expr<4x7x2x!fir.logical<4>>) -> i32 + hlfir.assign %9 to %4#0 : i32, !fir.ref + hlfir.destroy %8 : !hlfir.expr<4x7x2x!fir.logical<4>> + %10 = fir.load %4#1 : !fir.ref + return %10 : i32 +} +// CHECK-LABEL: func.func @_QFPtest_multi(%arg0: !fir.ref> {fir.bindc_name = "b"}, %arg1: !fir.ref {fir.bindc_name = "row"}, %arg2: !fir.ref {fir.bindc_name = "val"}) -> i32 { +// CHECK-NEXT: %c1_i32 = arith.constant 1 : i32 +// CHECK-NEXT: %c0_i32 = arith.constant 0 : i32 +// CHECK-NEXT: %c1 = arith.constant 1 : index +// CHECK-NEXT: %c4 = arith.constant 4 : index +// CHECK-NEXT: %c7 = arith.constant 7 : index +// CHECK-NEXT: %c2 = arith.constant 2 : index +// CHECK-NEXT: %[[V0:.*]] = fir.shape %c4, %c7, %c2 : (index, index, index) -> !fir.shape<3> +// CHECK-NEXT: %[[V1:.*]]:2 = hlfir.declare %arg0(%[[V0]]) {uniq_name = "_QFFtestEb"} : (!fir.ref>, !fir.shape<3>) -> (!fir.ref>, !fir.ref>) +// CHECK-NEXT: %[[V2:.*]]:2 = hlfir.declare %arg1 {uniq_name = "_QFFtestErow"} : (!fir.ref) -> (!fir.ref, !fir.ref) +// CHECK-NEXT: %[[V3:.*]] = fir.alloca i32 {bindc_name = "test", uniq_name = "_QFFtestEtest"} +// CHECK-NEXT: %[[V4:.*]]:2 = hlfir.declare %[[V3]] {uniq_name = "_QFFtestEtest"} : (!fir.ref) -> (!fir.ref, !fir.ref) +// CHECK-NEXT: %[[V5:.*]]:2 = hlfir.declare %arg2 {uniq_name = "_QFFtestEval"} : (!fir.ref) -> (!fir.ref, !fir.ref) +// CHECK-NEXT: %[[V6:.*]] = hlfir.designate %[[V1]]#0 (%c1:%c4:%c1, %c1:%c7:%c1, %c1:%c2:%c1) shape %[[V0]] : (!fir.ref>, index, index, index, index, index, index, index, index, index, !fir.shape<3>) -> !fir.ref> +// CHECK-NEXT: %[[V7:.*]] = fir.load %[[V5]]#0 : !fir.ref +// CHECK-NEXT: %[[V8:.*]] = fir.do_loop %arg3 = %c1 to %c2 step %c1 iter_args(%arg4 = %c0_i32) -> (i32) { +// CHECK-NEXT: %[[V10:.*]] = fir.do_loop %arg5 = %c1 to %c7 step %c1 iter_args(%arg6 = %arg4) -> (i32) { +// CHECK-NEXT: %[[V11:.*]] = fir.do_loop %arg7 = %c1 to %c4 step %c1 iter_args(%arg8 = %arg6) -> (i32) { +// CHECK-NEXT: %[[V12:.*]] = hlfir.designate %[[V6]] (%arg7, %arg5, %arg3) : (!fir.ref>, index, index, index) -> !fir.ref +// CHECK-NEXT: %[[V13:.*]] = fir.load %[[V12]] : !fir.ref +// CHECK-NEXT: %[[V14:.*]] = arith.cmpi sge, %[[V13]], %[[V7]] : i32 +// CHECK-NEXT: %[[V15:.*]] = arith.addi %arg8, %c1_i32 : i32 +// CHECK-NEXT: %[[V16:.*]] = arith.select %[[V14]], %[[V15]], %arg8 : i32 +// CHECK-NEXT: fir.result %[[V16]] : i32 +// CHECK-NEXT: } +// CHECK-NEXT: fir.result %[[V11]] : i32 +// CHECK-NEXT: } +// CHECK-NEXT: fir.result %[[V10]] : i32 +// CHECK-NEXT: } +// CHECK-NEXT: hlfir.assign %[[V8]] to %[[V4]]#0 : i32, !fir.ref +// CHECK-NEXT: %[[V9:.*]] = fir.load %[[V4]]#1 : !fir.ref +// CHECK-NEXT: return %[[V9]] : i32 + + + + + +func.func @_QFPtest_rec_sum(%arg0: !fir.ref> {fir.bindc_name = "b"}, %arg1: !fir.ref {fir.bindc_name = "row"}, %arg2: !fir.ref {fir.bindc_name = "val"}) -> i32 { + %c1 = arith.constant 1 : index + %c4 = arith.constant 4 : index + %c7 = arith.constant 7 : index + %0 = fir.shape %c4, %c7 : (index, index) -> !fir.shape<2> + %1:2 = hlfir.declare %arg0(%0) {uniq_name = "_QFFtestEb"} : (!fir.ref>, !fir.shape<2>) -> (!fir.ref>, !fir.ref>) + %2:2 = hlfir.declare %arg1 {uniq_name = "_QFFtestErow"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %3 = fir.alloca i32 {bindc_name = "test", uniq_name = "_QFFtestEtest"} + %4:2 = hlfir.declare %3 {uniq_name = "_QFFtestEtest"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %5:2 = hlfir.declare %arg2 {uniq_name = "_QFFtestEval"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %6 = fir.load %2#0 : !fir.ref + %7 = fir.convert %6 : (i32) -> i64 + %8 = fir.shape %c7 : (index) -> !fir.shape<1> + %9 = hlfir.designate %1#0 (%7, %c1:%c7:%c1) shape %8 : (!fir.ref>, i64, index, index, index, !fir.shape<1>) -> !fir.box> + %10 = fir.load %5#0 : !fir.ref + %11 = hlfir.elemental %8 unordered : (!fir.shape<1>) -> !hlfir.expr<7xi32> { + ^bb0(%arg3: index): + %15 = hlfir.designate %9 (%arg3) : (!fir.box>, index) -> !fir.ref + %16 = fir.load %15 : !fir.ref + hlfir.yield_element %16 : i32 + } + %12 = hlfir.elemental %8 unordered : (!fir.shape<1>) -> !hlfir.expr<7x!fir.logical<4>> { + ^bb0(%arg3: index): + %15 = hlfir.sum %11 : (!hlfir.expr<7xi32>) -> i32 + %16 = arith.cmpi sge, %15, %10 : i32 + %17 = fir.convert %16 : (i1) -> !fir.logical<4> + hlfir.yield_element %17 : !fir.logical<4> + } + %13 = hlfir.count %12 : (!hlfir.expr<7x!fir.logical<4>>) -> i32 + hlfir.assign %13 to %4#0 : i32, !fir.ref + hlfir.destroy %12 : !hlfir.expr<7x!fir.logical<4>> + hlfir.destroy %11 : !hlfir.expr<7xi32> + %14 = fir.load %4#1 : !fir.ref + return %14 : i32 +} +// CHECK-LABEL: func.func @_QFPtest_rec_sum(%arg0: !fir.ref> {fir.bindc_name = "b"}, %arg1: !fir.ref {fir.bindc_name = "row"}, %arg2: !fir.ref {fir.bindc_name = "val"}) -> i32 { +// CHECK: %[[V12:.*]] = fir.do_loop %arg3 = %c1 to %c7 step %c1 iter_args(%arg4 = %c0_i32) -> (i32) { +// CHECK: %[[V14:.*]] = hlfir.sum %[[V11]] : (!hlfir.expr<7xi32>) -> i32 +// CHECK: %[[V15:.*]] = arith.cmpi sge, %[[V14]], %[[V10]] : i32 +// CHECK: %[[V16:.*]] = arith.addi %arg4, %c1_i32 : i32 +// CHECK: %[[V17:.*]] = arith.select %[[V15]], %[[V16]], %arg4 : i32 +// CHECK: fir.result %[[V17]] : i32 +// CHECK: } + + + + +func.func @_QFPtest_rec_count(%arg0: !fir.ref> {fir.bindc_name = "b"}, %arg1: !fir.ref {fir.bindc_name = "row"}, %arg2: !fir.ref {fir.bindc_name = "val"}) -> i32 { + %c1 = arith.constant 1 : index + %c4 = arith.constant 4 : index + %c7 = arith.constant 7 : index + %0 = fir.shape %c4, %c7 : (index, index) -> !fir.shape<2> + %1:2 = hlfir.declare %arg0(%0) {uniq_name = "_QFFtestEb"} : (!fir.ref>, !fir.shape<2>) -> (!fir.ref>, !fir.ref>) + %2:2 = hlfir.declare %arg1 {uniq_name = "_QFFtestErow"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %3 = fir.alloca i32 {bindc_name = "test", uniq_name = "_QFFtestEtest"} + %4:2 = hlfir.declare %3 {uniq_name = "_QFFtestEtest"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %5:2 = hlfir.declare %arg2 {uniq_name = "_QFFtestEval"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %6 = fir.load %2#0 : !fir.ref + %7 = fir.convert %6 : (i32) -> i64 + %8 = fir.shape %c7 : (index) -> !fir.shape<1> + %9 = hlfir.designate %1#0 (%7, %c1:%c7:%c1) shape %8 : (!fir.ref>, i64, index, index, index, !fir.shape<1>) -> !fir.box> + %10 = fir.load %5#0 : !fir.ref + %11 = hlfir.elemental %8 unordered : (!fir.shape<1>) -> !hlfir.expr<7x!fir.logical<4>> { + ^bb0(%arg3: index): + %15 = hlfir.designate %9 (%arg3) : (!fir.box>, index) -> !fir.ref + %16 = fir.load %15 : !fir.ref + %17 = arith.cmpi sge, %16, %10 : i32 + %18 = fir.convert %17 : (i1) -> !fir.logical<4> + hlfir.yield_element %18 : !fir.logical<4> + } + %12 = hlfir.elemental %8 unordered : (!fir.shape<1>) -> !hlfir.expr<7x!fir.logical<4>> { + ^bb0(%arg3: index): + %15 = hlfir.count %11 : (!hlfir.expr<7x!fir.logical<4>>) -> i32 + %16 = arith.cmpi sge, %15, %10 : i32 + %17 = fir.convert %16 : (i1) -> !fir.logical<4> + hlfir.yield_element %17 : !fir.logical<4> + } + %13 = hlfir.count %12 : (!hlfir.expr<7x!fir.logical<4>>) -> i32 + hlfir.assign %13 to %4#0 : i32, !fir.ref + hlfir.destroy %12 : !hlfir.expr<7x!fir.logical<4>> + hlfir.destroy %11 : !hlfir.expr<7x!fir.logical<4>> + %14 = fir.load %4#1 : !fir.ref + return %14 : i32 +} +// CHECK-LABEL: func.func @_QFPtest_rec_count(%arg0: !fir.ref> {fir.bindc_name = "b"}, %arg1: !fir.ref {fir.bindc_name = "row"}, %arg2: !fir.ref {fir.bindc_name = "val"}) -> i32 { +// CHECK: %[[V11:.*]] = fir.do_loop %arg3 = %c1 to %c7 step %c1 iter_args(%arg4 = %c0_i32) -> (i32) { +// CHECK: %[[V13:.*]] = fir.do_loop %arg5 = %c1 to %c7 step %c1 iter_args(%arg6 = %c0_i32) -> (i32) { +// CHECK: %[[V17:.*]] = hlfir.designate %[[V9]] (%arg5) : (!fir.box>, index) -> !fir.ref +// CHECK: %[[V18:.*]] = fir.load %[[V17]] : !fir.ref +// CHECK: %[[V19:.*]] = arith.cmpi sge, %[[V18]], %[[V10]] : i32 +// CHECK: %[[V20:.*]] = arith.addi %arg6, %c1_i32 : i32 +// CHECK: %[[V21:.*]] = arith.select %[[V19]], %[[V20]], %arg6 : i32 +// CHECK: fir.result %[[V21]] : i32 +// CHECK: } +// CHECK: %[[V14:.*]] = arith.cmpi sge, %[[V13]], %[[V10]] : i32 +// CHECK: %[[V15:.*]] = arith.addi %arg4, %c1_i32 : i32 +// CHECK: %[[V16:.*]] = arith.select %[[V14]], %[[V15]], %arg4 : i32 +// CHECK: fir.result %[[V16]] : i32 +// CHECK: } diff --git a/flang/test/HLFIR/maxloc-elemental.fir b/flang/test/HLFIR/maxloc-elemental.fir new file mode 100644 index 0000000000000..c9210a59f0340 --- /dev/null +++ b/flang/test/HLFIR/maxloc-elemental.fir @@ -0,0 +1,133 @@ +// RUN: fir-opt %s -opt-bufferization | FileCheck %s + +func.func @_QPtest(%arg0: !fir.box> {fir.bindc_name = "array"}, %arg1: !fir.ref {fir.bindc_name = "val"}, %arg2: !fir.box> {fir.bindc_name = "m"}) { + %c0 = arith.constant 0 : index + %0:2 = hlfir.declare %arg0 {uniq_name = "_QFtestEarray"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %1:2 = hlfir.declare %arg2 {uniq_name = "_QFtestEm"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %2:2 = hlfir.declare %arg1 {uniq_name = "_QFtestEval"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %3 = fir.load %2#0 : !fir.ref + %4:3 = fir.box_dims %0#0, %c0 : (!fir.box>, index) -> (index, index, index) + %5 = fir.shape %4#1 : (index) -> !fir.shape<1> + %6 = hlfir.elemental %5 unordered : (!fir.shape<1>) -> !hlfir.expr> { + ^bb0(%arg3: index): + %8 = hlfir.designate %0#0 (%arg3) : (!fir.box>, index) -> !fir.ref + %9 = fir.load %8 : !fir.ref + %10 = arith.cmpi sge, %9, %3 : i32 + %11 = fir.convert %10 : (i1) -> !fir.logical<4> + hlfir.yield_element %11 : !fir.logical<4> + } + %7 = hlfir.maxloc %0#0 mask %6 {fastmath = #arith.fastmath} : (!fir.box>, !hlfir.expr>) -> !hlfir.expr<1xi32> + hlfir.assign %7 to %1#0 : !hlfir.expr<1xi32>, !fir.box> + hlfir.destroy %7 : !hlfir.expr<1xi32> + hlfir.destroy %6 : !hlfir.expr> + return +} +// CHECK-LABEL: func.func @_QPtest(%arg0: !fir.box> {fir.bindc_name = "array"}, %arg1: !fir.ref {fir.bindc_name = "val"}, %arg2: !fir.box> {fir.bindc_name = "m"}) { +// CHECK-NEXT: %true = arith.constant true +// CHECK-NEXT: %c-2147483648_i32 = arith.constant -2147483648 : i32 +// CHECK-NEXT: %c1_i32 = arith.constant 1 : i32 +// CHECK-NEXT: %c0 = arith.constant 0 : index +// CHECK-NEXT: %c1 = arith.constant 1 : index +// CHECK-NEXT: %c0_i32 = arith.constant 0 : i32 +// CHECK-NEXT: %[[V0:.*]] = fir.alloca i32 +// CHECK-NEXT: %[[RES:.*]] = fir.alloca !fir.array<1xi32> +// CHECK-NEXT: %[[V1:.*]]:2 = hlfir.declare %arg0 {uniq_name = "_QFtestEarray"} : (!fir.box>) -> (!fir.box>, !fir.box>) +// CHECK-NEXT: %[[V2:.*]]:2 = hlfir.declare %arg2 {uniq_name = "_QFtestEm"} : (!fir.box>) -> (!fir.box>, !fir.box>) +// CHECK-NEXT: %[[V3:.*]]:2 = hlfir.declare %arg1 {uniq_name = "_QFtestEval"} : (!fir.ref) -> (!fir.ref, !fir.ref) +// CHECK-NEXT: %[[V4:.*]] = fir.load %[[V3]]#0 : !fir.ref +// CHECK-NEXT: %[[V8:.*]] = hlfir.designate %[[RES]] (%c1) : (!fir.ref>, index) -> !fir.ref +// CHECK-NEXT: fir.store %c0_i32 to %[[V8]] : !fir.ref +// CHECK-NEXT: fir.store %c0_i32 to %[[V0]] : !fir.ref +// CHECK-NEXT: %[[V9:.*]]:3 = fir.box_dims %[[V1]]#0, %c0 : (!fir.box>, index) -> (index, index, index) +// CHECK-NEXT: %[[V10:.*]] = arith.subi %[[V9]]#1, %c1 : index +// CHECK-NEXT: %[[V11:.*]] = fir.do_loop %arg3 = %c0 to %[[V10]] step %c1 iter_args(%arg4 = %c-2147483648_i32) -> (i32) { +// CHECK-NEXT: %[[V14:.*]] = arith.addi %arg3, %c1 : index +// CHECK-NEXT: %[[V15:.*]] = hlfir.designate %[[V1]]#0 (%[[V14]]) : (!fir.box>, index) -> !fir.ref +// CHECK-NEXT: %[[V16:.*]] = fir.load %[[V15]] : !fir.ref +// CHECK-NEXT: %[[V17:.*]] = arith.cmpi sge, %[[V16]], %[[V4]] : i32 +// CHECK-NEXT: %[[V18:.*]] = fir.if %[[V17]] -> (i32) { +// CHECK-NEXT: %[[ISFIRST:.*]] = fir.load %[[V0]] : !fir.ref +// CHECK-NEXT: %[[V19:.*]] = hlfir.designate %[[V1]]#0 (%[[V14]]) : (!fir.box>, index) -> !fir.ref +// CHECK-NEXT: %[[V20:.*]] = fir.load %[[V19]] : !fir.ref +// CHECK-NEXT: %[[V21:.*]] = arith.cmpi sgt, %[[V20]], %arg4 : i32 +// CHECK-NEXT: %[[ISFIRSTL:.*]] = fir.convert %[[ISFIRST]] : (i32) -> i1 +// CHECK-NEXT: %[[ISFIRSTNOT:.*]] = arith.xori %[[ISFIRSTL]], %true : i1 +// CHECK-NEXT: %[[ORCOND:.*]] = arith.ori %[[V21]], %[[ISFIRSTNOT]] : i1 +// CHECK-NEXT: %[[V22:.*]] = fir.if %[[ORCOND]] -> (i32) { +// CHECK-NEXT: fir.store %c1_i32 to %[[V0]] : !fir.ref +// CHECK-NEXT: %[[V23:.*]] = hlfir.designate %[[RES]] (%c1) : (!fir.ref>, index) -> !fir.ref +// CHECK-NEXT: %[[V24:.*]] = fir.convert %[[V14]] : (index) -> i32 +// CHECK-NEXT: fir.store %[[V24]] to %[[V23]] : !fir.ref +// CHECK-NEXT: fir.result %[[V20]] : i32 +// CHECK-NEXT: } else { +// CHECK-NEXT: fir.result %arg4 : i32 +// CHECK-NEXT: } +// CHECK-NEXT: fir.result %[[V22]] : i32 +// CHECK-NEXT: } else { +// CHECK-NEXT: fir.result %arg4 : i32 +// CHECK-NEXT: } +// CHECK-NEXT: fir.result %[[V18]] : i32 +// CHECK-NEXT: } +// CHECK-NEXT: hlfir.assign %[[RES]] to %[[V2]]#0 : !fir.ref>, !fir.box> +// CHECK-NEXT: return +// CHECK-NEXT: } + + + +func.func @_QPtest_float(%arg0: !fir.box> {fir.bindc_name = "array"}, %arg1: !fir.ref {fir.bindc_name = "val"}, %arg2: !fir.box> {fir.bindc_name = "m"}) { + %c0 = arith.constant 0 : index + %0:2 = hlfir.declare %arg0 {uniq_name = "_QFtestEarray"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %1:2 = hlfir.declare %arg2 {uniq_name = "_QFtestEm"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %2:2 = hlfir.declare %arg1 {uniq_name = "_QFtestEval"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %3 = fir.load %2#0 : !fir.ref + %4:3 = fir.box_dims %0#0, %c0 : (!fir.box>, index) -> (index, index, index) + %5 = fir.shape %4#1 : (index) -> !fir.shape<1> + %6 = hlfir.elemental %5 unordered : (!fir.shape<1>) -> !hlfir.expr> { + ^bb0(%arg3: index): + %8 = hlfir.designate %0#0 (%arg3) : (!fir.box>, index) -> !fir.ref + %9 = fir.load %8 : !fir.ref + %10 = arith.cmpf oge, %9, %3 : f32 + %11 = fir.convert %10 : (i1) -> !fir.logical<4> + hlfir.yield_element %11 : !fir.logical<4> + } + %7 = hlfir.maxloc %0#0 mask %6 {fastmath = #arith.fastmath} : (!fir.box>, !hlfir.expr>) -> !hlfir.expr<1xi32> + hlfir.assign %7 to %1#0 : !hlfir.expr<1xi32>, !fir.box> + hlfir.destroy %7 : !hlfir.expr<1xi32> + hlfir.destroy %6 : !hlfir.expr> + return +} +// CHECK-LABEL: _QPtest_float +// CHECK: %cst = arith.constant 0xFF800000 : f32 +// CHECK: %[[V11:.*]] = fir.do_loop %arg3 = %c0 to %[[V10:.*]] step %c1 iter_args(%arg4 = %cst) -> (f32) { +// CHECK-NEXT: %[[V14:.*]] = arith.addi %arg3, %c1 : index +// CHECK-NEXT: %[[V15:.*]] = hlfir.designate %[[V1:.*]]#0 (%[[V14]]) : (!fir.box>, index) -> !fir.ref +// CHECK-NEXT: %[[V16:.*]] = fir.load %[[V15]] : !fir.ref +// CHECK-NEXT: %[[V17:.*]] = arith.cmpf oge, %[[V16]], %[[V4:.*]] : f32 +// CHECK-NEXT: %[[V18:.*]] = fir.if %[[V17]] -> (f32) { +// CHECK-NEXT: %[[ISFIRST:.*]] = fir.load %[[V0:.*]] : !fir.ref +// CHECK-NEXT: %[[V19:.*]] = hlfir.designate %[[V1]]#0 (%[[V14]]) : (!fir.box>, index) -> !fir.ref +// CHECK-NEXT: %[[V20:.*]] = fir.load %[[V19]] : !fir.ref +// CHECK-NEXT: %[[NEW_MIN:.*]] = arith.cmpf ogt, %[[V20]], %arg4 fastmath : f32 +// CHECK-NEXT: %[[CONDRED:.*]] = arith.cmpf une, %arg4, %arg4 fastmath : f32 +// CHECK-NEXT: %[[CONDELEM:.*]] = arith.cmpf oeq, %[[V20]], %[[V20]] fastmath : f32 +// CHECK-NEXT: %[[ANDCOND:.*]] = arith.andi %[[CONDRED]], %[[CONDELEM]] : i1 +// CHECK-NEXT: %[[NEW_MIN2:.*]] = arith.ori %[[NEW_MIN]], %[[ANDCOND]] : i1 +// CHECK-NEXT: %[[ISFIRSTL:.*]] = fir.convert %[[ISFIRST]] : (i32) -> i1 +// CHECK-NEXT: %[[ISFIRSTNOT:.*]] = arith.xori %[[ISFIRSTL]], %true : i1 +// CHECK-NEXT: %[[ORCOND:.*]] = arith.ori %[[NEW_MIN2]], %[[ISFIRSTNOT]] : i1 +// CHECK-NEXT: %[[V22:.*]] = fir.if %[[ORCOND]] -> (f32) { +// CHECK-NEXT: fir.store %c1_i32 to %[[V0]] : !fir.ref +// CHECK-NEXT: %[[V23:.*]] = hlfir.designate %{{.}} (%c1) : (!fir.ref>, index) -> !fir.ref +// CHECK-NEXT: %[[V24:.*]] = fir.convert %[[V14]] : (index) -> i32 +// CHECK-NEXT: fir.store %[[V24]] to %[[V23]] : !fir.ref +// CHECK-NEXT: fir.result %[[V20]] : f32 +// CHECK-NEXT: } else { +// CHECK-NEXT: fir.result %arg4 : f32 +// CHECK-NEXT: } +// CHECK-NEXT: fir.result %[[V22]] : f32 +// CHECK-NEXT: } else { +// CHECK-NEXT: fir.result %arg4 : f32 +// CHECK-NEXT: } +// CHECK-NEXT: fir.result %[[V18]] : f32 +// CHECK-NEXT: } + diff --git a/flang/test/HLFIR/maxval-elemental.fir b/flang/test/HLFIR/maxval-elemental.fir new file mode 100644 index 0000000000000..a21b4858412de --- /dev/null +++ b/flang/test/HLFIR/maxval-elemental.fir @@ -0,0 +1,117 @@ +// Test maxval inlining for both elemental and designate +// RUN: fir-opt %s -opt-bufferization | FileCheck %s + +// subroutine test(array) +// integer :: array(:), x +// x = maxval(abs(array)) +// end subroutine test + +func.func @_QPtest(%arg0: !fir.box> {fir.bindc_name = "array"}) { + %c31_i32 = arith.constant 31 : i32 + %c0 = arith.constant 0 : index + %0 = fir.dummy_scope : !fir.dscope + %1:2 = hlfir.declare %arg0 dummy_scope %0 {uniq_name = "_QFtestEarray"} : (!fir.box>, !fir.dscope) -> (!fir.box>, !fir.box>) + %2 = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFtestEx"} + %3:2 = hlfir.declare %2 {uniq_name = "_QFtestEx"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %4:3 = fir.box_dims %1#0, %c0 : (!fir.box>, index) -> (index, index, index) + %5 = fir.shape %4#1 : (index) -> !fir.shape<1> + %6 = hlfir.elemental %5 unordered : (!fir.shape<1>) -> !hlfir.expr { + ^bb0(%arg1: index): + %8 = hlfir.designate %1#0 (%arg1) : (!fir.box>, index) -> !fir.ref + %9 = fir.load %8 : !fir.ref + %10 = arith.shrsi %9, %c31_i32 : i32 + %11 = arith.xori %9, %10 : i32 + %12 = arith.subi %11, %10 : i32 + hlfir.yield_element %12 : i32 + } + %7 = hlfir.maxval %6 {fastmath = #arith.fastmath} : (!hlfir.expr) -> i32 + hlfir.assign %7 to %3#0 : i32, !fir.ref + hlfir.destroy %6 : !hlfir.expr + return +} + +// CHECK-LABEL: func.func @_QPtest(%arg0: !fir.box> {fir.bindc_name = "array"}) { +// CHECK-NEXT: %c1 = arith.constant 1 : index +// CHECK-NEXT: %c-2147483648_i32 = arith.constant -2147483648 : i32 +// CHECK-NEXT: %c31_i32 = arith.constant 31 : i32 +// CHECK-NEXT: %c0 = arith.constant 0 : index +// CHECK-NEXT: %[[V0:.*]] = fir.dummy_scope : !fir.dscope +// CHECK-NEXT: %[[V1:.*]]:2 = hlfir.declare %arg0 dummy_scope %[[V0]] {uniq_name = "_QFtestEarray"} : (!fir.box>, !fir.dscope) -> (!fir.box>, !fir.box>) +// CHECK-NEXT: %[[V2:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFtestEx"} +// CHECK-NEXT: %[[V3:.*]]:2 = hlfir.declare %[[V2]] {uniq_name = "_QFtestEx"} : (!fir.ref) -> (!fir.ref, !fir.ref) +// CHECK-NEXT: %[[V4:.*]]:3 = fir.box_dims %[[V1]]#0, %c0 : (!fir.box>, index) -> (index, index, index) +// CHECK-NEXT: %[[V5:.*]] = fir.do_loop %arg1 = %c1 to %[[V4]]#1 step %c1 iter_args(%arg2 = %c-2147483648_i32) -> (i32) { +// CHECK-NEXT: %[[V6:.*]] = hlfir.designate %[[V1]]#0 (%arg1) : (!fir.box>, index) -> !fir.ref +// CHECK-NEXT: %[[V7:.*]] = fir.load %[[V6]] : !fir.ref +// CHECK-NEXT: %[[V8:.*]] = arith.shrsi %[[V7]], %c31_i32 : i32 +// CHECK-NEXT: %[[V9:.*]] = arith.xori %[[V7]], %[[V8]] : i32 +// CHECK-NEXT: %[[V10:.*]] = arith.subi %[[V9]], %[[V8]] : i32 +// CHECK-NEXT: %[[V11:.*]] = arith.cmpi sgt, %[[V10]], %arg2 : i32 +// CHECK-NEXT: %[[V12:.*]] = arith.select %[[V11]], %[[V10]], %arg2 : i32 +// CHECK-NEXT: fir.result %[[V12]] : i32 +// CHECK-NEXT: } +// CHECK-NEXT: hlfir.assign %[[V5]] to %[[V3]]#0 : i32, !fir.ref +// CHECK-NEXT: return +// CHECK-NEXT: } + +// subroutine test(array) +// real :: array(:), x +// x = maxval(array(3:6)) +// end subroutine test + +func.func @_QPtest_float(%arg0: !fir.box> {fir.bindc_name = "array"}) { + %c4 = arith.constant 4 : index + %c1 = arith.constant 1 : index + %c6 = arith.constant 6 : index + %c3 = arith.constant 3 : index + %0 = fir.dummy_scope : !fir.dscope + %1:2 = hlfir.declare %arg0 dummy_scope %0 {uniq_name = "_QFtestEarray"} : (!fir.box>, !fir.dscope) -> (!fir.box>, !fir.box>) + %2 = fir.alloca f32 {bindc_name = "x", uniq_name = "_QFtestEx"} + %3:2 = hlfir.declare %2 {uniq_name = "_QFtestEx"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %4 = fir.shape %c4 : (index) -> !fir.shape<1> + %5 = hlfir.designate %1#0 (%c3:%c6:%c1) shape %4 : (!fir.box>, index, index, index, !fir.shape<1>) -> !fir.box> + %6 = hlfir.maxval %5 {fastmath = #arith.fastmath} : (!fir.box>) -> f32 + hlfir.assign %6 to %3#0 : f32, !fir.ref + return +} + +// CHECK-LABEL: _QPtest_float +// CHECK: %cst = arith.constant 0xFF800000 : f32 +// CHECK: %[[V4:.*]] = fir.shape %c4 : (index) -> !fir.shape<1> +// CHECK-NEXT: %[[V5:.*]] = hlfir.designate %{{.*}} (%c3:%c6:%c1) shape %[[V4]] : (!fir.box>, index, index, index, !fir.shape<1>) -> !fir.box> +// CHECK-NEXT: %[[V6:.*]] = fir.do_loop %arg1 = %c1 to %c4 step %c1 iter_args(%arg2 = %cst) -> (f32) { +// CHECK-NEXT: %[[V7:.*]] = hlfir.designate %[[V5]] (%arg1) : (!fir.box>, index) -> !fir.ref +// CHECK-NEXT: %[[V8:.*]] = fir.load %[[V7]] : !fir.ref +// CHECK-NEXT: %[[V9:.*]] = arith.cmpf ogt, %[[V8]], %arg2 fastmath : f32 +// CHECK-NEXT: %[[V10:.*]] = arith.cmpf une, %arg2, %arg2 fastmath : f32 +// CHECK-NEXT: %[[V11:.*]] = arith.cmpf oeq, %[[V8]], %[[V8]] fastmath : f32 +// CHECK-NEXT: %[[V12:.*]] = arith.andi %[[V10]], %[[V11]] : i1 +// CHECK-NEXT: %[[V13:.*]] = arith.ori %[[V9]], %[[V12]] : i1 +// CHECK-NEXT: %[[V14:.*]] = arith.select %[[V13]], %[[V8]], %arg2 : f32 +// CHECK-NEXT: fir.result %[[V14]] : f32 +// CHECK-NEXT: } +// CHECK-NEXT: hlfir.assign %[[V6]] to %3#0 : f32, !fir.ref +// CHECK-NEXT: return +// CHECK-NEXT: } + +// Verify that lower bounds of designator are applied in the indexing inside +// the generated loop (hlfir.designate takes indices relative to the base lower +// bounds). +func.func @component_lower_bounds(%arg0: !fir.ref}>>) -> i32 { + %c10 = arith.constant 10 : index + %c101 = arith.constant 101 : index + %4 = fir.shape_shift %c101, %c10 : (index, index) -> !fir.shapeshift<1> + %5 = hlfir.designate %arg0{"i"} shape %4 : (!fir.ref}>>, !fir.shapeshift<1>) -> !fir.box> + %6 = hlfir.maxval %5 : (!fir.box>) -> i32 + return %6 : i32 +} +// CHECK-LABEL: func.func @component_lower_bounds( +// CHECK: %[[VAL_1:.*]] = arith.constant 100 : index +// CHECK: %[[VAL_2:.*]] = arith.constant 1 : index +// CHECK: %[[VAL_4:.*]] = arith.constant 10 : index +// CHECK: %[[VAL_5:.*]] = arith.constant 101 : index +// CHECK: %[[VAL_6:.*]] = fir.shape_shift %[[VAL_5]], %[[VAL_4]] : (index, index) -> !fir.shapeshift<1> +// CHECK: %[[VAL_7:.*]] = hlfir.designate %{{.*}}{"i"} shape %[[VAL_6]] : (!fir.ref}>>, !fir.shapeshift<1>) -> !fir.box> +// CHECK: %[[VAL_8:.*]] = fir.do_loop %[[VAL_9:.*]] = %[[VAL_2]] to %[[VAL_4]] {{.*}} +// CHECK: %[[VAL_11:.*]] = arith.addi %[[VAL_9]], %[[VAL_1]] : index +// CHECK: hlfir.designate %[[VAL_7]] (%[[VAL_11]]) : (!fir.box>, index) -> !fir.ref diff --git a/flang/test/HLFIR/minloc-elemental.fir b/flang/test/HLFIR/minloc-elemental.fir new file mode 100644 index 0000000000000..9453a335b4fbf --- /dev/null +++ b/flang/test/HLFIR/minloc-elemental.fir @@ -0,0 +1,397 @@ +// RUN: fir-opt %s -opt-bufferization | FileCheck %s + +func.func @_QPtest(%arg0: !fir.box> {fir.bindc_name = "array"}, %arg1: !fir.ref {fir.bindc_name = "val"}, %arg2: !fir.box> {fir.bindc_name = "m"}) { + %c0 = arith.constant 0 : index + %0:2 = hlfir.declare %arg0 {uniq_name = "_QFtestEarray"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %1:2 = hlfir.declare %arg2 {uniq_name = "_QFtestEm"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %2:2 = hlfir.declare %arg1 {uniq_name = "_QFtestEval"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %3 = fir.load %2#0 : !fir.ref + %4:3 = fir.box_dims %0#0, %c0 : (!fir.box>, index) -> (index, index, index) + %5 = fir.shape %4#1 : (index) -> !fir.shape<1> + %6 = hlfir.elemental %5 unordered : (!fir.shape<1>) -> !hlfir.expr> { + ^bb0(%arg3: index): + %8 = hlfir.designate %0#0 (%arg3) : (!fir.box>, index) -> !fir.ref + %9 = fir.load %8 : !fir.ref + %10 = arith.cmpi sge, %9, %3 : i32 + %11 = fir.convert %10 : (i1) -> !fir.logical<4> + hlfir.yield_element %11 : !fir.logical<4> + } + %7 = hlfir.minloc %0#0 mask %6 {fastmath = #arith.fastmath} : (!fir.box>, !hlfir.expr>) -> !hlfir.expr<1xi32> + hlfir.assign %7 to %1#0 : !hlfir.expr<1xi32>, !fir.box> + hlfir.destroy %7 : !hlfir.expr<1xi32> + hlfir.destroy %6 : !hlfir.expr> + return +} +// CHECK-LABEL: func.func @_QPtest(%arg0: !fir.box> {fir.bindc_name = "array"}, %arg1: !fir.ref {fir.bindc_name = "val"}, %arg2: !fir.box> {fir.bindc_name = "m"}) { +// CHECK-NEXT: %true = arith.constant true +// CHECK-NEXT: %c2147483647_i32 = arith.constant 2147483647 : i32 +// CHECK-NEXT: %c1_i32 = arith.constant 1 : i32 +// CHECK-NEXT: %c0 = arith.constant 0 : index +// CHECK-NEXT: %c1 = arith.constant 1 : index +// CHECK-NEXT: %c0_i32 = arith.constant 0 : i32 +// CHECK-NEXT: %[[V0:.*]] = fir.alloca i32 +// CHECK-NEXT: %[[RES:.*]] = fir.alloca !fir.array<1xi32> +// CHECK-NEXT: %[[V1:.*]]:2 = hlfir.declare %arg0 {uniq_name = "_QFtestEarray"} : (!fir.box>) -> (!fir.box>, !fir.box>) +// CHECK-NEXT: %[[V2:.*]]:2 = hlfir.declare %arg2 {uniq_name = "_QFtestEm"} : (!fir.box>) -> (!fir.box>, !fir.box>) +// CHECK-NEXT: %[[V3:.*]]:2 = hlfir.declare %arg1 {uniq_name = "_QFtestEval"} : (!fir.ref) -> (!fir.ref, !fir.ref) +// CHECK-NEXT: %[[V4:.*]] = fir.load %[[V3]]#0 : !fir.ref +// CHECK-NEXT: %[[V8:.*]] = hlfir.designate %[[RES]] (%c1) : (!fir.ref>, index) -> !fir.ref +// CHECK-NEXT: fir.store %c0_i32 to %[[V8]] : !fir.ref +// CHECK-NEXT: fir.store %c0_i32 to %[[V0]] : !fir.ref +// CHECK-NEXT: %[[V9:.*]]:3 = fir.box_dims %[[V1]]#0, %c0 : (!fir.box>, index) -> (index, index, index) +// CHECK-NEXT: %[[V10:.*]] = arith.subi %[[V9]]#1, %c1 : index +// CHECK-NEXT: %[[V11:.*]] = fir.do_loop %arg3 = %c0 to %[[V10]] step %c1 iter_args(%arg4 = %c2147483647_i32) -> (i32) { +// CHECK-NEXT: %[[V14:.*]] = arith.addi %arg3, %c1 : index +// CHECK-NEXT: %[[V15:.*]] = hlfir.designate %[[V1]]#0 (%[[V14]]) : (!fir.box>, index) -> !fir.ref +// CHECK-NEXT: %[[V16:.*]] = fir.load %[[V15]] : !fir.ref +// CHECK-NEXT: %[[V17:.*]] = arith.cmpi sge, %[[V16]], %[[V4]] : i32 +// CHECK-NEXT: %[[V18:.*]] = fir.if %[[V17]] -> (i32) { +// CHECK-NEXT: %[[ISFIRST:.*]] = fir.load %[[V0]] : !fir.ref +// CHECK-NEXT: %[[V19:.*]] = hlfir.designate %[[V1]]#0 (%[[V14]]) : (!fir.box>, index) -> !fir.ref +// CHECK-NEXT: %[[V20:.*]] = fir.load %[[V19]] : !fir.ref +// CHECK-NEXT: %[[V21:.*]] = arith.cmpi slt, %[[V20]], %arg4 : i32 +// CHECK-NEXT: %[[ISFIRSTL:.*]] = fir.convert %[[ISFIRST]] : (i32) -> i1 +// CHECK-NEXT: %[[ISFIRSTNOT:.*]] = arith.xori %[[ISFIRSTL]], %true : i1 +// CHECK-NEXT: %[[ORCOND:.*]] = arith.ori %[[V21]], %[[ISFIRSTNOT]] : i1 +// CHECK-NEXT: %[[V22:.*]] = fir.if %[[ORCOND]] -> (i32) { +// CHECK-NEXT: fir.store %c1_i32 to %[[V0]] : !fir.ref +// CHECK-NEXT: %[[V23:.*]] = hlfir.designate %[[RES]] (%c1) : (!fir.ref>, index) -> !fir.ref +// CHECK-NEXT: %[[V24:.*]] = fir.convert %[[V14]] : (index) -> i32 +// CHECK-NEXT: fir.store %[[V24]] to %[[V23]] : !fir.ref +// CHECK-NEXT: fir.result %[[V20]] : i32 +// CHECK-NEXT: } else { +// CHECK-NEXT: fir.result %arg4 : i32 +// CHECK-NEXT: } +// CHECK-NEXT: fir.result %[[V22]] : i32 +// CHECK-NEXT: } else { +// CHECK-NEXT: fir.result %arg4 : i32 +// CHECK-NEXT: } +// CHECK-NEXT: fir.result %[[V18]] : i32 +// CHECK-NEXT: } +// CHECK-NEXT: hlfir.assign %[[RES]] to %[[V2]]#0 : !fir.ref>, !fir.box> +// CHECK-NEXT: return +// CHECK-NEXT: } + + +func.func @_QPtest_kind2(%arg0: !fir.box> {fir.bindc_name = "array"}, %arg1: !fir.ref {fir.bindc_name = "val"}, %arg2: !fir.box> {fir.bindc_name = "m"}) { + %c0 = arith.constant 0 : index + %0:2 = hlfir.declare %arg0 {uniq_name = "_QFtestEarray"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %1:2 = hlfir.declare %arg2 {uniq_name = "_QFtestEm"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %2:2 = hlfir.declare %arg1 {uniq_name = "_QFtestEval"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %3 = fir.load %2#0 : !fir.ref + %4:3 = fir.box_dims %0#0, %c0 : (!fir.box>, index) -> (index, index, index) + %5 = fir.shape %4#1 : (index) -> !fir.shape<1> + %6 = hlfir.elemental %5 unordered : (!fir.shape<1>) -> !hlfir.expr> { + ^bb0(%arg3: index): + %8 = hlfir.designate %0#0 (%arg3) : (!fir.box>, index) -> !fir.ref + %9 = fir.load %8 : !fir.ref + %10 = arith.cmpi sge, %9, %3 : i32 + %11 = fir.convert %10 : (i1) -> !fir.logical<4> + hlfir.yield_element %11 : !fir.logical<4> + } + %7 = hlfir.minloc %0#0 mask %6 {fastmath = #arith.fastmath} : (!fir.box>, !hlfir.expr>) -> !hlfir.expr<1xi16> + hlfir.assign %7 to %1#0 : !hlfir.expr<1xi16>, !fir.box> + hlfir.destroy %7 : !hlfir.expr<1xi16> + hlfir.destroy %6 : !hlfir.expr> + return +} +// CHECK-LABEL: func.func @_QPtest_kind2(%arg0: !fir.box> {fir.bindc_name = "array"}, %arg1: !fir.ref {fir.bindc_name = "val"}, %arg2: !fir.box> {fir.bindc_name = "m"}) { +// CHECK-NEXT: %true = arith.constant true +// CHECK-NEXT: %c2147483647_i32 = arith.constant 2147483647 : i32 +// CHECK-NEXT: %c1_i16 = arith.constant 1 : i16 +// CHECK-NEXT: %c0 = arith.constant 0 : index +// CHECK-NEXT: %c1 = arith.constant 1 : index +// CHECK-NEXT: %c0_i16 = arith.constant 0 : i16 +// CHECK-NEXT: %[[V0:.*]] = fir.alloca i16 +// CHECK-NEXT: %[[RES:.*]] = fir.alloca !fir.array<1xi16> +// CHECK-NEXT: %[[V1:.*]]:2 = hlfir.declare %arg0 {uniq_name = "_QFtestEarray"} : (!fir.box>) -> (!fir.box>, !fir.box>) +// CHECK-NEXT: %[[V2:.*]]:2 = hlfir.declare %arg2 {uniq_name = "_QFtestEm"} : (!fir.box>) -> (!fir.box>, !fir.box>) +// CHECK-NEXT: %[[V3:.*]]:2 = hlfir.declare %arg1 {uniq_name = "_QFtestEval"} : (!fir.ref) -> (!fir.ref, !fir.ref) +// CHECK-NEXT: %[[V4:.*]] = fir.load %[[V3]]#0 : !fir.ref +// CHECK-NEXT: %[[V8:.*]] = hlfir.designate %[[RES]] (%c1) : (!fir.ref>, index) -> !fir.ref +// CHECK-NEXT: fir.store %c0_i16 to %[[V8]] : !fir.ref +// CHECK-NEXT: fir.store %c0_i16 to %[[V0]] : !fir.ref +// CHECK-NEXT: %[[V9:.*]]:3 = fir.box_dims %[[V1]]#0, %c0 : (!fir.box>, index) -> (index, index, index) +// CHECK-NEXT: %[[V10:.*]] = arith.subi %[[V9]]#1, %c1 : index +// CHECK-NEXT: %[[V11:.*]] = fir.do_loop %arg3 = %c0 to %[[V10]] step %c1 iter_args(%arg4 = %c2147483647_i32) -> (i32) { +// CHECK-NEXT: %[[V14:.*]] = arith.addi %arg3, %c1 : index +// CHECK-NEXT: %[[V15:.*]] = hlfir.designate %[[V1]]#0 (%[[V14]]) : (!fir.box>, index) -> !fir.ref +// CHECK-NEXT: %[[V16:.*]] = fir.load %[[V15]] : !fir.ref +// CHECK-NEXT: %[[V17:.*]] = arith.cmpi sge, %[[V16]], %[[V4]] : i32 +// CHECK-NEXT: %[[V18:.*]] = fir.if %[[V17]] -> (i32) { +// CHECK-NEXT: %[[ISFIRST:.*]] = fir.load %[[V0]] : !fir.ref +// CHECK-NEXT: %[[V19:.*]] = hlfir.designate %[[V1]]#0 (%[[V14]]) : (!fir.box>, index) -> !fir.ref +// CHECK-NEXT: %[[V20:.*]] = fir.load %[[V19]] : !fir.ref +// CHECK-NEXT: %[[V21:.*]] = arith.cmpi slt, %[[V20]], %arg4 : i32 +// CHECK-NEXT: %[[ISFIRSTL:.*]] = fir.convert %[[ISFIRST]] : (i16) -> i1 +// CHECK-NEXT: %[[ISFIRSTNOT:.*]] = arith.xori %[[ISFIRSTL]], %true : i1 +// CHECK-NEXT: %[[ORCOND:.*]] = arith.ori %[[V21]], %[[ISFIRSTNOT]] : i1 +// CHECK-NEXT: %[[V22:.*]] = fir.if %[[ORCOND]] -> (i32) { +// CHECK-NEXT: fir.store %c1_i16 to %[[V0]] : !fir.ref +// CHECK-NEXT: %[[V23:.*]] = hlfir.designate %[[RES]] (%c1) : (!fir.ref>, index) -> !fir.ref +// CHECK-NEXT: %[[V24:.*]] = fir.convert %[[V14]] : (index) -> i16 +// CHECK-NEXT: fir.store %[[V24]] to %[[V23]] : !fir.ref +// CHECK-NEXT: fir.result %[[V20]] : i32 +// CHECK-NEXT: } else { +// CHECK-NEXT: fir.result %arg4 : i32 +// CHECK-NEXT: } +// CHECK-NEXT: fir.result %[[V22]] : i32 +// CHECK-NEXT: } else { +// CHECK-NEXT: fir.result %arg4 : i32 +// CHECK-NEXT: } +// CHECK-NEXT: fir.result %[[V18]] : i32 +// CHECK-NEXT: } +// CHECK-NEXT: hlfir.assign %[[RES]] to %[[V2]]#0 : !fir.ref>, !fir.box> +// CHECK-NEXT: return + + +func.func @_QPtest_kind2_convert(%arg0: !fir.box> {fir.bindc_name = "array"}, %arg1: !fir.ref {fir.bindc_name = "val"}, %arg2: !fir.box> {fir.bindc_name = "m"}) { + %c1 = arith.constant 1 : index + %c0 = arith.constant 0 : index + %0:2 = hlfir.declare %arg0 {uniq_name = "_QFtestEarray"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %1:2 = hlfir.declare %arg2 {uniq_name = "_QFtestEm"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %2:2 = hlfir.declare %arg1 {uniq_name = "_QFtestEval"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %3 = fir.load %2#0 : !fir.ref + %4:3 = fir.box_dims %0#0, %c0 : (!fir.box>, index) -> (index, index, index) + %5 = fir.shape %4#1 : (index) -> !fir.shape<1> + %6 = hlfir.elemental %5 unordered : (!fir.shape<1>) -> !hlfir.expr> { + ^bb0(%arg3: index): + %10 = hlfir.designate %0#0 (%arg3) : (!fir.box>, index) -> !fir.ref + %11 = fir.load %10 : !fir.ref + %12 = arith.cmpi sge, %11, %3 : i32 + %13 = fir.convert %12 : (i1) -> !fir.logical<4> + hlfir.yield_element %13 : !fir.logical<4> + } + %7 = hlfir.minloc %0#0 mask %6 {fastmath = #arith.fastmath} : (!fir.box>, !hlfir.expr>) -> !hlfir.expr<1xi16> + %8 = fir.shape %c1 : (index) -> !fir.shape<1> + %9 = hlfir.elemental %8 unordered : (!fir.shape<1>) -> !hlfir.expr { + ^bb0(%arg3: index): + %10 = hlfir.apply %7, %arg3 : (!hlfir.expr<1xi16>, index) -> i16 + %11 = fir.convert %10 : (i16) -> i32 + hlfir.yield_element %11 : i32 + } + hlfir.assign %9 to %1#0 : !hlfir.expr, !fir.box> + hlfir.destroy %9 : !hlfir.expr + hlfir.destroy %7 : !hlfir.expr<1xi16> + hlfir.destroy %6 : !hlfir.expr> + return +} +// CHECK-LABEL: func.func @_QPtest_kind2_convert( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.box> {fir.bindc_name = "array"}, +// CHECK-SAME: %[[VAL_1:.*]]: !fir.ref {fir.bindc_name = "val"}, +// CHECK-SAME: %[[VAL_2:.*]]: !fir.box> {fir.bindc_name = "m"}) { +// CHECK: %[[VAL_3:.*]] = arith.constant false +// CHECK: %[[VAL_4:.*]] = arith.constant true +// CHECK: %[[VAL_5:.*]] = arith.constant 2147483647 : i32 +// CHECK: %[[VAL_6:.*]] = arith.constant 1 : i16 +// CHECK: %[[VAL_7:.*]] = arith.constant 0 : index +// CHECK: %[[VAL_8:.*]] = arith.constant 0 : i16 +// CHECK: %[[VAL_9:.*]] = arith.constant 1 : index +// CHECK: %[[VAL_10:.*]] = fir.alloca i16 +// CHECK: %[[VAL_11:.*]] = fir.alloca !fir.array<1xi16> +// CHECK: %[[VAL_12:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFtestEarray"} : (!fir.box>) -> (!fir.box>, !fir.box>) +// CHECK: %[[VAL_13:.*]]:2 = hlfir.declare %[[VAL_2]] {uniq_name = "_QFtestEm"} : (!fir.box>) -> (!fir.box>, !fir.box>) +// CHECK: %[[VAL_14:.*]]:2 = hlfir.declare %[[VAL_1]] {uniq_name = "_QFtestEval"} : (!fir.ref) -> (!fir.ref, !fir.ref) +// CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_14]]#0 : !fir.ref +// CHECK: %[[VAL_16:.*]] = hlfir.designate %[[VAL_11]] (%[[VAL_9]]) : (!fir.ref>, index) -> !fir.ref +// CHECK: fir.store %[[VAL_8]] to %[[VAL_16]] : !fir.ref +// CHECK: fir.store %[[VAL_8]] to %[[VAL_10]] : !fir.ref +// CHECK: %[[VAL_17:.*]]:3 = fir.box_dims %[[VAL_12]]#0, %[[VAL_7]] : (!fir.box>, index) -> (index, index, index) +// CHECK: %[[VAL_18:.*]] = arith.subi %[[VAL_17]]#1, %[[VAL_9]] : index +// CHECK: %[[VAL_19:.*]] = fir.do_loop %[[VAL_20:.*]] = %[[VAL_7]] to %[[VAL_18]] step %[[VAL_9]] iter_args(%[[VAL_21:.*]] = %[[VAL_5]]) -> (i32) { +// CHECK: %[[VAL_22:.*]] = arith.addi %[[VAL_20]], %[[VAL_9]] : index +// CHECK: %[[VAL_23:.*]] = hlfir.designate %[[VAL_12]]#0 (%[[VAL_22]]) : (!fir.box>, index) -> !fir.ref +// CHECK: %[[VAL_24:.*]] = fir.load %[[VAL_23]] : !fir.ref +// CHECK: %[[VAL_25:.*]] = arith.cmpi sge, %[[VAL_24]], %[[VAL_15]] : i32 +// CHECK: %[[VAL_26:.*]] = fir.if %[[VAL_25]] -> (i32) { +// CHECK: %[[VAL_27:.*]] = fir.load %[[VAL_10]] : !fir.ref +// CHECK: %[[VAL_28:.*]] = hlfir.designate %[[VAL_12]]#0 (%[[VAL_22]]) : (!fir.box>, index) -> !fir.ref +// CHECK: %[[VAL_29:.*]] = fir.load %[[VAL_28]] : !fir.ref +// CHECK: %[[VAL_30:.*]] = arith.cmpi slt, %[[VAL_29]], %[[VAL_21]] : i32 +// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_27]] : (i16) -> i1 +// CHECK: %[[VAL_32:.*]] = arith.xori %[[VAL_31]], %[[VAL_4]] : i1 +// CHECK: %[[VAL_33:.*]] = arith.ori %[[VAL_30]], %[[VAL_32]] : i1 +// CHECK: %[[VAL_34:.*]] = fir.if %[[VAL_33]] -> (i32) { +// CHECK: fir.store %[[VAL_6]] to %[[VAL_10]] : !fir.ref +// CHECK: %[[VAL_35:.*]] = hlfir.designate %[[VAL_11]] (%[[VAL_9]]) : (!fir.ref>, index) -> !fir.ref +// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_22]] : (index) -> i16 +// CHECK: fir.store %[[VAL_36]] to %[[VAL_35]] : !fir.ref +// CHECK: fir.result %[[VAL_29]] : i32 +// CHECK: } else { +// CHECK: fir.result %[[VAL_21]] : i32 +// CHECK: } +// CHECK: fir.result %[[VAL_34]] : i32 +// CHECK: } else { +// CHECK: fir.result %[[VAL_21]] : i32 +// CHECK: } +// CHECK: fir.result %[[VAL_26]] : i32 +// CHECK: } +// CHECK: %[[VAL_37:.*]] = hlfir.as_expr %[[VAL_11]] move %[[VAL_3]] : (!fir.ref>, i1) -> !hlfir.expr<1xi16> +// CHECK: fir.do_loop %[[VAL_38:.*]] = %[[VAL_9]] to %[[VAL_9]] step %[[VAL_9]] unordered { +// CHECK: %[[VAL_39:.*]] = hlfir.apply %[[VAL_37]], %[[VAL_38]] : (!hlfir.expr<1xi16>, index) -> i16 +// CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_39]] : (i16) -> i32 +// CHECK: %[[VAL_41:.*]] = hlfir.designate %[[VAL_13]]#0 (%[[VAL_38]]) : (!fir.box>, index) -> !fir.ref +// CHECK: hlfir.assign %[[VAL_40]] to %[[VAL_41]] : i32, !fir.ref +// CHECK: } +// CHECK: return +// CHECK: } + + +func.func @_QPtest_float(%arg0: !fir.box> {fir.bindc_name = "array"}, %arg1: !fir.ref {fir.bindc_name = "val"}, %arg2: !fir.box> {fir.bindc_name = "m"}) { + %c0 = arith.constant 0 : index + %0:2 = hlfir.declare %arg0 {uniq_name = "_QFtestEarray"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %1:2 = hlfir.declare %arg2 {uniq_name = "_QFtestEm"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %2:2 = hlfir.declare %arg1 {uniq_name = "_QFtestEval"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %3 = fir.load %2#0 : !fir.ref + %4:3 = fir.box_dims %0#0, %c0 : (!fir.box>, index) -> (index, index, index) + %5 = fir.shape %4#1 : (index) -> !fir.shape<1> + %6 = hlfir.elemental %5 unordered : (!fir.shape<1>) -> !hlfir.expr> { + ^bb0(%arg3: index): + %8 = hlfir.designate %0#0 (%arg3) : (!fir.box>, index) -> !fir.ref + %9 = fir.load %8 : !fir.ref + %10 = arith.cmpf oge, %9, %3 : f32 + %11 = fir.convert %10 : (i1) -> !fir.logical<4> + hlfir.yield_element %11 : !fir.logical<4> + } + %7 = hlfir.minloc %0#0 mask %6 {fastmath = #arith.fastmath} : (!fir.box>, !hlfir.expr>) -> !hlfir.expr<1xi32> + hlfir.assign %7 to %1#0 : !hlfir.expr<1xi32>, !fir.box> + hlfir.destroy %7 : !hlfir.expr<1xi32> + hlfir.destroy %6 : !hlfir.expr> + return +} +// CHECK-LABEL: _QPtest_float +// CHECK: %cst = arith.constant 0x7F800000 : f32 +// CHECK: %[[V11:.*]] = fir.do_loop %arg3 = %c0 to %[[V10:.*]] step %c1 iter_args(%arg4 = %cst) -> (f32) { +// CHECK-NEXT: %[[V14:.*]] = arith.addi %arg3, %c1 : index +// CHECK-NEXT: %[[V15:.*]] = hlfir.designate %[[V1:.*]]#0 (%[[V14]]) : (!fir.box>, index) -> !fir.ref +// CHECK-NEXT: %[[V16:.*]] = fir.load %[[V15]] : !fir.ref +// CHECK-NEXT: %[[V17:.*]] = arith.cmpf oge, %[[V16]], %[[V4:.*]] : f32 +// CHECK-NEXT: %[[V18:.*]] = fir.if %[[V17]] -> (f32) { +// CHECK-NEXT: %[[ISFIRST:.*]] = fir.load %[[V0:.*]] : !fir.ref +// CHECK-NEXT: %[[V19:.*]] = hlfir.designate %[[V1]]#0 (%[[V14]]) : (!fir.box>, index) -> !fir.ref +// CHECK-NEXT: %[[V20:.*]] = fir.load %[[V19]] : !fir.ref +// CHECK-NEXT: %[[NEW_MIN:.*]] = arith.cmpf olt, %[[V20]], %arg4 fastmath : f32 +// CHECK-NEXT: %[[CONDRED:.*]] = arith.cmpf une, %arg4, %arg4 fastmath : f32 +// CHECK-NEXT: %[[CONDELEM:.*]] = arith.cmpf oeq, %[[V20]], %[[V20]] fastmath : f32 +// CHECK-NEXT: %[[ANDCOND:.*]] = arith.andi %[[CONDRED]], %[[CONDELEM]] : i1 +// CHECK-NEXT: %[[NEW_MIN2:.*]] = arith.ori %[[NEW_MIN]], %[[ANDCOND]] : i1 +// CHECK-NEXT: %[[ISFIRSTL:.*]] = fir.convert %[[ISFIRST]] : (i32) -> i1 +// CHECK-NEXT: %[[ISFIRSTNOT:.*]] = arith.xori %[[ISFIRSTL]], %true : i1 +// CHECK-NEXT: %[[ORCOND:.*]] = arith.ori %[[NEW_MIN2]], %[[ISFIRSTNOT]] : i1 +// CHECK-NEXT: %[[V22:.*]] = fir.if %[[ORCOND]] -> (f32) { +// CHECK-NEXT: fir.store %c1_i32 to %[[V0]] : !fir.ref +// CHECK-NEXT: %[[V23:.*]] = hlfir.designate %{{.}} (%c1) : (!fir.ref>, index) -> !fir.ref +// CHECK-NEXT: %[[V24:.*]] = fir.convert %[[V14]] : (index) -> i32 +// CHECK-NEXT: fir.store %[[V24]] to %[[V23]] : !fir.ref +// CHECK-NEXT: fir.result %[[V20]] : f32 +// CHECK-NEXT: } else { +// CHECK-NEXT: fir.result %arg4 : f32 +// CHECK-NEXT: } +// CHECK-NEXT: fir.result %[[V22]] : f32 +// CHECK-NEXT: } else { +// CHECK-NEXT: fir.result %arg4 : f32 +// CHECK-NEXT: } +// CHECK-NEXT: fir.result %[[V18]] : f32 +// CHECK-NEXT: } + + +func.func @_QPtest_assignshape(%arg0: !fir.ref> {fir.bindc_name = "array"}, %arg1: !fir.ref {fir.bindc_name = "val"}, %arg2: !fir.ref> {fir.bindc_name = "m"}) { + %c2 = arith.constant 2 : index + %c1 = arith.constant 1 : index + %c3 = arith.constant 3 : index + %0 = fir.shape %c3, %c3 : (index, index) -> !fir.shape<2> + %1:2 = hlfir.declare %arg0(%0) {uniq_name = "_QFtestEarray"} : (!fir.ref>, !fir.shape<2>) -> (!fir.ref>, !fir.ref>) + %2 = fir.shape %c3 : (index) -> !fir.shape<1> + %3:2 = hlfir.declare %arg2(%2) {uniq_name = "_QFtestEm"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) + %4:2 = hlfir.declare %arg1 {uniq_name = "_QFtestEval"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %5 = fir.load %4#0 : !fir.ref + %6 = hlfir.elemental %0 unordered : (!fir.shape<2>) -> !hlfir.expr<3x3x!fir.logical<4>> { + ^bb0(%arg3: index, %arg4: index): + %10 = hlfir.designate %1#0 (%arg3, %arg4) : (!fir.ref>, index, index) -> !fir.ref + %11 = fir.load %10 : !fir.ref + %12 = arith.cmpf oge, %11, %5 : f32 + %13 = fir.convert %12 : (i1) -> !fir.logical<4> + hlfir.yield_element %13 : !fir.logical<4> + } + %7 = hlfir.minloc %1#0 mask %6 {fastmath = #arith.fastmath} : (!fir.ref>, !hlfir.expr<3x3x!fir.logical<4>>) -> !hlfir.expr<2xi32> + %8 = fir.shape %c2 : (index) -> !fir.shape<1> + %9 = hlfir.designate %3#0 (%c1:%c2:%c1) shape %8 : (!fir.ref>, index, index, index, !fir.shape<1>) -> !fir.ref> + hlfir.assign %7 to %9 : !hlfir.expr<2xi32>, !fir.ref> + hlfir.destroy %7 : !hlfir.expr<2xi32> + hlfir.destroy %6 : !hlfir.expr<3x3x!fir.logical<4>> + return +} +// Not supported as the input is not a box +// CHECK-LABEL: _QPtest_assignshape +// CHECK: hlfir.minloc + + +func.func @_QFPtest_character(%arg0: !fir.box>> {fir.bindc_name = "b"}, %arg1: !fir.box> {fir.bindc_name = "c"}, %arg2: !fir.ref {fir.bindc_name = "val"}) -> i32 { + %c0 = arith.constant 0 : index + %c1 = arith.constant 1 : index + %0:2 = hlfir.declare %arg0 typeparams %c1 {uniq_name = "_QFFtestEb"} : (!fir.box>>, index) -> (!fir.box>>, !fir.box>>) + %1:2 = hlfir.declare %arg1 {uniq_name = "_QFFtestEc"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %2 = fir.alloca !fir.array<1xi32> {bindc_name = "m", uniq_name = "_QFFtestEm"} + %3 = fir.shape %c1 : (index) -> !fir.shape<1> + %4:2 = hlfir.declare %2(%3) {uniq_name = "_QFFtestEm"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) + %5 = fir.alloca i32 {bindc_name = "test", uniq_name = "_QFFtestEtest"} + %6:2 = hlfir.declare %5 {uniq_name = "_QFFtestEtest"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %7:2 = hlfir.declare %arg2 {uniq_name = "_QFFtestEval"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %8 = fir.load %7#0 : !fir.ref + %9:3 = fir.box_dims %1#0, %c0 : (!fir.box>, index) -> (index, index, index) + %10 = fir.shape %9#1 : (index) -> !fir.shape<1> + %11 = hlfir.elemental %10 unordered : (!fir.shape<1>) -> !hlfir.expr> { + ^bb0(%arg3: index): + %16 = hlfir.designate %1#0 (%arg3) : (!fir.box>, index) -> !fir.ref + %17 = fir.load %16 : !fir.ref + %18 = arith.cmpi eq, %17, %8 : i32 + %19 = fir.convert %18 : (i1) -> !fir.logical<4> + hlfir.yield_element %19 : !fir.logical<4> + } + %12 = hlfir.minloc %0#0 mask %11 {fastmath = #arith.fastmath} : (!fir.box>>, !hlfir.expr>) -> !hlfir.expr<1xi32> + hlfir.assign %12 to %4#0 : !hlfir.expr<1xi32>, !fir.ref> + hlfir.destroy %12 : !hlfir.expr<1xi32> + hlfir.destroy %11 : !hlfir.expr> + %13 = hlfir.designate %4#0 (%c1) : (!fir.ref>, index) -> !fir.ref + %14 = fir.load %13 : !fir.ref + hlfir.assign %14 to %6#0 : i32, !fir.ref + %15 = fir.load %6#1 : !fir.ref + return %15 : i32 +} +// Characters are not supported at the moment +// CHECK-LABEL: _QFPtest_character +// CHECK: hlfir.minloc + + +func.func @_QPtest_parts(%arg0: !fir.box> {fir.bindc_name = "x"}, %arg1: !fir.box> {fir.bindc_name = "mask"}) -> f32 { + %c1 = arith.constant 1 : index + %c5 = arith.constant 5 : index + %c0 = arith.constant 0 : index + %c5_i32 = arith.constant 5 : i32 + %0:2 = hlfir.declare %arg1 {uniq_name = "_QFtestEmask"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %1 = fir.alloca f32 {bindc_name = "test", uniq_name = "_QFtestEtest"} + %2:2 = hlfir.declare %1 {uniq_name = "_QFtestEtest"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %3:2 = hlfir.declare %arg0 {uniq_name = "_QFtestEx"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %4:3 = fir.box_dims %0#0, %c0 : (!fir.box>, index) -> (index, index, index) + %5 = fir.shape %4#1 : (index) -> !fir.shape<1> + %6 = hlfir.elemental %5 unordered : (!fir.shape<1>) -> !hlfir.expr> { + ^bb0(%arg2: index): + %11 = hlfir.designate %0#0 (%arg2) : (!fir.box>, index) -> !fir.ref + %12 = fir.load %11 : !fir.ref + %13 = arith.cmpi sge, %12, %c5_i32 : i32 + %14 = fir.convert %13 : (i1) -> !fir.logical<4> + hlfir.yield_element %14 : !fir.logical<4> + } + %7 = hlfir.minloc %3#0 mask %6 {fastmath = #arith.fastmath} : (!fir.box>, !hlfir.expr>) -> !hlfir.expr<1xi32> + %8 = fir.shape %c1 : (index) -> !fir.shape<1> + %9 = hlfir.designate %3#0 (%c5:%c5:%c1) shape %8 : (!fir.box>, index, index, index, !fir.shape<1>) -> !fir.box> + hlfir.assign %7 to %9 : !hlfir.expr<1xi32>, !fir.box> + hlfir.destroy %7 : !hlfir.expr<1xi32> + hlfir.destroy %6 : !hlfir.expr> + %10 = fir.load %2#1 : !fir.ref + return %10 : f32 +} +// Characters are not supported at the moment +// CHECK-LABEL: _QPtest_parts +// CHECK: fir.do_loop %{{.*}} = %c0 to %{{.*}} step %c1 iter_args(%{{.*}} = %c2147483647_i32) -> (i32) { + diff --git a/flang/test/HLFIR/minval-elemental.fir b/flang/test/HLFIR/minval-elemental.fir new file mode 100644 index 0000000000000..64cd5403ec558 --- /dev/null +++ b/flang/test/HLFIR/minval-elemental.fir @@ -0,0 +1,95 @@ +// Test maxval inlining for both elemental and designate +// RUN: fir-opt %s -opt-bufferization | FileCheck %s + +// subroutine test(array) +// integer :: array(:), x +// x = minval(abs(array)) +// end subroutine test + +func.func @_QPtest(%arg0: !fir.box> {fir.bindc_name = "array"}) { + %c31_i32 = arith.constant 31 : i32 + %c0 = arith.constant 0 : index + %0 = fir.dummy_scope : !fir.dscope + %1:2 = hlfir.declare %arg0 dummy_scope %0 {uniq_name = "_QFtestEarray"} : (!fir.box>, !fir.dscope) -> (!fir.box>, !fir.box>) + %2 = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFtestEx"} + %3:2 = hlfir.declare %2 {uniq_name = "_QFtestEx"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %4:3 = fir.box_dims %1#0, %c0 : (!fir.box>, index) -> (index, index, index) + %5 = fir.shape %4#1 : (index) -> !fir.shape<1> + %6 = hlfir.elemental %5 unordered : (!fir.shape<1>) -> !hlfir.expr { + ^bb0(%arg1: index): + %8 = hlfir.designate %1#0 (%arg1) : (!fir.box>, index) -> !fir.ref + %9 = fir.load %8 : !fir.ref + %10 = arith.shrsi %9, %c31_i32 : i32 + %11 = arith.xori %9, %10 : i32 + %12 = arith.subi %11, %10 : i32 + hlfir.yield_element %12 : i32 + } + %7 = hlfir.minval %6 {fastmath = #arith.fastmath} : (!hlfir.expr) -> i32 + hlfir.assign %7 to %3#0 : i32, !fir.ref + hlfir.destroy %6 : !hlfir.expr + return +} + +// CHECK-LABEL: func.func @_QPtest(%arg0: !fir.box> {fir.bindc_name = "array"}) { +// CHECK-NEXT: %c1 = arith.constant 1 : index +// CHECK-NEXT: %c2147483647_i32 = arith.constant 2147483647 : i32 +// CHECK-NEXT: %c31_i32 = arith.constant 31 : i32 +// CHECK-NEXT: %c0 = arith.constant 0 : index +// CHECK-NEXT: %[[V0:.*]] = fir.dummy_scope : !fir.dscope +// CHECK-NEXT: %[[V1:.*]]:2 = hlfir.declare %arg0 dummy_scope %[[V0]] {uniq_name = "_QFtestEarray"} : (!fir.box>, !fir.dscope) -> (!fir.box>, !fir.box>) +// CHECK-NEXT: %[[V2:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFtestEx"} +// CHECK-NEXT: %[[V3:.*]]:2 = hlfir.declare %[[V2]] {uniq_name = "_QFtestEx"} : (!fir.ref) -> (!fir.ref, !fir.ref) +// CHECK-NEXT: %[[V4:.*]]:3 = fir.box_dims %[[V1]]#0, %c0 : (!fir.box>, index) -> (index, index, index) +// CHECK-NEXT: %[[V5:.*]] = fir.do_loop %arg1 = %c1 to %[[V4]]#1 step %c1 iter_args(%arg2 = %c2147483647_i32) -> (i32) { +// CHECK-NEXT: %[[V6:.*]] = hlfir.designate %[[V1]]#0 (%arg1) : (!fir.box>, index) -> !fir.ref +// CHECK-NEXT: %[[V7:.*]] = fir.load %[[V6]] : !fir.ref +// CHECK-NEXT: %[[V8:.*]] = arith.shrsi %[[V7]], %c31_i32 : i32 +// CHECK-NEXT: %[[V9:.*]] = arith.xori %[[V7]], %[[V8]] : i32 +// CHECK-NEXT: %[[V10:.*]] = arith.subi %[[V9]], %[[V8]] : i32 +// CHECK-NEXT: %[[V11:.*]] = arith.cmpi slt, %[[V10]], %arg2 : i32 +// CHECK-NEXT: %[[V12:.*]] = arith.select %[[V11]], %[[V10]], %arg2 : i32 +// CHECK-NEXT: fir.result %[[V12]] : i32 +// CHECK-NEXT: } +// CHECK-NEXT: hlfir.assign %[[V5]] to %[[V3]]#0 : i32, !fir.ref +// CHECK-NEXT: return +// CHECK-NEXT: } + +// subroutine test(array) +// real :: array(:), x +// x = minval(array(3:6)) +// end subroutine test + +func.func @_QPtest_float(%arg0: !fir.box> {fir.bindc_name = "array"}) { + %c4 = arith.constant 4 : index + %c1 = arith.constant 1 : index + %c6 = arith.constant 6 : index + %c3 = arith.constant 3 : index + %0 = fir.dummy_scope : !fir.dscope + %1:2 = hlfir.declare %arg0 dummy_scope %0 {uniq_name = "_QFtestEarray"} : (!fir.box>, !fir.dscope) -> (!fir.box>, !fir.box>) + %2 = fir.alloca f32 {bindc_name = "x", uniq_name = "_QFtestEx"} + %3:2 = hlfir.declare %2 {uniq_name = "_QFtestEx"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %4 = fir.shape %c4 : (index) -> !fir.shape<1> + %5 = hlfir.designate %1#0 (%c3:%c6:%c1) shape %4 : (!fir.box>, index, index, index, !fir.shape<1>) -> !fir.box> + %6 = hlfir.minval %5 {fastmath = #arith.fastmath} : (!fir.box>) -> f32 + hlfir.assign %6 to %3#0 : f32, !fir.ref + return +} + +// CHECK-LABEL: _QPtest_float +// CHECK: %cst = arith.constant 0x7F800000 : f32 +// CHECK: %[[V4:.*]] = fir.shape %c4 : (index) -> !fir.shape<1> +// CHECK-NEXT: %[[V5:.*]] = hlfir.designate %{{.*}} (%c3:%c6:%c1) shape %[[V4]] : (!fir.box>, index, index, index, !fir.shape<1>) -> !fir.box> +// CHECK-NEXT: %[[V6:.*]] = fir.do_loop %arg1 = %c1 to %c4 step %c1 iter_args(%arg2 = %cst) -> (f32) { +// CHECK-NEXT: %[[V7:.*]] = hlfir.designate %[[V5]] (%arg1) : (!fir.box>, index) -> !fir.ref +// CHECK-NEXT: %[[V8:.*]] = fir.load %[[V7]] : !fir.ref +// CHECK-NEXT: %[[V9:.*]] = arith.cmpf olt, %[[V8]], %arg2 fastmath : f32 +// CHECK-NEXT: %[[V10:.*]] = arith.cmpf une, %arg2, %arg2 fastmath : f32 +// CHECK-NEXT: %[[V11:.*]] = arith.cmpf oeq, %[[V8]], %[[V8]] fastmath : f32 +// CHECK-NEXT: %[[V12:.*]] = arith.andi %[[V10]], %[[V11]] : i1 +// CHECK-NEXT: %[[V13:.*]] = arith.ori %[[V9]], %[[V12]] : i1 +// CHECK-NEXT: %[[V14:.*]] = arith.select %[[V13]], %[[V8]], %arg2 : f32 +// CHECK-NEXT: fir.result %[[V14]] : f32 +// CHECK-NEXT: } +// CHECK-NEXT: hlfir.assign %[[V6]] to %3#0 : f32, !fir.ref +// CHECK-NEXT: return +// CHECK-NEXT: } diff --git a/flang/test/HLFIR/simplify-hlfir-intrinsics-all.fir b/flang/test/HLFIR/simplify-hlfir-intrinsics-all.fir deleted file mode 100644 index fb0f39811ea74..0000000000000 --- a/flang/test/HLFIR/simplify-hlfir-intrinsics-all.fir +++ /dev/null @@ -1,123 +0,0 @@ -// RUN: fir-opt %s --simplify-hlfir-intrinsics | FileCheck %s - -func.func @test_total_expr(%arg0: !hlfir.expr>) -> !fir.logical<4> { - %0 = hlfir.all %arg0 : (!hlfir.expr>) -> !fir.logical<4> - return %0 : !fir.logical<4> -} -// CHECK-LABEL: func.func @test_total_expr( -// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !hlfir.expr>) -> !fir.logical<4> { -// CHECK: %[[VAL_1:.*]] = arith.constant 1 : index -// CHECK: %[[VAL_2:.*]] = arith.constant true -// CHECK: %[[VAL_3:.*]] = hlfir.shape_of %[[VAL_0]] : (!hlfir.expr>) -> !fir.shape<2> -// CHECK: %[[VAL_4:.*]] = hlfir.get_extent %[[VAL_3]] {dim = 0 : index} : (!fir.shape<2>) -> index -// CHECK: %[[VAL_5:.*]] = hlfir.get_extent %[[VAL_3]] {dim = 1 : index} : (!fir.shape<2>) -> index -// CHECK: %[[VAL_6:.*]] = fir.do_loop %[[VAL_7:.*]] = %[[VAL_1]] to %[[VAL_5]] step %[[VAL_1]] unordered iter_args(%[[VAL_8:.*]] = %[[VAL_2]]) -> (i1) { -// CHECK: %[[VAL_9:.*]] = fir.do_loop %[[VAL_10:.*]] = %[[VAL_1]] to %[[VAL_4]] step %[[VAL_1]] unordered iter_args(%[[VAL_11:.*]] = %[[VAL_8]]) -> (i1) { -// CHECK: %[[VAL_12:.*]] = hlfir.apply %[[VAL_0]], %[[VAL_10]], %[[VAL_7]] : (!hlfir.expr>, index, index) -> !fir.logical<4> -// CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_12]] : (!fir.logical<4>) -> i1 -// CHECK: %[[VAL_14:.*]] = arith.andi %[[VAL_13]], %[[VAL_11]] : i1 -// CHECK: fir.result %[[VAL_14]] : i1 -// CHECK: } -// CHECK: fir.result %[[VAL_9]] : i1 -// CHECK: } -// CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_6]] : (i1) -> !fir.logical<4> -// CHECK: return %[[VAL_15]] : !fir.logical<4> -// CHECK: } - -func.func @test_partial_expr(%arg0: !hlfir.expr>) -> !hlfir.expr> { - %dim = arith.constant 2 : i32 - %0 = hlfir.all %arg0 dim %dim : (!hlfir.expr>, i32) -> !hlfir.expr> - return %0 : !hlfir.expr> -} -// CHECK-LABEL: func.func @test_partial_expr( -// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !hlfir.expr>) -> !hlfir.expr> { -// CHECK: %[[VAL_1:.*]] = arith.constant 1 : index -// CHECK: %[[VAL_2:.*]] = arith.constant true -// CHECK: %[[VAL_3:.*]] = hlfir.shape_of %[[VAL_0]] : (!hlfir.expr>) -> !fir.shape<3> -// CHECK: %[[VAL_4:.*]] = hlfir.get_extent %[[VAL_3]] {dim = 0 : index} : (!fir.shape<3>) -> index -// CHECK: %[[VAL_5:.*]] = hlfir.get_extent %[[VAL_3]] {dim = 1 : index} : (!fir.shape<3>) -> index -// CHECK: %[[VAL_6:.*]] = hlfir.get_extent %[[VAL_3]] {dim = 2 : index} : (!fir.shape<3>) -> index -// CHECK: %[[VAL_7:.*]] = fir.shape %[[VAL_4]], %[[VAL_6]] : (index, index) -> !fir.shape<2> -// CHECK: %[[VAL_8:.*]] = hlfir.elemental %[[VAL_7]] unordered : (!fir.shape<2>) -> !hlfir.expr> { -// CHECK: ^bb0(%[[VAL_9:.*]]: index, %[[VAL_10:.*]]: index): -// CHECK: %[[VAL_11:.*]] = fir.do_loop %[[VAL_12:.*]] = %[[VAL_1]] to %[[VAL_5]] step %[[VAL_1]] unordered iter_args(%[[VAL_13:.*]] = %[[VAL_2]]) -> (i1) { -// CHECK: %[[VAL_14:.*]] = hlfir.apply %[[VAL_0]], %[[VAL_9]], %[[VAL_12]], %[[VAL_10]] : (!hlfir.expr>, index, index, index) -> !fir.logical<1> -// CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_14]] : (!fir.logical<1>) -> i1 -// CHECK: %[[VAL_16:.*]] = arith.andi %[[VAL_15]], %[[VAL_13]] : i1 -// CHECK: fir.result %[[VAL_16]] : i1 -// CHECK: } -// CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_11]] : (i1) -> !fir.logical<1> -// CHECK: hlfir.yield_element %[[VAL_17]] : !fir.logical<1> -// CHECK: } -// CHECK: return %[[VAL_8]] : !hlfir.expr> -// CHECK: } - -func.func @test_total_var(%arg0: !fir.box>>) -> !fir.logical<4> { - %0 = hlfir.all %arg0 : (!fir.box>>) -> !fir.logical<4> - return %0 : !fir.logical<4> -} -// CHECK-LABEL: func.func @test_total_var( -// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box>>) -> !fir.logical<4> { -// CHECK: %[[VAL_1:.*]] = arith.constant true -// CHECK: %[[VAL_2:.*]] = arith.constant 1 : index -// CHECK: %[[VAL_3:.*]] = arith.constant 0 : index -// CHECK: %[[VAL_4:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_5:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_2]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_6:.*]] = fir.do_loop %[[VAL_7:.*]] = %[[VAL_2]] to %[[VAL_5]]#1 step %[[VAL_2]] unordered iter_args(%[[VAL_8:.*]] = %[[VAL_1]]) -> (i1) { -// CHECK: %[[VAL_9:.*]] = fir.do_loop %[[VAL_10:.*]] = %[[VAL_2]] to %[[VAL_4]]#1 step %[[VAL_2]] unordered iter_args(%[[VAL_11:.*]] = %[[VAL_8]]) -> (i1) { -// CHECK: %[[VAL_12:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_13:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_2]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_14:.*]] = arith.subi %[[VAL_12]]#0, %[[VAL_2]] : index -// CHECK: %[[VAL_15:.*]] = arith.addi %[[VAL_10]], %[[VAL_14]] : index -// CHECK: %[[VAL_16:.*]] = arith.subi %[[VAL_13]]#0, %[[VAL_2]] : index -// CHECK: %[[VAL_17:.*]] = arith.addi %[[VAL_7]], %[[VAL_16]] : index -// CHECK: %[[VAL_18:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_15]], %[[VAL_17]]) : (!fir.box>>, index, index) -> !fir.ref> -// CHECK: %[[VAL_19:.*]] = fir.load %[[VAL_18]] : !fir.ref> -// CHECK: %[[VAL_20:.*]] = fir.convert %[[VAL_19]] : (!fir.logical<4>) -> i1 -// CHECK: %[[VAL_21:.*]] = arith.andi %[[VAL_20]], %[[VAL_11]] : i1 -// CHECK: fir.result %[[VAL_21]] : i1 -// CHECK: } -// CHECK: fir.result %[[VAL_9]] : i1 -// CHECK: } -// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_6]] : (i1) -> !fir.logical<4> -// CHECK: return %[[VAL_22]] : !fir.logical<4> -// CHECK: } - -func.func @test_partial_var(%arg0: !fir.box>>) -> !hlfir.expr> { - %dim = arith.constant 2 : i32 - %0 = hlfir.all %arg0 dim %dim : (!fir.box>>, i32) -> !hlfir.expr> - return %0 : !hlfir.expr> -} -// CHECK-LABEL: func.func @test_partial_var( -// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box>>) -> !hlfir.expr> { -// CHECK: %[[VAL_1:.*]] = arith.constant true -// CHECK: %[[VAL_2:.*]] = arith.constant 2 : index -// CHECK: %[[VAL_3:.*]] = arith.constant 1 : index -// CHECK: %[[VAL_4:.*]] = arith.constant 0 : index -// CHECK: %[[VAL_5:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_6:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_7:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_2]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_8:.*]] = fir.shape %[[VAL_5]]#1, %[[VAL_7]]#1 : (index, index) -> !fir.shape<2> -// CHECK: %[[VAL_9:.*]] = hlfir.elemental %[[VAL_8]] unordered : (!fir.shape<2>) -> !hlfir.expr> { -// CHECK: ^bb0(%[[VAL_10:.*]]: index, %[[VAL_11:.*]]: index): -// CHECK: %[[VAL_12:.*]] = fir.do_loop %[[VAL_13:.*]] = %[[VAL_3]] to %[[VAL_6]]#1 step %[[VAL_3]] unordered iter_args(%[[VAL_14:.*]] = %[[VAL_1]]) -> (i1) { -// CHECK: %[[VAL_15:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_16:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_17:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_2]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_18:.*]] = arith.subi %[[VAL_15]]#0, %[[VAL_3]] : index -// CHECK: %[[VAL_19:.*]] = arith.addi %[[VAL_10]], %[[VAL_18]] : index -// CHECK: %[[VAL_20:.*]] = arith.subi %[[VAL_16]]#0, %[[VAL_3]] : index -// CHECK: %[[VAL_21:.*]] = arith.addi %[[VAL_13]], %[[VAL_20]] : index -// CHECK: %[[VAL_22:.*]] = arith.subi %[[VAL_17]]#0, %[[VAL_3]] : index -// CHECK: %[[VAL_23:.*]] = arith.addi %[[VAL_11]], %[[VAL_22]] : index -// CHECK: %[[VAL_24:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_19]], %[[VAL_21]], %[[VAL_23]]) : (!fir.box>>, index, index, index) -> !fir.ref> -// CHECK: %[[VAL_25:.*]] = fir.load %[[VAL_24]] : !fir.ref> -// CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_25]] : (!fir.logical<2>) -> i1 -// CHECK: %[[VAL_27:.*]] = arith.andi %[[VAL_26]], %[[VAL_14]] : i1 -// CHECK: fir.result %[[VAL_27]] : i1 -// CHECK: } -// CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_12]] : (i1) -> !fir.logical<2> -// CHECK: hlfir.yield_element %[[VAL_28]] : !fir.logical<2> -// CHECK: } -// CHECK: return %[[VAL_9]] : !hlfir.expr> -// CHECK: } diff --git a/flang/test/HLFIR/simplify-hlfir-intrinsics-any.fir b/flang/test/HLFIR/simplify-hlfir-intrinsics-any.fir deleted file mode 100644 index 5bd76f3d24927..0000000000000 --- a/flang/test/HLFIR/simplify-hlfir-intrinsics-any.fir +++ /dev/null @@ -1,123 +0,0 @@ -// RUN: fir-opt %s --simplify-hlfir-intrinsics | FileCheck %s - -func.func @test_total_expr(%arg0: !hlfir.expr>) -> !fir.logical<4> { - %0 = hlfir.any %arg0 : (!hlfir.expr>) -> !fir.logical<4> - return %0 : !fir.logical<4> -} -// CHECK-LABEL: func.func @test_total_expr( -// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !hlfir.expr>) -> !fir.logical<4> { -// CHECK: %[[VAL_1:.*]] = arith.constant 1 : index -// CHECK: %[[VAL_2:.*]] = arith.constant false -// CHECK: %[[VAL_3:.*]] = hlfir.shape_of %[[VAL_0]] : (!hlfir.expr>) -> !fir.shape<2> -// CHECK: %[[VAL_4:.*]] = hlfir.get_extent %[[VAL_3]] {dim = 0 : index} : (!fir.shape<2>) -> index -// CHECK: %[[VAL_5:.*]] = hlfir.get_extent %[[VAL_3]] {dim = 1 : index} : (!fir.shape<2>) -> index -// CHECK: %[[VAL_6:.*]] = fir.do_loop %[[VAL_7:.*]] = %[[VAL_1]] to %[[VAL_5]] step %[[VAL_1]] unordered iter_args(%[[VAL_8:.*]] = %[[VAL_2]]) -> (i1) { -// CHECK: %[[VAL_9:.*]] = fir.do_loop %[[VAL_10:.*]] = %[[VAL_1]] to %[[VAL_4]] step %[[VAL_1]] unordered iter_args(%[[VAL_11:.*]] = %[[VAL_8]]) -> (i1) { -// CHECK: %[[VAL_12:.*]] = hlfir.apply %[[VAL_0]], %[[VAL_10]], %[[VAL_7]] : (!hlfir.expr>, index, index) -> !fir.logical<4> -// CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_12]] : (!fir.logical<4>) -> i1 -// CHECK: %[[VAL_14:.*]] = arith.ori %[[VAL_13]], %[[VAL_11]] : i1 -// CHECK: fir.result %[[VAL_14]] : i1 -// CHECK: } -// CHECK: fir.result %[[VAL_9]] : i1 -// CHECK: } -// CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_6]] : (i1) -> !fir.logical<4> -// CHECK: return %[[VAL_15]] : !fir.logical<4> -// CHECK: } - -func.func @test_partial_expr(%arg0: !hlfir.expr>) -> !hlfir.expr> { - %dim = arith.constant 2 : i32 - %0 = hlfir.any %arg0 dim %dim : (!hlfir.expr>, i32) -> !hlfir.expr> - return %0 : !hlfir.expr> -} -// CHECK-LABEL: func.func @test_partial_expr( -// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !hlfir.expr>) -> !hlfir.expr> { -// CHECK: %[[VAL_1:.*]] = arith.constant 1 : index -// CHECK: %[[VAL_2:.*]] = arith.constant false -// CHECK: %[[VAL_3:.*]] = hlfir.shape_of %[[VAL_0]] : (!hlfir.expr>) -> !fir.shape<3> -// CHECK: %[[VAL_4:.*]] = hlfir.get_extent %[[VAL_3]] {dim = 0 : index} : (!fir.shape<3>) -> index -// CHECK: %[[VAL_5:.*]] = hlfir.get_extent %[[VAL_3]] {dim = 1 : index} : (!fir.shape<3>) -> index -// CHECK: %[[VAL_6:.*]] = hlfir.get_extent %[[VAL_3]] {dim = 2 : index} : (!fir.shape<3>) -> index -// CHECK: %[[VAL_7:.*]] = fir.shape %[[VAL_4]], %[[VAL_6]] : (index, index) -> !fir.shape<2> -// CHECK: %[[VAL_8:.*]] = hlfir.elemental %[[VAL_7]] unordered : (!fir.shape<2>) -> !hlfir.expr> { -// CHECK: ^bb0(%[[VAL_9:.*]]: index, %[[VAL_10:.*]]: index): -// CHECK: %[[VAL_11:.*]] = fir.do_loop %[[VAL_12:.*]] = %[[VAL_1]] to %[[VAL_5]] step %[[VAL_1]] unordered iter_args(%[[VAL_13:.*]] = %[[VAL_2]]) -> (i1) { -// CHECK: %[[VAL_14:.*]] = hlfir.apply %[[VAL_0]], %[[VAL_9]], %[[VAL_12]], %[[VAL_10]] : (!hlfir.expr>, index, index, index) -> !fir.logical<1> -// CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_14]] : (!fir.logical<1>) -> i1 -// CHECK: %[[VAL_16:.*]] = arith.ori %[[VAL_15]], %[[VAL_13]] : i1 -// CHECK: fir.result %[[VAL_16]] : i1 -// CHECK: } -// CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_11]] : (i1) -> !fir.logical<1> -// CHECK: hlfir.yield_element %[[VAL_17]] : !fir.logical<1> -// CHECK: } -// CHECK: return %[[VAL_8]] : !hlfir.expr> -// CHECK: } - -func.func @test_total_var(%arg0: !fir.box>>) -> !fir.logical<4> { - %0 = hlfir.any %arg0 : (!fir.box>>) -> !fir.logical<4> - return %0 : !fir.logical<4> -} -// CHECK-LABEL: func.func @test_total_var( -// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box>>) -> !fir.logical<4> { -// CHECK: %[[VAL_1:.*]] = arith.constant false -// CHECK: %[[VAL_2:.*]] = arith.constant 1 : index -// CHECK: %[[VAL_3:.*]] = arith.constant 0 : index -// CHECK: %[[VAL_4:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_5:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_2]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_6:.*]] = fir.do_loop %[[VAL_7:.*]] = %[[VAL_2]] to %[[VAL_5]]#1 step %[[VAL_2]] unordered iter_args(%[[VAL_8:.*]] = %[[VAL_1]]) -> (i1) { -// CHECK: %[[VAL_9:.*]] = fir.do_loop %[[VAL_10:.*]] = %[[VAL_2]] to %[[VAL_4]]#1 step %[[VAL_2]] unordered iter_args(%[[VAL_11:.*]] = %[[VAL_8]]) -> (i1) { -// CHECK: %[[VAL_12:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_13:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_2]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_14:.*]] = arith.subi %[[VAL_12]]#0, %[[VAL_2]] : index -// CHECK: %[[VAL_15:.*]] = arith.addi %[[VAL_10]], %[[VAL_14]] : index -// CHECK: %[[VAL_16:.*]] = arith.subi %[[VAL_13]]#0, %[[VAL_2]] : index -// CHECK: %[[VAL_17:.*]] = arith.addi %[[VAL_7]], %[[VAL_16]] : index -// CHECK: %[[VAL_18:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_15]], %[[VAL_17]]) : (!fir.box>>, index, index) -> !fir.ref> -// CHECK: %[[VAL_19:.*]] = fir.load %[[VAL_18]] : !fir.ref> -// CHECK: %[[VAL_20:.*]] = fir.convert %[[VAL_19]] : (!fir.logical<4>) -> i1 -// CHECK: %[[VAL_21:.*]] = arith.ori %[[VAL_20]], %[[VAL_11]] : i1 -// CHECK: fir.result %[[VAL_21]] : i1 -// CHECK: } -// CHECK: fir.result %[[VAL_9]] : i1 -// CHECK: } -// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_6]] : (i1) -> !fir.logical<4> -// CHECK: return %[[VAL_22]] : !fir.logical<4> -// CHECK: } - -func.func @test_partial_var(%arg0: !fir.box>>) -> !hlfir.expr> { - %dim = arith.constant 2 : i32 - %0 = hlfir.any %arg0 dim %dim : (!fir.box>>, i32) -> !hlfir.expr> - return %0 : !hlfir.expr> -} -// CHECK-LABEL: func.func @test_partial_var( -// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box>>) -> !hlfir.expr> { -// CHECK: %[[VAL_1:.*]] = arith.constant false -// CHECK: %[[VAL_2:.*]] = arith.constant 2 : index -// CHECK: %[[VAL_3:.*]] = arith.constant 1 : index -// CHECK: %[[VAL_4:.*]] = arith.constant 0 : index -// CHECK: %[[VAL_5:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_6:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_7:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_2]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_8:.*]] = fir.shape %[[VAL_5]]#1, %[[VAL_7]]#1 : (index, index) -> !fir.shape<2> -// CHECK: %[[VAL_9:.*]] = hlfir.elemental %[[VAL_8]] unordered : (!fir.shape<2>) -> !hlfir.expr> { -// CHECK: ^bb0(%[[VAL_10:.*]]: index, %[[VAL_11:.*]]: index): -// CHECK: %[[VAL_12:.*]] = fir.do_loop %[[VAL_13:.*]] = %[[VAL_3]] to %[[VAL_6]]#1 step %[[VAL_3]] unordered iter_args(%[[VAL_14:.*]] = %[[VAL_1]]) -> (i1) { -// CHECK: %[[VAL_15:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_16:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_17:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_2]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_18:.*]] = arith.subi %[[VAL_15]]#0, %[[VAL_3]] : index -// CHECK: %[[VAL_19:.*]] = arith.addi %[[VAL_10]], %[[VAL_18]] : index -// CHECK: %[[VAL_20:.*]] = arith.subi %[[VAL_16]]#0, %[[VAL_3]] : index -// CHECK: %[[VAL_21:.*]] = arith.addi %[[VAL_13]], %[[VAL_20]] : index -// CHECK: %[[VAL_22:.*]] = arith.subi %[[VAL_17]]#0, %[[VAL_3]] : index -// CHECK: %[[VAL_23:.*]] = arith.addi %[[VAL_11]], %[[VAL_22]] : index -// CHECK: %[[VAL_24:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_19]], %[[VAL_21]], %[[VAL_23]]) : (!fir.box>>, index, index, index) -> !fir.ref> -// CHECK: %[[VAL_25:.*]] = fir.load %[[VAL_24]] : !fir.ref> -// CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_25]] : (!fir.logical<2>) -> i1 -// CHECK: %[[VAL_27:.*]] = arith.ori %[[VAL_26]], %[[VAL_14]] : i1 -// CHECK: fir.result %[[VAL_27]] : i1 -// CHECK: } -// CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_12]] : (i1) -> !fir.logical<2> -// CHECK: hlfir.yield_element %[[VAL_28]] : !fir.logical<2> -// CHECK: } -// CHECK: return %[[VAL_9]] : !hlfir.expr> -// CHECK: } diff --git a/flang/test/HLFIR/simplify-hlfir-intrinsics-count.fir b/flang/test/HLFIR/simplify-hlfir-intrinsics-count.fir deleted file mode 100644 index 44594c646a368..0000000000000 --- a/flang/test/HLFIR/simplify-hlfir-intrinsics-count.fir +++ /dev/null @@ -1,127 +0,0 @@ -// RUN: fir-opt %s --simplify-hlfir-intrinsics | FileCheck %s - -func.func @test_total_expr(%arg0: !hlfir.expr>) -> i32 { - %0 = hlfir.count %arg0 : (!hlfir.expr>) -> i32 - return %0 : i32 -} -// CHECK-LABEL: func.func @test_total_expr( -// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !hlfir.expr>) -> i32 { -// CHECK: %[[VAL_1:.*]] = arith.constant 1 : i32 -// CHECK: %[[VAL_2:.*]] = arith.constant 1 : index -// CHECK: %[[VAL_3:.*]] = arith.constant 0 : i32 -// CHECK: %[[VAL_4:.*]] = hlfir.shape_of %[[VAL_0]] : (!hlfir.expr>) -> !fir.shape<2> -// CHECK: %[[VAL_5:.*]] = hlfir.get_extent %[[VAL_4]] {dim = 0 : index} : (!fir.shape<2>) -> index -// CHECK: %[[VAL_6:.*]] = hlfir.get_extent %[[VAL_4]] {dim = 1 : index} : (!fir.shape<2>) -> index -// CHECK: %[[VAL_7:.*]] = fir.do_loop %[[VAL_8:.*]] = %[[VAL_2]] to %[[VAL_6]] step %[[VAL_2]] unordered iter_args(%[[VAL_9:.*]] = %[[VAL_3]]) -> (i32) { -// CHECK: %[[VAL_10:.*]] = fir.do_loop %[[VAL_11:.*]] = %[[VAL_2]] to %[[VAL_5]] step %[[VAL_2]] unordered iter_args(%[[VAL_12:.*]] = %[[VAL_9]]) -> (i32) { -// CHECK: %[[VAL_13:.*]] = hlfir.apply %[[VAL_0]], %[[VAL_11]], %[[VAL_8]] : (!hlfir.expr>, index, index) -> !fir.logical<4> -// CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_13]] : (!fir.logical<4>) -> i1 -// CHECK: %[[VAL_15:.*]] = arith.addi %[[VAL_12]], %[[VAL_1]] : i32 -// CHECK: %[[VAL_16:.*]] = arith.select %[[VAL_14]], %[[VAL_15]], %[[VAL_12]] : i32 -// CHECK: fir.result %[[VAL_16]] : i32 -// CHECK: } -// CHECK: fir.result %[[VAL_10]] : i32 -// CHECK: } -// CHECK: return %[[VAL_7]] : i32 -// CHECK: } - -func.func @test_partial_expr(%arg0: !hlfir.expr>) -> !hlfir.expr { - %dim = arith.constant 2 : i32 - %0 = hlfir.count %arg0 dim %dim : (!hlfir.expr>, i32) -> !hlfir.expr - return %0 : !hlfir.expr -} -// CHECK-LABEL: func.func @test_partial_expr( -// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !hlfir.expr>) -> !hlfir.expr { -// CHECK: %[[VAL_1:.*]] = arith.constant 1 : i16 -// CHECK: %[[VAL_2:.*]] = arith.constant 1 : index -// CHECK: %[[VAL_3:.*]] = arith.constant 0 : i16 -// CHECK: %[[VAL_4:.*]] = hlfir.shape_of %[[VAL_0]] : (!hlfir.expr>) -> !fir.shape<3> -// CHECK: %[[VAL_5:.*]] = hlfir.get_extent %[[VAL_4]] {dim = 0 : index} : (!fir.shape<3>) -> index -// CHECK: %[[VAL_6:.*]] = hlfir.get_extent %[[VAL_4]] {dim = 1 : index} : (!fir.shape<3>) -> index -// CHECK: %[[VAL_7:.*]] = hlfir.get_extent %[[VAL_4]] {dim = 2 : index} : (!fir.shape<3>) -> index -// CHECK: %[[VAL_8:.*]] = fir.shape %[[VAL_5]], %[[VAL_7]] : (index, index) -> !fir.shape<2> -// CHECK: %[[VAL_9:.*]] = hlfir.elemental %[[VAL_8]] unordered : (!fir.shape<2>) -> !hlfir.expr { -// CHECK: ^bb0(%[[VAL_10:.*]]: index, %[[VAL_11:.*]]: index): -// CHECK: %[[VAL_12:.*]] = fir.do_loop %[[VAL_13:.*]] = %[[VAL_2]] to %[[VAL_6]] step %[[VAL_2]] unordered iter_args(%[[VAL_14:.*]] = %[[VAL_3]]) -> (i16) { -// CHECK: %[[VAL_15:.*]] = hlfir.apply %[[VAL_0]], %[[VAL_10]], %[[VAL_13]], %[[VAL_11]] : (!hlfir.expr>, index, index, index) -> !fir.logical<1> -// CHECK: %[[VAL_16:.*]] = fir.convert %[[VAL_15]] : (!fir.logical<1>) -> i1 -// CHECK: %[[VAL_17:.*]] = arith.addi %[[VAL_14]], %[[VAL_1]] : i16 -// CHECK: %[[VAL_18:.*]] = arith.select %[[VAL_16]], %[[VAL_17]], %[[VAL_14]] : i16 -// CHECK: fir.result %[[VAL_18]] : i16 -// CHECK: } -// CHECK: hlfir.yield_element %[[VAL_12]] : i16 -// CHECK: } -// CHECK: return %[[VAL_9]] : !hlfir.expr -// CHECK: } - -func.func @test_total_var(%arg0: !fir.box>>) -> i32 { - %0 = hlfir.count %arg0 : (!fir.box>>) -> i32 - return %0 : i32 -} -// CHECK-LABEL: func.func @test_total_var( -// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box>>) -> i32 { -// CHECK: %[[VAL_1:.*]] = arith.constant 1 : i32 -// CHECK: %[[VAL_2:.*]] = arith.constant 0 : i32 -// CHECK: %[[VAL_3:.*]] = arith.constant 1 : index -// CHECK: %[[VAL_4:.*]] = arith.constant 0 : index -// CHECK: %[[VAL_5:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_6:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_7:.*]] = fir.do_loop %[[VAL_8:.*]] = %[[VAL_3]] to %[[VAL_6]]#1 step %[[VAL_3]] unordered iter_args(%[[VAL_9:.*]] = %[[VAL_2]]) -> (i32) { -// CHECK: %[[VAL_10:.*]] = fir.do_loop %[[VAL_11:.*]] = %[[VAL_3]] to %[[VAL_5]]#1 step %[[VAL_3]] unordered iter_args(%[[VAL_12:.*]] = %[[VAL_9]]) -> (i32) { -// CHECK: %[[VAL_13:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_14:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_15:.*]] = arith.subi %[[VAL_13]]#0, %[[VAL_3]] : index -// CHECK: %[[VAL_16:.*]] = arith.addi %[[VAL_11]], %[[VAL_15]] : index -// CHECK: %[[VAL_17:.*]] = arith.subi %[[VAL_14]]#0, %[[VAL_3]] : index -// CHECK: %[[VAL_18:.*]] = arith.addi %[[VAL_8]], %[[VAL_17]] : index -// CHECK: %[[VAL_19:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_16]], %[[VAL_18]]) : (!fir.box>>, index, index) -> !fir.ref> -// CHECK: %[[VAL_20:.*]] = fir.load %[[VAL_19]] : !fir.ref> -// CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_20]] : (!fir.logical<4>) -> i1 -// CHECK: %[[VAL_22:.*]] = arith.addi %[[VAL_12]], %[[VAL_1]] : i32 -// CHECK: %[[VAL_23:.*]] = arith.select %[[VAL_21]], %[[VAL_22]], %[[VAL_12]] : i32 -// CHECK: fir.result %[[VAL_23]] : i32 -// CHECK: } -// CHECK: fir.result %[[VAL_10]] : i32 -// CHECK: } -// CHECK: return %[[VAL_7]] : i32 -// CHECK: } - -func.func @test_partial_var(%arg0: !fir.box>>) -> !hlfir.expr { - %dim = arith.constant 2 : i32 - %0 = hlfir.count %arg0 dim %dim : (!fir.box>>, i32) -> !hlfir.expr - return %0 : !hlfir.expr -} -// CHECK-LABEL: func.func @test_partial_var( -// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box>>) -> !hlfir.expr { -// CHECK: %[[VAL_1:.*]] = arith.constant 1 : i64 -// CHECK: %[[VAL_2:.*]] = arith.constant 0 : i64 -// CHECK: %[[VAL_3:.*]] = arith.constant 2 : index -// CHECK: %[[VAL_4:.*]] = arith.constant 1 : index -// CHECK: %[[VAL_5:.*]] = arith.constant 0 : index -// CHECK: %[[VAL_6:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_7:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_8:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_9:.*]] = fir.shape %[[VAL_6]]#1, %[[VAL_8]]#1 : (index, index) -> !fir.shape<2> -// CHECK: %[[VAL_10:.*]] = hlfir.elemental %[[VAL_9]] unordered : (!fir.shape<2>) -> !hlfir.expr { -// CHECK: ^bb0(%[[VAL_11:.*]]: index, %[[VAL_12:.*]]: index): -// CHECK: %[[VAL_13:.*]] = fir.do_loop %[[VAL_14:.*]] = %[[VAL_4]] to %[[VAL_7]]#1 step %[[VAL_4]] unordered iter_args(%[[VAL_15:.*]] = %[[VAL_2]]) -> (i64) { -// CHECK: %[[VAL_16:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_17:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_18:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_19:.*]] = arith.subi %[[VAL_16]]#0, %[[VAL_4]] : index -// CHECK: %[[VAL_20:.*]] = arith.addi %[[VAL_11]], %[[VAL_19]] : index -// CHECK: %[[VAL_21:.*]] = arith.subi %[[VAL_17]]#0, %[[VAL_4]] : index -// CHECK: %[[VAL_22:.*]] = arith.addi %[[VAL_14]], %[[VAL_21]] : index -// CHECK: %[[VAL_23:.*]] = arith.subi %[[VAL_18]]#0, %[[VAL_4]] : index -// CHECK: %[[VAL_24:.*]] = arith.addi %[[VAL_12]], %[[VAL_23]] : index -// CHECK: %[[VAL_25:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_20]], %[[VAL_22]], %[[VAL_24]]) : (!fir.box>>, index, index, index) -> !fir.ref> -// CHECK: %[[VAL_26:.*]] = fir.load %[[VAL_25]] : !fir.ref> -// CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_26]] : (!fir.logical<2>) -> i1 -// CHECK: %[[VAL_28:.*]] = arith.addi %[[VAL_15]], %[[VAL_1]] : i64 -// CHECK: %[[VAL_29:.*]] = arith.select %[[VAL_27]], %[[VAL_28]], %[[VAL_15]] : i64 -// CHECK: fir.result %[[VAL_29]] : i64 -// CHECK: } -// CHECK: hlfir.yield_element %[[VAL_13]] : i64 -// CHECK: } -// CHECK: return %[[VAL_10]] : !hlfir.expr -// CHECK: } diff --git a/flang/test/HLFIR/simplify-hlfir-intrinsics-maxloc.fir b/flang/test/HLFIR/simplify-hlfir-intrinsics-maxloc.fir deleted file mode 100644 index 49e3bb6936338..0000000000000 --- a/flang/test/HLFIR/simplify-hlfir-intrinsics-maxloc.fir +++ /dev/null @@ -1,343 +0,0 @@ -// RUN: fir-opt %s --simplify-hlfir-intrinsics | FileCheck %s - -func.func @test_1d_total_expr(%input: !hlfir.expr, %mask: !hlfir.expr>) -> !hlfir.expr<1xi32> { - %0 = hlfir.maxloc %input mask %mask {fastmath = #arith.fastmath} : (!hlfir.expr, !hlfir.expr>) -> !hlfir.expr<1xi32> - return %0 : !hlfir.expr<1xi32> -} -// CHECK-LABEL: func.func @test_1d_total_expr( -// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !hlfir.expr, -// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !hlfir.expr>) -> !hlfir.expr<1xi32> { -// CHECK: %[[VAL_2:.*]] = arith.constant false -// CHECK: %[[VAL_3:.*]] = arith.constant 1 : index -// CHECK: %[[VAL_4:.*]] = arith.constant true -// CHECK: %[[VAL_5:.*]] = arith.constant -2147483648 : i32 -// CHECK: %[[VAL_6:.*]] = arith.constant 0 : i32 -// CHECK: %[[VAL_7:.*]] = fir.alloca !fir.array<1xi32> -// CHECK: %[[VAL_8:.*]] = hlfir.shape_of %[[VAL_0]] : (!hlfir.expr) -> !fir.shape<1> -// CHECK: %[[VAL_9:.*]] = hlfir.get_extent %[[VAL_8]] {dim = 0 : index} : (!fir.shape<1>) -> index -// CHECK: %[[VAL_10:.*]]:3 = fir.do_loop %[[VAL_11:.*]] = %[[VAL_3]] to %[[VAL_9]] step %[[VAL_3]] unordered iter_args(%[[VAL_12:.*]] = %[[VAL_6]], %[[VAL_13:.*]] = %[[VAL_5]], %[[VAL_14:.*]] = %[[VAL_4]]) -> (i32, i32, i1) { -// CHECK: %[[VAL_15:.*]] = hlfir.apply %[[VAL_1]], %[[VAL_11]] : (!hlfir.expr>, index) -> !fir.logical<4> -// CHECK: %[[VAL_16:.*]] = fir.convert %[[VAL_15]] : (!fir.logical<4>) -> i1 -// CHECK: %[[VAL_17:.*]]:3 = fir.if %[[VAL_16]] -> (i32, i32, i1) { -// CHECK: %[[VAL_18:.*]] = hlfir.apply %[[VAL_0]], %[[VAL_11]] : (!hlfir.expr, index) -> i32 -// CHECK: %[[VAL_19:.*]] = arith.cmpi sgt, %[[VAL_18]], %[[VAL_13]] : i32 -// CHECK: %[[VAL_20:.*]] = arith.ori %[[VAL_19]], %[[VAL_14]] : i1 -// CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_11]] : (index) -> i32 -// CHECK: %[[VAL_22:.*]] = arith.select %[[VAL_20]], %[[VAL_21]], %[[VAL_12]] : i32 -// CHECK: %[[VAL_23:.*]] = arith.select %[[VAL_20]], %[[VAL_18]], %[[VAL_13]] : i32 -// CHECK: fir.result %[[VAL_22]], %[[VAL_23]], %[[VAL_2]] : i32, i32, i1 -// CHECK: } else { -// CHECK: fir.result %[[VAL_12]], %[[VAL_13]], %[[VAL_14]] : i32, i32, i1 -// CHECK: } -// CHECK: fir.result %[[VAL_24:.*]]#0, %[[VAL_24]]#1, %[[VAL_24]]#2 : i32, i32, i1 -// CHECK: } -// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_26:.*]]#0 : (i32) -> index -// CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_25]] : (index) -> i32 -// CHECK: %[[VAL_28:.*]] = hlfir.designate %[[VAL_7]] (%[[VAL_3]]) : (!fir.ref>, index) -> !fir.ref -// CHECK: hlfir.assign %[[VAL_27]] to %[[VAL_28]] : i32, !fir.ref -// CHECK: %[[VAL_29:.*]] = hlfir.as_expr %[[VAL_7]] move %[[VAL_2]] : (!fir.ref>, i1) -> !hlfir.expr<1xi32> -// CHECK: return %[[VAL_29]] : !hlfir.expr<1xi32> -// CHECK: } - -func.func @test_1d_dim_expr(%input: !hlfir.expr, %mask: !hlfir.expr>) -> i32 { - %dim = arith.constant 1 : i16 - %0 = hlfir.maxloc %input dim %dim mask %mask {fastmath = #arith.fastmath} : (!hlfir.expr, i16, !hlfir.expr>) -> i32 - return %0 : i32 -} -// CHECK-LABEL: func.func @test_1d_dim_expr( -// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !hlfir.expr, -// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !hlfir.expr>) -> i32 { -// CHECK: %[[VAL_2:.*]] = arith.constant false -// CHECK: %[[VAL_3:.*]] = arith.constant 1 : index -// CHECK: %[[VAL_4:.*]] = arith.constant true -// CHECK: %[[VAL_5:.*]] = arith.constant -3.40282347E+38 : f32 -// CHECK: %[[VAL_6:.*]] = arith.constant 0 : i32 -// CHECK: %[[VAL_7:.*]] = hlfir.shape_of %[[VAL_0]] : (!hlfir.expr) -> !fir.shape<1> -// CHECK: %[[VAL_8:.*]] = hlfir.get_extent %[[VAL_7]] {dim = 0 : index} : (!fir.shape<1>) -> index -// CHECK: %[[VAL_9:.*]]:3 = fir.do_loop %[[VAL_10:.*]] = %[[VAL_3]] to %[[VAL_8]] step %[[VAL_3]] iter_args(%[[VAL_11:.*]] = %[[VAL_6]], %[[VAL_12:.*]] = %[[VAL_5]], %[[VAL_13:.*]] = %[[VAL_4]]) -> (i32, f32, i1) { -// CHECK: %[[VAL_14:.*]] = hlfir.apply %[[VAL_1]], %[[VAL_10]] : (!hlfir.expr>, index) -> !fir.logical<4> -// CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_14]] : (!fir.logical<4>) -> i1 -// CHECK: %[[VAL_16:.*]]:3 = fir.if %[[VAL_15]] -> (i32, f32, i1) { -// CHECK: %[[VAL_17:.*]] = hlfir.apply %[[VAL_0]], %[[VAL_10]] : (!hlfir.expr, index) -> f32 -// CHECK: %[[VAL_18:.*]] = arith.cmpf ogt, %[[VAL_17]], %[[VAL_12]] fastmath : f32 -// CHECK: %[[VAL_19:.*]] = arith.cmpf une, %[[VAL_12]], %[[VAL_12]] fastmath : f32 -// CHECK: %[[VAL_20:.*]] = arith.cmpf oeq, %[[VAL_17]], %[[VAL_17]] fastmath : f32 -// CHECK: %[[VAL_21:.*]] = arith.andi %[[VAL_19]], %[[VAL_20]] : i1 -// CHECK: %[[VAL_22:.*]] = arith.ori %[[VAL_18]], %[[VAL_21]] : i1 -// CHECK: %[[VAL_23:.*]] = arith.ori %[[VAL_22]], %[[VAL_13]] : i1 -// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_10]] : (index) -> i32 -// CHECK: %[[VAL_25:.*]] = arith.select %[[VAL_23]], %[[VAL_24]], %[[VAL_11]] : i32 -// CHECK: %[[VAL_26:.*]] = arith.select %[[VAL_23]], %[[VAL_17]], %[[VAL_12]] : f32 -// CHECK: fir.result %[[VAL_25]], %[[VAL_26]], %[[VAL_2]] : i32, f32, i1 -// CHECK: } else { -// CHECK: fir.result %[[VAL_11]], %[[VAL_12]], %[[VAL_13]] : i32, f32, i1 -// CHECK: } -// CHECK: fir.result %[[VAL_27:.*]]#0, %[[VAL_27]]#1, %[[VAL_27]]#2 : i32, f32, i1 -// CHECK: } -// CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_29:.*]]#0 : (i32) -> index -// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_28]] : (index) -> i32 -// CHECK: return %[[VAL_30]] : i32 -// CHECK: } - -func.func @test_1d_total_var(%input: !fir.box>, %mask: !hlfir.expr>) -> !hlfir.expr<1xi16> { - %0 = hlfir.maxloc %input mask %mask {fastmath = #arith.fastmath} : (!fir.box>, !hlfir.expr>) -> !hlfir.expr<1xi16> - return %0 : !hlfir.expr<1xi16> -} -// CHECK-LABEL: func.func @test_1d_total_var( -// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box>, -// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !hlfir.expr>) -> !hlfir.expr<1xi16> { -// CHECK: %[[VAL_2:.*]] = arith.constant false -// CHECK: %[[VAL_3:.*]] = arith.constant 1 : index -// CHECK: %[[VAL_4:.*]] = arith.constant true -// CHECK: %[[VAL_5:.*]] = arith.constant -3.40282347E+38 : f32 -// CHECK: %[[VAL_6:.*]] = arith.constant 0 : i16 -// CHECK: %[[VAL_7:.*]] = arith.constant 0 : index -// CHECK: %[[VAL_8:.*]] = fir.alloca !fir.array<1xi16> -// CHECK: %[[VAL_9:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_7]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_10:.*]]:3 = fir.do_loop %[[VAL_11:.*]] = %[[VAL_3]] to %[[VAL_9]]#1 step %[[VAL_3]] iter_args(%[[VAL_12:.*]] = %[[VAL_6]], %[[VAL_13:.*]] = %[[VAL_5]], %[[VAL_14:.*]] = %[[VAL_4]]) -> (i16, f32, i1) { -// CHECK: %[[VAL_15:.*]] = hlfir.apply %[[VAL_1]], %[[VAL_11]] : (!hlfir.expr>, index) -> !fir.logical<4> -// CHECK: %[[VAL_16:.*]] = fir.convert %[[VAL_15]] : (!fir.logical<4>) -> i1 -// CHECK: %[[VAL_17:.*]]:3 = fir.if %[[VAL_16]] -> (i16, f32, i1) { -// CHECK: %[[VAL_18:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_7]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_19:.*]] = arith.subi %[[VAL_18]]#0, %[[VAL_3]] : index -// CHECK: %[[VAL_20:.*]] = arith.addi %[[VAL_11]], %[[VAL_19]] : index -// CHECK: %[[VAL_21:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_20]]) : (!fir.box>, index) -> !fir.ref -// CHECK: %[[VAL_22:.*]] = fir.load %[[VAL_21]] : !fir.ref -// CHECK: %[[VAL_23:.*]] = arith.cmpf ogt, %[[VAL_22]], %[[VAL_13]] fastmath : f32 -// CHECK: %[[VAL_24:.*]] = arith.cmpf une, %[[VAL_13]], %[[VAL_13]] fastmath : f32 -// CHECK: %[[VAL_25:.*]] = arith.cmpf oeq, %[[VAL_22]], %[[VAL_22]] fastmath : f32 -// CHECK: %[[VAL_26:.*]] = arith.andi %[[VAL_24]], %[[VAL_25]] : i1 -// CHECK: %[[VAL_27:.*]] = arith.ori %[[VAL_23]], %[[VAL_26]] : i1 -// CHECK: %[[VAL_28:.*]] = arith.ori %[[VAL_27]], %[[VAL_14]] : i1 -// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_11]] : (index) -> i16 -// CHECK: %[[VAL_30:.*]] = arith.select %[[VAL_28]], %[[VAL_29]], %[[VAL_12]] : i16 -// CHECK: %[[VAL_31:.*]] = arith.select %[[VAL_28]], %[[VAL_22]], %[[VAL_13]] : f32 -// CHECK: fir.result %[[VAL_30]], %[[VAL_31]], %[[VAL_2]] : i16, f32, i1 -// CHECK: } else { -// CHECK: fir.result %[[VAL_12]], %[[VAL_13]], %[[VAL_14]] : i16, f32, i1 -// CHECK: } -// CHECK: fir.result %[[VAL_32:.*]]#0, %[[VAL_32]]#1, %[[VAL_32]]#2 : i16, f32, i1 -// CHECK: } -// CHECK: %[[VAL_33:.*]] = arith.cmpi ne, %[[VAL_34:.*]]#0, %[[VAL_6]] : i16 -// CHECK: %[[VAL_35:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_7]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_34]]#0 : (i16) -> index -// CHECK: %[[VAL_37:.*]] = arith.addi %[[VAL_36]], %[[VAL_35]]#0 : index -// CHECK: %[[VAL_38:.*]] = arith.subi %[[VAL_37]], %[[VAL_3]] : index -// CHECK: %[[VAL_39:.*]] = arith.select %[[VAL_33]], %[[VAL_38]], %[[VAL_36]] : index -// CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_39]] : (index) -> i16 -// CHECK: %[[VAL_41:.*]] = hlfir.designate %[[VAL_8]] (%[[VAL_3]]) : (!fir.ref>, index) -> !fir.ref -// CHECK: hlfir.assign %[[VAL_40]] to %[[VAL_41]] : i16, !fir.ref -// CHECK: %[[VAL_42:.*]] = hlfir.as_expr %[[VAL_8]] move %[[VAL_2]] : (!fir.ref>, i1) -> !hlfir.expr<1xi16> -// CHECK: return %[[VAL_42]] : !hlfir.expr<1xi16> -// CHECK: } - -func.func @test_1d_dim_var(%input: !fir.box>, %mask: !hlfir.expr>) -> i64 { - %dim = arith.constant 1 : i32 - %0 = hlfir.maxloc %input dim %dim mask %mask {fastmath = #arith.fastmath} : (!fir.box>, i32, !hlfir.expr>) -> i64 - return %0 : i64 -} -// CHECK-LABEL: func.func @test_1d_dim_var( -// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box>, -// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !hlfir.expr>) -> i64 { -// CHECK: %[[VAL_2:.*]] = arith.constant false -// CHECK: %[[VAL_3:.*]] = arith.constant 1 : index -// CHECK: %[[VAL_4:.*]] = arith.constant true -// CHECK: %[[VAL_5:.*]] = arith.constant -1.7976931348623157E+308 : f64 -// CHECK: %[[VAL_6:.*]] = arith.constant 0 : i64 -// CHECK: %[[VAL_7:.*]] = arith.constant 0 : index -// CHECK: %[[VAL_8:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_7]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_9:.*]]:3 = fir.do_loop %[[VAL_10:.*]] = %[[VAL_3]] to %[[VAL_8]]#1 step %[[VAL_3]] iter_args(%[[VAL_11:.*]] = %[[VAL_6]], %[[VAL_12:.*]] = %[[VAL_5]], %[[VAL_13:.*]] = %[[VAL_4]]) -> (i64, f64, i1) { -// CHECK: %[[VAL_14:.*]] = hlfir.apply %[[VAL_1]], %[[VAL_10]] : (!hlfir.expr>, index) -> !fir.logical<4> -// CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_14]] : (!fir.logical<4>) -> i1 -// CHECK: %[[VAL_16:.*]]:3 = fir.if %[[VAL_15]] -> (i64, f64, i1) { -// CHECK: %[[VAL_17:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_7]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_18:.*]] = arith.subi %[[VAL_17]]#0, %[[VAL_3]] : index -// CHECK: %[[VAL_19:.*]] = arith.addi %[[VAL_10]], %[[VAL_18]] : index -// CHECK: %[[VAL_20:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_19]]) : (!fir.box>, index) -> !fir.ref -// CHECK: %[[VAL_21:.*]] = fir.load %[[VAL_20]] : !fir.ref -// CHECK: %[[VAL_22:.*]] = arith.cmpf ogt, %[[VAL_21]], %[[VAL_12]] fastmath : f64 -// CHECK: %[[VAL_23:.*]] = arith.cmpf une, %[[VAL_12]], %[[VAL_12]] fastmath : f64 -// CHECK: %[[VAL_24:.*]] = arith.cmpf oeq, %[[VAL_21]], %[[VAL_21]] fastmath : f64 -// CHECK: %[[VAL_25:.*]] = arith.andi %[[VAL_23]], %[[VAL_24]] : i1 -// CHECK: %[[VAL_26:.*]] = arith.ori %[[VAL_22]], %[[VAL_25]] : i1 -// CHECK: %[[VAL_27:.*]] = arith.ori %[[VAL_26]], %[[VAL_13]] : i1 -// CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_10]] : (index) -> i64 -// CHECK: %[[VAL_29:.*]] = arith.select %[[VAL_27]], %[[VAL_28]], %[[VAL_11]] : i64 -// CHECK: %[[VAL_30:.*]] = arith.select %[[VAL_27]], %[[VAL_21]], %[[VAL_12]] : f64 -// CHECK: fir.result %[[VAL_29]], %[[VAL_30]], %[[VAL_2]] : i64, f64, i1 -// CHECK: } else { -// CHECK: fir.result %[[VAL_11]], %[[VAL_12]], %[[VAL_13]] : i64, f64, i1 -// CHECK: } -// CHECK: fir.result %[[VAL_31:.*]]#0, %[[VAL_31]]#1, %[[VAL_31]]#2 : i64, f64, i1 -// CHECK: } -// CHECK: %[[VAL_32:.*]] = arith.cmpi ne, %[[VAL_33:.*]]#0, %[[VAL_6]] : i64 -// CHECK: %[[VAL_34:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_7]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_33]]#0 : (i64) -> index -// CHECK: %[[VAL_36:.*]] = arith.addi %[[VAL_35]], %[[VAL_34]]#0 : index -// CHECK: %[[VAL_37:.*]] = arith.subi %[[VAL_36]], %[[VAL_3]] : index -// CHECK: %[[VAL_38:.*]] = arith.select %[[VAL_32]], %[[VAL_37]], %[[VAL_35]] : index -// CHECK: %[[VAL_39:.*]] = fir.convert %[[VAL_38]] : (index) -> i64 -// CHECK: return %[[VAL_39]] : i64 -// CHECK: } - -func.func @test_total_expr(%input: !hlfir.expr, %mask: !hlfir.expr>) -> !hlfir.expr<3xi32> { - %0 = hlfir.maxloc %input mask %mask {fastmath = #arith.fastmath} : (!hlfir.expr, !hlfir.expr>) -> !hlfir.expr<3xi32> - return %0 : !hlfir.expr<3xi32> -} -// CHECK-LABEL: func.func @test_total_expr( -// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !hlfir.expr, -// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !hlfir.expr>) -> !hlfir.expr<3xi32> { -// CHECK: %[[VAL_2:.*]] = arith.constant 3 : index -// CHECK: %[[VAL_3:.*]] = arith.constant 2 : index -// CHECK: %[[VAL_4:.*]] = arith.constant false -// CHECK: %[[VAL_5:.*]] = arith.constant 1 : index -// CHECK: %[[VAL_6:.*]] = arith.constant true -// CHECK: %[[VAL_7:.*]] = arith.constant -3.40282347E+38 : f32 -// CHECK: %[[VAL_8:.*]] = arith.constant 0 : i32 -// CHECK: %[[VAL_9:.*]] = fir.alloca !fir.array<3xi32> -// CHECK: %[[VAL_10:.*]] = hlfir.shape_of %[[VAL_0]] : (!hlfir.expr) -> !fir.shape<3> -// CHECK: %[[VAL_11:.*]] = hlfir.get_extent %[[VAL_10]] {dim = 0 : index} : (!fir.shape<3>) -> index -// CHECK: %[[VAL_12:.*]] = hlfir.get_extent %[[VAL_10]] {dim = 1 : index} : (!fir.shape<3>) -> index -// CHECK: %[[VAL_13:.*]] = hlfir.get_extent %[[VAL_10]] {dim = 2 : index} : (!fir.shape<3>) -> index -// CHECK: %[[VAL_14:.*]]:5 = fir.do_loop %[[VAL_15:.*]] = %[[VAL_5]] to %[[VAL_13]] step %[[VAL_5]] unordered iter_args(%[[VAL_16:.*]] = %[[VAL_8]], %[[VAL_17:.*]] = %[[VAL_8]], %[[VAL_18:.*]] = %[[VAL_8]], %[[VAL_19:.*]] = %[[VAL_7]], %[[VAL_20:.*]] = %[[VAL_6]]) -> (i32, i32, i32, f32, i1) { -// CHECK: %[[VAL_21:.*]]:5 = fir.do_loop %[[VAL_22:.*]] = %[[VAL_5]] to %[[VAL_12]] step %[[VAL_5]] unordered iter_args(%[[VAL_23:.*]] = %[[VAL_16]], %[[VAL_24:.*]] = %[[VAL_17]], %[[VAL_25:.*]] = %[[VAL_18]], %[[VAL_26:.*]] = %[[VAL_19]], %[[VAL_27:.*]] = %[[VAL_20]]) -> (i32, i32, i32, f32, i1) { -// CHECK: %[[VAL_28:.*]]:5 = fir.do_loop %[[VAL_29:.*]] = %[[VAL_5]] to %[[VAL_11]] step %[[VAL_5]] unordered iter_args(%[[VAL_30:.*]] = %[[VAL_23]], %[[VAL_31:.*]] = %[[VAL_24]], %[[VAL_32:.*]] = %[[VAL_25]], %[[VAL_33:.*]] = %[[VAL_26]], %[[VAL_34:.*]] = %[[VAL_27]]) -> (i32, i32, i32, f32, i1) { -// CHECK: %[[VAL_35:.*]] = hlfir.apply %[[VAL_1]], %[[VAL_29]], %[[VAL_22]], %[[VAL_15]] : (!hlfir.expr>, index, index, index) -> !fir.logical<4> -// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_35]] : (!fir.logical<4>) -> i1 -// CHECK: %[[VAL_37:.*]]:5 = fir.if %[[VAL_36]] -> (i32, i32, i32, f32, i1) { -// CHECK: %[[VAL_38:.*]] = hlfir.apply %[[VAL_0]], %[[VAL_29]], %[[VAL_22]], %[[VAL_15]] : (!hlfir.expr, index, index, index) -> f32 -// CHECK: %[[VAL_39:.*]] = arith.cmpf ogt, %[[VAL_38]], %[[VAL_33]] fastmath : f32 -// CHECK: %[[VAL_40:.*]] = arith.cmpf une, %[[VAL_33]], %[[VAL_33]] fastmath : f32 -// CHECK: %[[VAL_41:.*]] = arith.cmpf oeq, %[[VAL_38]], %[[VAL_38]] fastmath : f32 -// CHECK: %[[VAL_42:.*]] = arith.andi %[[VAL_40]], %[[VAL_41]] : i1 -// CHECK: %[[VAL_43:.*]] = arith.ori %[[VAL_39]], %[[VAL_42]] : i1 -// CHECK: %[[VAL_44:.*]] = arith.ori %[[VAL_43]], %[[VAL_34]] : i1 -// CHECK: %[[VAL_45:.*]] = fir.convert %[[VAL_29]] : (index) -> i32 -// CHECK: %[[VAL_46:.*]] = arith.select %[[VAL_44]], %[[VAL_45]], %[[VAL_30]] : i32 -// CHECK: %[[VAL_47:.*]] = fir.convert %[[VAL_22]] : (index) -> i32 -// CHECK: %[[VAL_48:.*]] = arith.select %[[VAL_44]], %[[VAL_47]], %[[VAL_31]] : i32 -// CHECK: %[[VAL_49:.*]] = fir.convert %[[VAL_15]] : (index) -> i32 -// CHECK: %[[VAL_50:.*]] = arith.select %[[VAL_44]], %[[VAL_49]], %[[VAL_32]] : i32 -// CHECK: %[[VAL_51:.*]] = arith.select %[[VAL_44]], %[[VAL_38]], %[[VAL_33]] : f32 -// CHECK: fir.result %[[VAL_46]], %[[VAL_48]], %[[VAL_50]], %[[VAL_51]], %[[VAL_4]] : i32, i32, i32, f32, i1 -// CHECK: } else { -// CHECK: fir.result %[[VAL_30]], %[[VAL_31]], %[[VAL_32]], %[[VAL_33]], %[[VAL_34]] : i32, i32, i32, f32, i1 -// CHECK: } -// CHECK: fir.result %[[VAL_52:.*]]#0, %[[VAL_52]]#1, %[[VAL_52]]#2, %[[VAL_52]]#3, %[[VAL_52]]#4 : i32, i32, i32, f32, i1 -// CHECK: } -// CHECK: fir.result %[[VAL_53:.*]]#0, %[[VAL_53]]#1, %[[VAL_53]]#2, %[[VAL_53]]#3, %[[VAL_53]]#4 : i32, i32, i32, f32, i1 -// CHECK: } -// CHECK: fir.result %[[VAL_54:.*]]#0, %[[VAL_54]]#1, %[[VAL_54]]#2, %[[VAL_54]]#3, %[[VAL_54]]#4 : i32, i32, i32, f32, i1 -// CHECK: } -// CHECK: %[[VAL_55:.*]] = fir.convert %[[VAL_56:.*]]#0 : (i32) -> index -// CHECK: %[[VAL_57:.*]] = fir.convert %[[VAL_55]] : (index) -> i32 -// CHECK: %[[VAL_58:.*]] = hlfir.designate %[[VAL_9]] (%[[VAL_5]]) : (!fir.ref>, index) -> !fir.ref -// CHECK: hlfir.assign %[[VAL_57]] to %[[VAL_58]] : i32, !fir.ref -// CHECK: %[[VAL_59:.*]] = fir.convert %[[VAL_56]]#1 : (i32) -> index -// CHECK: %[[VAL_60:.*]] = fir.convert %[[VAL_59]] : (index) -> i32 -// CHECK: %[[VAL_61:.*]] = hlfir.designate %[[VAL_9]] (%[[VAL_3]]) : (!fir.ref>, index) -> !fir.ref -// CHECK: hlfir.assign %[[VAL_60]] to %[[VAL_61]] : i32, !fir.ref -// CHECK: %[[VAL_62:.*]] = fir.convert %[[VAL_56]]#2 : (i32) -> index -// CHECK: %[[VAL_63:.*]] = fir.convert %[[VAL_62]] : (index) -> i32 -// CHECK: %[[VAL_64:.*]] = hlfir.designate %[[VAL_9]] (%[[VAL_2]]) : (!fir.ref>, index) -> !fir.ref -// CHECK: hlfir.assign %[[VAL_63]] to %[[VAL_64]] : i32, !fir.ref -// CHECK: %[[VAL_65:.*]] = hlfir.as_expr %[[VAL_9]] move %[[VAL_4]] : (!fir.ref>, i1) -> !hlfir.expr<3xi32> -// CHECK: return %[[VAL_65]] : !hlfir.expr<3xi32> -// CHECK: } - -func.func @test_partial_var(%input: !fir.box>, %mask: !fir.box>>) -> !hlfir.expr { - %dim = arith.constant 2 : i32 - %0 = hlfir.maxloc %input dim %dim mask %mask {fastmath = #arith.fastmath} : (!fir.box>, i32, !fir.box>>) -> !hlfir.expr - return %0 : !hlfir.expr -} -// CHECK-LABEL: func.func @test_partial_var( -// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box>, -// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box>>) -> !hlfir.expr { -// CHECK: %[[VAL_2:.*]] = arith.constant false -// CHECK: %[[VAL_3:.*]] = arith.constant true -// CHECK: %[[VAL_4:.*]] = arith.constant -3.40282347E+38 : f32 -// CHECK: %[[VAL_5:.*]] = arith.constant 0 : i32 -// CHECK: %[[VAL_6:.*]] = arith.constant 2 : index -// CHECK: %[[VAL_7:.*]] = arith.constant 1 : index -// CHECK: %[[VAL_8:.*]] = arith.constant 0 : index -// CHECK: %[[VAL_9:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_8]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_10:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_7]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_11:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_6]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_12:.*]] = fir.shape %[[VAL_9]]#1, %[[VAL_11]]#1 : (index, index) -> !fir.shape<2> -// CHECK: %[[VAL_13:.*]] = fir.is_present %[[VAL_1]] : (!fir.box>>) -> i1 -// CHECK: %[[VAL_14:.*]] = hlfir.elemental %[[VAL_12]] unordered : (!fir.shape<2>) -> !hlfir.expr { -// CHECK: ^bb0(%[[VAL_15:.*]]: index, %[[VAL_16:.*]]: index): -// CHECK: %[[VAL_17:.*]]:3 = fir.do_loop %[[VAL_18:.*]] = %[[VAL_7]] to %[[VAL_10]]#1 step %[[VAL_7]] unordered iter_args(%[[VAL_19:.*]] = %[[VAL_5]], %[[VAL_20:.*]] = %[[VAL_4]], %[[VAL_21:.*]] = %[[VAL_3]]) -> (i32, f32, i1) { -// CHECK: %[[VAL_22:.*]] = fir.if %[[VAL_13]] -> (!fir.logical<4>) { -// CHECK: %[[VAL_23:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_8]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_24:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_7]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_25:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_6]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_26:.*]] = arith.subi %[[VAL_23]]#0, %[[VAL_7]] : index -// CHECK: %[[VAL_27:.*]] = arith.addi %[[VAL_15]], %[[VAL_26]] : index -// CHECK: %[[VAL_28:.*]] = arith.subi %[[VAL_24]]#0, %[[VAL_7]] : index -// CHECK: %[[VAL_29:.*]] = arith.addi %[[VAL_18]], %[[VAL_28]] : index -// CHECK: %[[VAL_30:.*]] = arith.subi %[[VAL_25]]#0, %[[VAL_7]] : index -// CHECK: %[[VAL_31:.*]] = arith.addi %[[VAL_16]], %[[VAL_30]] : index -// CHECK: %[[VAL_32:.*]] = hlfir.designate %[[VAL_1]] (%[[VAL_27]], %[[VAL_29]], %[[VAL_31]]) : (!fir.box>>, index, index, index) -> !fir.ref> -// CHECK: %[[VAL_33:.*]] = fir.load %[[VAL_32]] : !fir.ref> -// CHECK: fir.result %[[VAL_33]] : !fir.logical<4> -// CHECK: } else { -// CHECK: %[[VAL_34:.*]] = fir.convert %[[VAL_3]] : (i1) -> !fir.logical<4> -// CHECK: fir.result %[[VAL_34]] : !fir.logical<4> -// CHECK: } -// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_22]] : (!fir.logical<4>) -> i1 -// CHECK: %[[VAL_36:.*]]:3 = fir.if %[[VAL_35]] -> (i32, f32, i1) { -// CHECK: %[[VAL_37:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_8]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_38:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_7]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_39:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_6]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_40:.*]] = arith.subi %[[VAL_37]]#0, %[[VAL_7]] : index -// CHECK: %[[VAL_41:.*]] = arith.addi %[[VAL_15]], %[[VAL_40]] : index -// CHECK: %[[VAL_42:.*]] = arith.subi %[[VAL_38]]#0, %[[VAL_7]] : index -// CHECK: %[[VAL_43:.*]] = arith.addi %[[VAL_18]], %[[VAL_42]] : index -// CHECK: %[[VAL_44:.*]] = arith.subi %[[VAL_39]]#0, %[[VAL_7]] : index -// CHECK: %[[VAL_45:.*]] = arith.addi %[[VAL_16]], %[[VAL_44]] : index -// CHECK: %[[VAL_46:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_41]], %[[VAL_43]], %[[VAL_45]]) : (!fir.box>, index, index, index) -> !fir.ref -// CHECK: %[[VAL_47:.*]] = fir.load %[[VAL_46]] : !fir.ref -// CHECK: %[[VAL_48:.*]] = arith.cmpf ogt, %[[VAL_47]], %[[VAL_20]] fastmath : f32 -// CHECK: %[[VAL_49:.*]] = arith.cmpf une, %[[VAL_20]], %[[VAL_20]] fastmath : f32 -// CHECK: %[[VAL_50:.*]] = arith.cmpf oeq, %[[VAL_47]], %[[VAL_47]] fastmath : f32 -// CHECK: %[[VAL_51:.*]] = arith.andi %[[VAL_49]], %[[VAL_50]] : i1 -// CHECK: %[[VAL_52:.*]] = arith.ori %[[VAL_48]], %[[VAL_51]] : i1 -// CHECK: %[[VAL_53:.*]] = arith.ori %[[VAL_52]], %[[VAL_21]] : i1 -// CHECK: %[[VAL_54:.*]] = fir.convert %[[VAL_18]] : (index) -> i32 -// CHECK: %[[VAL_55:.*]] = arith.select %[[VAL_53]], %[[VAL_54]], %[[VAL_19]] : i32 -// CHECK: %[[VAL_56:.*]] = arith.select %[[VAL_53]], %[[VAL_47]], %[[VAL_20]] : f32 -// CHECK: fir.result %[[VAL_55]], %[[VAL_56]], %[[VAL_2]] : i32, f32, i1 -// CHECK: } else { -// CHECK: fir.result %[[VAL_19]], %[[VAL_20]], %[[VAL_21]] : i32, f32, i1 -// CHECK: } -// CHECK: fir.result %[[VAL_57:.*]]#0, %[[VAL_57]]#1, %[[VAL_57]]#2 : i32, f32, i1 -// CHECK: } -// CHECK: %[[VAL_58:.*]] = arith.cmpi ne, %[[VAL_59:.*]]#0, %[[VAL_5]] : i32 -// CHECK: %[[VAL_60:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_7]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_61:.*]] = fir.convert %[[VAL_59]]#0 : (i32) -> index -// CHECK: %[[VAL_62:.*]] = arith.addi %[[VAL_61]], %[[VAL_60]]#0 : index -// CHECK: %[[VAL_63:.*]] = arith.subi %[[VAL_62]], %[[VAL_7]] : index -// CHECK: %[[VAL_64:.*]] = arith.select %[[VAL_58]], %[[VAL_63]], %[[VAL_61]] : index -// CHECK: %[[VAL_65:.*]] = fir.convert %[[VAL_64]] : (index) -> i32 -// CHECK: hlfir.yield_element %[[VAL_65]] : i32 -// CHECK: } -// CHECK: return %[[VAL_14]] : !hlfir.expr -// CHECK: } - -// Character comparisons are not supported yet. -func.func @test_character(%input: !fir.box>>) -> !hlfir.expr<1xi32> { - %0 = hlfir.maxloc %input : (!fir.box>>) -> !hlfir.expr<1xi32> - return %0 : !hlfir.expr<1xi32> -} -// CHECK-LABEL: func.func @test_character( -// CHECK: hlfir.maxloc - -// BACK is not supported yet. -func.func @test_back(%input: !hlfir.expr) -> !hlfir.expr<1xi32> { - %back = arith.constant true - %0 = hlfir.maxloc %input back %back : (!hlfir.expr, i1) -> !hlfir.expr<1xi32> - return %0 : !hlfir.expr<1xi32> -} -// CHECK-LABEL: func.func @test_back( -// CHECK: hlfir.maxloc diff --git a/flang/test/HLFIR/simplify-hlfir-intrinsics-maxval.fir b/flang/test/HLFIR/simplify-hlfir-intrinsics-maxval.fir deleted file mode 100644 index 4022b7d3b2b77..0000000000000 --- a/flang/test/HLFIR/simplify-hlfir-intrinsics-maxval.fir +++ /dev/null @@ -1,177 +0,0 @@ -// RUN: fir-opt %s --simplify-hlfir-intrinsics | FileCheck %s - -func.func @test_total_expr(%input: !hlfir.expr, %mask: !hlfir.expr>) -> f32 { - %0 = hlfir.maxval %input mask %mask {fastmath = #arith.fastmath} : (!hlfir.expr, !hlfir.expr>) -> f32 - return %0 : f32 -} -// CHECK-LABEL: func.func @test_total_expr( -// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !hlfir.expr, -// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !hlfir.expr>) -> f32 { -// CHECK: %[[VAL_2:.*]] = arith.constant 1 : index -// CHECK: %[[VAL_3:.*]] = arith.constant -3.40282347E+38 : f32 -// CHECK: %[[VAL_4:.*]] = hlfir.shape_of %[[VAL_0]] : (!hlfir.expr) -> !fir.shape<2> -// CHECK: %[[VAL_5:.*]] = hlfir.get_extent %[[VAL_4]] {dim = 0 : index} : (!fir.shape<2>) -> index -// CHECK: %[[VAL_6:.*]] = hlfir.get_extent %[[VAL_4]] {dim = 1 : index} : (!fir.shape<2>) -> index -// CHECK: %[[VAL_7:.*]] = fir.do_loop %[[VAL_8:.*]] = %[[VAL_2]] to %[[VAL_6]] step %[[VAL_2]] iter_args(%[[VAL_9:.*]] = %[[VAL_3]]) -> (f32) { -// CHECK: %[[VAL_10:.*]] = fir.do_loop %[[VAL_11:.*]] = %[[VAL_2]] to %[[VAL_5]] step %[[VAL_2]] iter_args(%[[VAL_12:.*]] = %[[VAL_9]]) -> (f32) { -// CHECK: %[[VAL_13:.*]] = hlfir.apply %[[VAL_1]], %[[VAL_11]], %[[VAL_8]] : (!hlfir.expr>, index, index) -> !fir.logical<4> -// CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_13]] : (!fir.logical<4>) -> i1 -// CHECK: %[[VAL_15:.*]] = fir.if %[[VAL_14]] -> (f32) { -// CHECK: %[[VAL_16:.*]] = hlfir.apply %[[VAL_0]], %[[VAL_11]], %[[VAL_8]] : (!hlfir.expr, index, index) -> f32 -// CHECK: %[[VAL_17:.*]] = arith.cmpf ogt, %[[VAL_16]], %[[VAL_12]] fastmath : f32 -// CHECK: %[[VAL_18:.*]] = arith.cmpf une, %[[VAL_12]], %[[VAL_12]] fastmath : f32 -// CHECK: %[[VAL_19:.*]] = arith.cmpf oeq, %[[VAL_16]], %[[VAL_16]] fastmath : f32 -// CHECK: %[[VAL_20:.*]] = arith.andi %[[VAL_18]], %[[VAL_19]] : i1 -// CHECK: %[[VAL_21:.*]] = arith.ori %[[VAL_17]], %[[VAL_20]] : i1 -// CHECK: %[[VAL_22:.*]] = arith.select %[[VAL_21]], %[[VAL_16]], %[[VAL_12]] : f32 -// CHECK: fir.result %[[VAL_22]] : f32 -// CHECK: } else { -// CHECK: fir.result %[[VAL_12]] : f32 -// CHECK: } -// CHECK: fir.result %[[VAL_15]] : f32 -// CHECK: } -// CHECK: fir.result %[[VAL_10]] : f32 -// CHECK: } -// CHECK: return %[[VAL_7]] : f32 -// CHECK: } - -func.func @test_partial_expr(%input: !hlfir.expr, %mask: !hlfir.expr>) -> !hlfir.expr { - %dim = arith.constant 1 : i32 - %0 = hlfir.maxval %input dim %dim mask %mask {fastmath = #arith.fastmath} : (!hlfir.expr, i32, !hlfir.expr>) -> !hlfir.expr - return %0 : !hlfir.expr -} -// CHECK-LABEL: func.func @test_partial_expr( -// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !hlfir.expr, -// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !hlfir.expr>) -> !hlfir.expr { -// CHECK: %[[VAL_2:.*]] = arith.constant 1 : index -// CHECK: %[[VAL_3:.*]] = arith.constant -1.7976931348623157E+308 : f64 -// CHECK: %[[VAL_4:.*]] = hlfir.shape_of %[[VAL_0]] : (!hlfir.expr) -> !fir.shape<2> -// CHECK: %[[VAL_5:.*]] = hlfir.get_extent %[[VAL_4]] {dim = 0 : index} : (!fir.shape<2>) -> index -// CHECK: %[[VAL_6:.*]] = hlfir.get_extent %[[VAL_4]] {dim = 1 : index} : (!fir.shape<2>) -> index -// CHECK: %[[VAL_7:.*]] = fir.shape %[[VAL_6]] : (index) -> !fir.shape<1> -// CHECK: %[[VAL_8:.*]] = hlfir.elemental %[[VAL_7]] unordered : (!fir.shape<1>) -> !hlfir.expr { -// CHECK: ^bb0(%[[VAL_9:.*]]: index): -// CHECK: %[[VAL_10:.*]] = fir.do_loop %[[VAL_11:.*]] = %[[VAL_2]] to %[[VAL_5]] step %[[VAL_2]] unordered iter_args(%[[VAL_12:.*]] = %[[VAL_3]]) -> (f64) { -// CHECK: %[[VAL_13:.*]] = hlfir.apply %[[VAL_1]], %[[VAL_11]], %[[VAL_9]] : (!hlfir.expr>, index, index) -> !fir.logical<4> -// CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_13]] : (!fir.logical<4>) -> i1 -// CHECK: %[[VAL_15:.*]] = fir.if %[[VAL_14]] -> (f64) { -// CHECK: %[[VAL_16:.*]] = hlfir.apply %[[VAL_0]], %[[VAL_11]], %[[VAL_9]] : (!hlfir.expr, index, index) -> f64 -// CHECK: %[[VAL_17:.*]] = arith.cmpf ogt, %[[VAL_16]], %[[VAL_12]] fastmath : f64 -// CHECK: %[[VAL_18:.*]] = arith.cmpf une, %[[VAL_12]], %[[VAL_12]] fastmath : f64 -// CHECK: %[[VAL_19:.*]] = arith.cmpf oeq, %[[VAL_16]], %[[VAL_16]] fastmath : f64 -// CHECK: %[[VAL_20:.*]] = arith.andi %[[VAL_18]], %[[VAL_19]] : i1 -// CHECK: %[[VAL_21:.*]] = arith.ori %[[VAL_17]], %[[VAL_20]] : i1 -// CHECK: %[[VAL_22:.*]] = arith.select %[[VAL_21]], %[[VAL_16]], %[[VAL_12]] : f64 -// CHECK: fir.result %[[VAL_22]] : f64 -// CHECK: } else { -// CHECK: fir.result %[[VAL_12]] : f64 -// CHECK: } -// CHECK: fir.result %[[VAL_15]] : f64 -// CHECK: } -// CHECK: hlfir.yield_element %[[VAL_10]] : f64 -// CHECK: } -// CHECK: return %[[VAL_8]] : !hlfir.expr -// CHECK: } - -func.func @test_total_var(%input: !fir.box>, %mask: !fir.ref>>) -> f16 { - %0 = hlfir.maxval %input mask %mask {fastmath = #arith.fastmath} : (!fir.box>, !fir.ref>>) -> f16 - return %0 : f16 -} -// CHECK-LABEL: func.func @test_total_var( -// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box>, -// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref>>) -> f16 { -// CHECK: %[[VAL_2:.*]] = arith.constant -6.550400e+04 : f16 -// CHECK: %[[VAL_3:.*]] = arith.constant 1 : index -// CHECK: %[[VAL_4:.*]] = arith.constant 0 : index -// CHECK: %[[VAL_5:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_6:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_7:.*]] = fir.do_loop %[[VAL_8:.*]] = %[[VAL_3]] to %[[VAL_6]]#1 step %[[VAL_3]] unordered iter_args(%[[VAL_9:.*]] = %[[VAL_2]]) -> (f16) { -// CHECK: %[[VAL_10:.*]] = fir.do_loop %[[VAL_11:.*]] = %[[VAL_3]] to %[[VAL_5]]#1 step %[[VAL_3]] unordered iter_args(%[[VAL_12:.*]] = %[[VAL_9]]) -> (f16) { -// CHECK: %[[VAL_13:.*]] = hlfir.designate %[[VAL_1]] (%[[VAL_11]], %[[VAL_8]]) : (!fir.ref>>, index, index) -> !fir.ref> -// CHECK: %[[VAL_14:.*]] = fir.load %[[VAL_13]] : !fir.ref> -// CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_14]] : (!fir.logical<1>) -> i1 -// CHECK: %[[VAL_16:.*]] = fir.if %[[VAL_15]] -> (f16) { -// CHECK: %[[VAL_17:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_18:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_19:.*]] = arith.subi %[[VAL_17]]#0, %[[VAL_3]] : index -// CHECK: %[[VAL_20:.*]] = arith.addi %[[VAL_11]], %[[VAL_19]] : index -// CHECK: %[[VAL_21:.*]] = arith.subi %[[VAL_18]]#0, %[[VAL_3]] : index -// CHECK: %[[VAL_22:.*]] = arith.addi %[[VAL_8]], %[[VAL_21]] : index -// CHECK: %[[VAL_23:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_20]], %[[VAL_22]]) : (!fir.box>, index, index) -> !fir.ref -// CHECK: %[[VAL_24:.*]] = fir.load %[[VAL_23]] : !fir.ref -// CHECK: %[[VAL_25:.*]] = arith.cmpf ogt, %[[VAL_24]], %[[VAL_12]] fastmath : f16 -// CHECK: %[[VAL_26:.*]] = arith.cmpf une, %[[VAL_12]], %[[VAL_12]] fastmath : f16 -// CHECK: %[[VAL_27:.*]] = arith.cmpf oeq, %[[VAL_24]], %[[VAL_24]] fastmath : f16 -// CHECK: %[[VAL_28:.*]] = arith.andi %[[VAL_26]], %[[VAL_27]] : i1 -// CHECK: %[[VAL_29:.*]] = arith.ori %[[VAL_25]], %[[VAL_28]] : i1 -// CHECK: %[[VAL_30:.*]] = arith.select %[[VAL_29]], %[[VAL_24]], %[[VAL_12]] : f16 -// CHECK: fir.result %[[VAL_30]] : f16 -// CHECK: } else { -// CHECK: fir.result %[[VAL_12]] : f16 -// CHECK: } -// CHECK: fir.result %[[VAL_16]] : f16 -// CHECK: } -// CHECK: fir.result %[[VAL_10]] : f16 -// CHECK: } -// CHECK: return %[[VAL_7]] : f16 -// CHECK: } - -func.func @test_partial_var(%input: !fir.box>, %mask: !fir.box>>) -> !hlfir.expr { - %dim = arith.constant 2 : i32 - %0 = hlfir.maxval %input dim %dim mask %mask {fastmath = #arith.fastmath} : (!fir.box>, i32, !fir.box>>) -> !hlfir.expr - return %0 : !hlfir.expr -} -// CHECK-LABEL: func.func @test_partial_var( -// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box>, -// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box>>) -> !hlfir.expr { -// CHECK: %[[VAL_2:.*]] = arith.constant true -// CHECK: %[[VAL_3:.*]] = arith.constant -6.550400e+04 : f16 -// CHECK: %[[VAL_4:.*]] = arith.constant 1 : index -// CHECK: %[[VAL_5:.*]] = arith.constant 0 : index -// CHECK: %[[VAL_6:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_7:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_8:.*]] = fir.shape %[[VAL_6]]#1 : (index) -> !fir.shape<1> -// CHECK: %[[VAL_9:.*]] = fir.is_present %[[VAL_1]] : (!fir.box>>) -> i1 -// CHECK: %[[VAL_10:.*]] = hlfir.elemental %[[VAL_8]] unordered : (!fir.shape<1>) -> !hlfir.expr { -// CHECK: ^bb0(%[[VAL_11:.*]]: index): -// CHECK: %[[VAL_12:.*]] = fir.do_loop %[[VAL_13:.*]] = %[[VAL_4]] to %[[VAL_7]]#1 step %[[VAL_4]] unordered iter_args(%[[VAL_14:.*]] = %[[VAL_3]]) -> (f16) { -// CHECK: %[[VAL_15:.*]] = fir.if %[[VAL_9]] -> (!fir.logical<1>) { -// CHECK: %[[VAL_16:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_5]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_17:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_4]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_18:.*]] = arith.subi %[[VAL_16]]#0, %[[VAL_4]] : index -// CHECK: %[[VAL_19:.*]] = arith.addi %[[VAL_11]], %[[VAL_18]] : index -// CHECK: %[[VAL_20:.*]] = arith.subi %[[VAL_17]]#0, %[[VAL_4]] : index -// CHECK: %[[VAL_21:.*]] = arith.addi %[[VAL_13]], %[[VAL_20]] : index -// CHECK: %[[VAL_22:.*]] = hlfir.designate %[[VAL_1]] (%[[VAL_19]], %[[VAL_21]]) : (!fir.box>>, index, index) -> !fir.ref> -// CHECK: %[[VAL_23:.*]] = fir.load %[[VAL_22]] : !fir.ref> -// CHECK: fir.result %[[VAL_23]] : !fir.logical<1> -// CHECK: } else { -// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_2]] : (i1) -> !fir.logical<1> -// CHECK: fir.result %[[VAL_24]] : !fir.logical<1> -// CHECK: } -// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_15]] : (!fir.logical<1>) -> i1 -// CHECK: %[[VAL_26:.*]] = fir.if %[[VAL_25]] -> (f16) { -// CHECK: %[[VAL_27:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_28:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_29:.*]] = arith.subi %[[VAL_27]]#0, %[[VAL_4]] : index -// CHECK: %[[VAL_30:.*]] = arith.addi %[[VAL_11]], %[[VAL_29]] : index -// CHECK: %[[VAL_31:.*]] = arith.subi %[[VAL_28]]#0, %[[VAL_4]] : index -// CHECK: %[[VAL_32:.*]] = arith.addi %[[VAL_13]], %[[VAL_31]] : index -// CHECK: %[[VAL_33:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_30]], %[[VAL_32]]) : (!fir.box>, index, index) -> !fir.ref -// CHECK: %[[VAL_34:.*]] = fir.load %[[VAL_33]] : !fir.ref -// CHECK: %[[VAL_35:.*]] = arith.cmpf ogt, %[[VAL_34]], %[[VAL_14]] fastmath : f16 -// CHECK: %[[VAL_36:.*]] = arith.cmpf une, %[[VAL_14]], %[[VAL_14]] fastmath : f16 -// CHECK: %[[VAL_37:.*]] = arith.cmpf oeq, %[[VAL_34]], %[[VAL_34]] fastmath : f16 -// CHECK: %[[VAL_38:.*]] = arith.andi %[[VAL_36]], %[[VAL_37]] : i1 -// CHECK: %[[VAL_39:.*]] = arith.ori %[[VAL_35]], %[[VAL_38]] : i1 -// CHECK: %[[VAL_40:.*]] = arith.select %[[VAL_39]], %[[VAL_34]], %[[VAL_14]] : f16 -// CHECK: fir.result %[[VAL_40]] : f16 -// CHECK: } else { -// CHECK: fir.result %[[VAL_14]] : f16 -// CHECK: } -// CHECK: fir.result %[[VAL_26]] : f16 -// CHECK: } -// CHECK: hlfir.yield_element %[[VAL_12]] : f16 -// CHECK: } -// CHECK: return %[[VAL_10]] : !hlfir.expr -// CHECK: } diff --git a/flang/test/HLFIR/simplify-hlfir-intrinsics-minloc.fir b/flang/test/HLFIR/simplify-hlfir-intrinsics-minloc.fir deleted file mode 100644 index 96dcebaf9a2cd..0000000000000 --- a/flang/test/HLFIR/simplify-hlfir-intrinsics-minloc.fir +++ /dev/null @@ -1,343 +0,0 @@ -// RUN: fir-opt %s --simplify-hlfir-intrinsics | FileCheck %s - -func.func @test_1d_total_expr(%input: !hlfir.expr, %mask: !hlfir.expr>) -> !hlfir.expr<1xi32> { - %0 = hlfir.minloc %input mask %mask {fastmath = #arith.fastmath} : (!hlfir.expr, !hlfir.expr>) -> !hlfir.expr<1xi32> - return %0 : !hlfir.expr<1xi32> -} -// CHECK-LABEL: func.func @test_1d_total_expr( -// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !hlfir.expr, -// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !hlfir.expr>) -> !hlfir.expr<1xi32> { -// CHECK: %[[VAL_2:.*]] = arith.constant false -// CHECK: %[[VAL_3:.*]] = arith.constant 1 : index -// CHECK: %[[VAL_4:.*]] = arith.constant true -// CHECK: %[[VAL_5:.*]] = arith.constant 2147483647 : i32 -// CHECK: %[[VAL_6:.*]] = arith.constant 0 : i32 -// CHECK: %[[VAL_7:.*]] = fir.alloca !fir.array<1xi32> -// CHECK: %[[VAL_8:.*]] = hlfir.shape_of %[[VAL_0]] : (!hlfir.expr) -> !fir.shape<1> -// CHECK: %[[VAL_9:.*]] = hlfir.get_extent %[[VAL_8]] {dim = 0 : index} : (!fir.shape<1>) -> index -// CHECK: %[[VAL_10:.*]]:3 = fir.do_loop %[[VAL_11:.*]] = %[[VAL_3]] to %[[VAL_9]] step %[[VAL_3]] unordered iter_args(%[[VAL_12:.*]] = %[[VAL_6]], %[[VAL_13:.*]] = %[[VAL_5]], %[[VAL_14:.*]] = %[[VAL_4]]) -> (i32, i32, i1) { -// CHECK: %[[VAL_15:.*]] = hlfir.apply %[[VAL_1]], %[[VAL_11]] : (!hlfir.expr>, index) -> !fir.logical<4> -// CHECK: %[[VAL_16:.*]] = fir.convert %[[VAL_15]] : (!fir.logical<4>) -> i1 -// CHECK: %[[VAL_17:.*]]:3 = fir.if %[[VAL_16]] -> (i32, i32, i1) { -// CHECK: %[[VAL_18:.*]] = hlfir.apply %[[VAL_0]], %[[VAL_11]] : (!hlfir.expr, index) -> i32 -// CHECK: %[[VAL_19:.*]] = arith.cmpi slt, %[[VAL_18]], %[[VAL_13]] : i32 -// CHECK: %[[VAL_20:.*]] = arith.ori %[[VAL_19]], %[[VAL_14]] : i1 -// CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_11]] : (index) -> i32 -// CHECK: %[[VAL_22:.*]] = arith.select %[[VAL_20]], %[[VAL_21]], %[[VAL_12]] : i32 -// CHECK: %[[VAL_23:.*]] = arith.select %[[VAL_20]], %[[VAL_18]], %[[VAL_13]] : i32 -// CHECK: fir.result %[[VAL_22]], %[[VAL_23]], %[[VAL_2]] : i32, i32, i1 -// CHECK: } else { -// CHECK: fir.result %[[VAL_12]], %[[VAL_13]], %[[VAL_14]] : i32, i32, i1 -// CHECK: } -// CHECK: fir.result %[[VAL_24:.*]]#0, %[[VAL_24]]#1, %[[VAL_24]]#2 : i32, i32, i1 -// CHECK: } -// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_26:.*]]#0 : (i32) -> index -// CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_25]] : (index) -> i32 -// CHECK: %[[VAL_28:.*]] = hlfir.designate %[[VAL_7]] (%[[VAL_3]]) : (!fir.ref>, index) -> !fir.ref -// CHECK: hlfir.assign %[[VAL_27]] to %[[VAL_28]] : i32, !fir.ref -// CHECK: %[[VAL_29:.*]] = hlfir.as_expr %[[VAL_7]] move %[[VAL_2]] : (!fir.ref>, i1) -> !hlfir.expr<1xi32> -// CHECK: return %[[VAL_29]] : !hlfir.expr<1xi32> -// CHECK: } - -func.func @test_1d_dim_expr(%input: !hlfir.expr, %mask: !hlfir.expr>) -> i32 { - %dim = arith.constant 1 : i16 - %0 = hlfir.minloc %input dim %dim mask %mask {fastmath = #arith.fastmath} : (!hlfir.expr, i16, !hlfir.expr>) -> i32 - return %0 : i32 -} -// CHECK-LABEL: func.func @test_1d_dim_expr( -// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !hlfir.expr, -// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !hlfir.expr>) -> i32 { -// CHECK: %[[VAL_2:.*]] = arith.constant false -// CHECK: %[[VAL_3:.*]] = arith.constant 1 : index -// CHECK: %[[VAL_4:.*]] = arith.constant true -// CHECK: %[[VAL_5:.*]] = arith.constant 3.40282347E+38 : f32 -// CHECK: %[[VAL_6:.*]] = arith.constant 0 : i32 -// CHECK: %[[VAL_7:.*]] = hlfir.shape_of %[[VAL_0]] : (!hlfir.expr) -> !fir.shape<1> -// CHECK: %[[VAL_8:.*]] = hlfir.get_extent %[[VAL_7]] {dim = 0 : index} : (!fir.shape<1>) -> index -// CHECK: %[[VAL_9:.*]]:3 = fir.do_loop %[[VAL_10:.*]] = %[[VAL_3]] to %[[VAL_8]] step %[[VAL_3]] iter_args(%[[VAL_11:.*]] = %[[VAL_6]], %[[VAL_12:.*]] = %[[VAL_5]], %[[VAL_13:.*]] = %[[VAL_4]]) -> (i32, f32, i1) { -// CHECK: %[[VAL_14:.*]] = hlfir.apply %[[VAL_1]], %[[VAL_10]] : (!hlfir.expr>, index) -> !fir.logical<4> -// CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_14]] : (!fir.logical<4>) -> i1 -// CHECK: %[[VAL_16:.*]]:3 = fir.if %[[VAL_15]] -> (i32, f32, i1) { -// CHECK: %[[VAL_17:.*]] = hlfir.apply %[[VAL_0]], %[[VAL_10]] : (!hlfir.expr, index) -> f32 -// CHECK: %[[VAL_18:.*]] = arith.cmpf olt, %[[VAL_17]], %[[VAL_12]] fastmath : f32 -// CHECK: %[[VAL_19:.*]] = arith.cmpf une, %[[VAL_12]], %[[VAL_12]] fastmath : f32 -// CHECK: %[[VAL_20:.*]] = arith.cmpf oeq, %[[VAL_17]], %[[VAL_17]] fastmath : f32 -// CHECK: %[[VAL_21:.*]] = arith.andi %[[VAL_19]], %[[VAL_20]] : i1 -// CHECK: %[[VAL_22:.*]] = arith.ori %[[VAL_18]], %[[VAL_21]] : i1 -// CHECK: %[[VAL_23:.*]] = arith.ori %[[VAL_22]], %[[VAL_13]] : i1 -// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_10]] : (index) -> i32 -// CHECK: %[[VAL_25:.*]] = arith.select %[[VAL_23]], %[[VAL_24]], %[[VAL_11]] : i32 -// CHECK: %[[VAL_26:.*]] = arith.select %[[VAL_23]], %[[VAL_17]], %[[VAL_12]] : f32 -// CHECK: fir.result %[[VAL_25]], %[[VAL_26]], %[[VAL_2]] : i32, f32, i1 -// CHECK: } else { -// CHECK: fir.result %[[VAL_11]], %[[VAL_12]], %[[VAL_13]] : i32, f32, i1 -// CHECK: } -// CHECK: fir.result %[[VAL_27:.*]]#0, %[[VAL_27]]#1, %[[VAL_27]]#2 : i32, f32, i1 -// CHECK: } -// CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_29:.*]]#0 : (i32) -> index -// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_28]] : (index) -> i32 -// CHECK: return %[[VAL_30]] : i32 -// CHECK: } - -func.func @test_1d_total_var(%input: !fir.box>, %mask: !hlfir.expr>) -> !hlfir.expr<1xi16> { - %0 = hlfir.minloc %input mask %mask {fastmath = #arith.fastmath} : (!fir.box>, !hlfir.expr>) -> !hlfir.expr<1xi16> - return %0 : !hlfir.expr<1xi16> -} -// CHECK-LABEL: func.func @test_1d_total_var( -// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box>, -// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !hlfir.expr>) -> !hlfir.expr<1xi16> { -// CHECK: %[[VAL_2:.*]] = arith.constant false -// CHECK: %[[VAL_3:.*]] = arith.constant 1 : index -// CHECK: %[[VAL_4:.*]] = arith.constant true -// CHECK: %[[VAL_5:.*]] = arith.constant 3.40282347E+38 : f32 -// CHECK: %[[VAL_6:.*]] = arith.constant 0 : i16 -// CHECK: %[[VAL_7:.*]] = arith.constant 0 : index -// CHECK: %[[VAL_8:.*]] = fir.alloca !fir.array<1xi16> -// CHECK: %[[VAL_9:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_7]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_10:.*]]:3 = fir.do_loop %[[VAL_11:.*]] = %[[VAL_3]] to %[[VAL_9]]#1 step %[[VAL_3]] iter_args(%[[VAL_12:.*]] = %[[VAL_6]], %[[VAL_13:.*]] = %[[VAL_5]], %[[VAL_14:.*]] = %[[VAL_4]]) -> (i16, f32, i1) { -// CHECK: %[[VAL_15:.*]] = hlfir.apply %[[VAL_1]], %[[VAL_11]] : (!hlfir.expr>, index) -> !fir.logical<4> -// CHECK: %[[VAL_16:.*]] = fir.convert %[[VAL_15]] : (!fir.logical<4>) -> i1 -// CHECK: %[[VAL_17:.*]]:3 = fir.if %[[VAL_16]] -> (i16, f32, i1) { -// CHECK: %[[VAL_18:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_7]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_19:.*]] = arith.subi %[[VAL_18]]#0, %[[VAL_3]] : index -// CHECK: %[[VAL_20:.*]] = arith.addi %[[VAL_11]], %[[VAL_19]] : index -// CHECK: %[[VAL_21:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_20]]) : (!fir.box>, index) -> !fir.ref -// CHECK: %[[VAL_22:.*]] = fir.load %[[VAL_21]] : !fir.ref -// CHECK: %[[VAL_23:.*]] = arith.cmpf olt, %[[VAL_22]], %[[VAL_13]] fastmath : f32 -// CHECK: %[[VAL_24:.*]] = arith.cmpf une, %[[VAL_13]], %[[VAL_13]] fastmath : f32 -// CHECK: %[[VAL_25:.*]] = arith.cmpf oeq, %[[VAL_22]], %[[VAL_22]] fastmath : f32 -// CHECK: %[[VAL_26:.*]] = arith.andi %[[VAL_24]], %[[VAL_25]] : i1 -// CHECK: %[[VAL_27:.*]] = arith.ori %[[VAL_23]], %[[VAL_26]] : i1 -// CHECK: %[[VAL_28:.*]] = arith.ori %[[VAL_27]], %[[VAL_14]] : i1 -// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_11]] : (index) -> i16 -// CHECK: %[[VAL_30:.*]] = arith.select %[[VAL_28]], %[[VAL_29]], %[[VAL_12]] : i16 -// CHECK: %[[VAL_31:.*]] = arith.select %[[VAL_28]], %[[VAL_22]], %[[VAL_13]] : f32 -// CHECK: fir.result %[[VAL_30]], %[[VAL_31]], %[[VAL_2]] : i16, f32, i1 -// CHECK: } else { -// CHECK: fir.result %[[VAL_12]], %[[VAL_13]], %[[VAL_14]] : i16, f32, i1 -// CHECK: } -// CHECK: fir.result %[[VAL_32:.*]]#0, %[[VAL_32]]#1, %[[VAL_32]]#2 : i16, f32, i1 -// CHECK: } -// CHECK: %[[VAL_33:.*]] = arith.cmpi ne, %[[VAL_34:.*]]#0, %[[VAL_6]] : i16 -// CHECK: %[[VAL_35:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_7]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_34]]#0 : (i16) -> index -// CHECK: %[[VAL_37:.*]] = arith.addi %[[VAL_36]], %[[VAL_35]]#0 : index -// CHECK: %[[VAL_38:.*]] = arith.subi %[[VAL_37]], %[[VAL_3]] : index -// CHECK: %[[VAL_39:.*]] = arith.select %[[VAL_33]], %[[VAL_38]], %[[VAL_36]] : index -// CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_39]] : (index) -> i16 -// CHECK: %[[VAL_41:.*]] = hlfir.designate %[[VAL_8]] (%[[VAL_3]]) : (!fir.ref>, index) -> !fir.ref -// CHECK: hlfir.assign %[[VAL_40]] to %[[VAL_41]] : i16, !fir.ref -// CHECK: %[[VAL_42:.*]] = hlfir.as_expr %[[VAL_8]] move %[[VAL_2]] : (!fir.ref>, i1) -> !hlfir.expr<1xi16> -// CHECK: return %[[VAL_42]] : !hlfir.expr<1xi16> -// CHECK: } - -func.func @test_1d_dim_var(%input: !fir.box>, %mask: !hlfir.expr>) -> i64 { - %dim = arith.constant 1 : i32 - %0 = hlfir.minloc %input dim %dim mask %mask {fastmath = #arith.fastmath} : (!fir.box>, i32, !hlfir.expr>) -> i64 - return %0 : i64 -} -// CHECK-LABEL: func.func @test_1d_dim_var( -// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box>, -// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !hlfir.expr>) -> i64 { -// CHECK: %[[VAL_2:.*]] = arith.constant false -// CHECK: %[[VAL_3:.*]] = arith.constant 1 : index -// CHECK: %[[VAL_4:.*]] = arith.constant true -// CHECK: %[[VAL_5:.*]] = arith.constant 1.7976931348623157E+308 : f64 -// CHECK: %[[VAL_6:.*]] = arith.constant 0 : i64 -// CHECK: %[[VAL_7:.*]] = arith.constant 0 : index -// CHECK: %[[VAL_8:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_7]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_9:.*]]:3 = fir.do_loop %[[VAL_10:.*]] = %[[VAL_3]] to %[[VAL_8]]#1 step %[[VAL_3]] iter_args(%[[VAL_11:.*]] = %[[VAL_6]], %[[VAL_12:.*]] = %[[VAL_5]], %[[VAL_13:.*]] = %[[VAL_4]]) -> (i64, f64, i1) { -// CHECK: %[[VAL_14:.*]] = hlfir.apply %[[VAL_1]], %[[VAL_10]] : (!hlfir.expr>, index) -> !fir.logical<4> -// CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_14]] : (!fir.logical<4>) -> i1 -// CHECK: %[[VAL_16:.*]]:3 = fir.if %[[VAL_15]] -> (i64, f64, i1) { -// CHECK: %[[VAL_17:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_7]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_18:.*]] = arith.subi %[[VAL_17]]#0, %[[VAL_3]] : index -// CHECK: %[[VAL_19:.*]] = arith.addi %[[VAL_10]], %[[VAL_18]] : index -// CHECK: %[[VAL_20:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_19]]) : (!fir.box>, index) -> !fir.ref -// CHECK: %[[VAL_21:.*]] = fir.load %[[VAL_20]] : !fir.ref -// CHECK: %[[VAL_22:.*]] = arith.cmpf olt, %[[VAL_21]], %[[VAL_12]] fastmath : f64 -// CHECK: %[[VAL_23:.*]] = arith.cmpf une, %[[VAL_12]], %[[VAL_12]] fastmath : f64 -// CHECK: %[[VAL_24:.*]] = arith.cmpf oeq, %[[VAL_21]], %[[VAL_21]] fastmath : f64 -// CHECK: %[[VAL_25:.*]] = arith.andi %[[VAL_23]], %[[VAL_24]] : i1 -// CHECK: %[[VAL_26:.*]] = arith.ori %[[VAL_22]], %[[VAL_25]] : i1 -// CHECK: %[[VAL_27:.*]] = arith.ori %[[VAL_26]], %[[VAL_13]] : i1 -// CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_10]] : (index) -> i64 -// CHECK: %[[VAL_29:.*]] = arith.select %[[VAL_27]], %[[VAL_28]], %[[VAL_11]] : i64 -// CHECK: %[[VAL_30:.*]] = arith.select %[[VAL_27]], %[[VAL_21]], %[[VAL_12]] : f64 -// CHECK: fir.result %[[VAL_29]], %[[VAL_30]], %[[VAL_2]] : i64, f64, i1 -// CHECK: } else { -// CHECK: fir.result %[[VAL_11]], %[[VAL_12]], %[[VAL_13]] : i64, f64, i1 -// CHECK: } -// CHECK: fir.result %[[VAL_31:.*]]#0, %[[VAL_31]]#1, %[[VAL_31]]#2 : i64, f64, i1 -// CHECK: } -// CHECK: %[[VAL_32:.*]] = arith.cmpi ne, %[[VAL_33:.*]]#0, %[[VAL_6]] : i64 -// CHECK: %[[VAL_34:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_7]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_33]]#0 : (i64) -> index -// CHECK: %[[VAL_36:.*]] = arith.addi %[[VAL_35]], %[[VAL_34]]#0 : index -// CHECK: %[[VAL_37:.*]] = arith.subi %[[VAL_36]], %[[VAL_3]] : index -// CHECK: %[[VAL_38:.*]] = arith.select %[[VAL_32]], %[[VAL_37]], %[[VAL_35]] : index -// CHECK: %[[VAL_39:.*]] = fir.convert %[[VAL_38]] : (index) -> i64 -// CHECK: return %[[VAL_39]] : i64 -// CHECK: } - -func.func @test_total_expr(%input: !hlfir.expr, %mask: !hlfir.expr>) -> !hlfir.expr<3xi32> { - %0 = hlfir.minloc %input mask %mask {fastmath = #arith.fastmath} : (!hlfir.expr, !hlfir.expr>) -> !hlfir.expr<3xi32> - return %0 : !hlfir.expr<3xi32> -} -// CHECK-LABEL: func.func @test_total_expr( -// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !hlfir.expr, -// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !hlfir.expr>) -> !hlfir.expr<3xi32> { -// CHECK: %[[VAL_2:.*]] = arith.constant 3 : index -// CHECK: %[[VAL_3:.*]] = arith.constant 2 : index -// CHECK: %[[VAL_4:.*]] = arith.constant false -// CHECK: %[[VAL_5:.*]] = arith.constant 1 : index -// CHECK: %[[VAL_6:.*]] = arith.constant true -// CHECK: %[[VAL_7:.*]] = arith.constant 3.40282347E+38 : f32 -// CHECK: %[[VAL_8:.*]] = arith.constant 0 : i32 -// CHECK: %[[VAL_9:.*]] = fir.alloca !fir.array<3xi32> -// CHECK: %[[VAL_10:.*]] = hlfir.shape_of %[[VAL_0]] : (!hlfir.expr) -> !fir.shape<3> -// CHECK: %[[VAL_11:.*]] = hlfir.get_extent %[[VAL_10]] {dim = 0 : index} : (!fir.shape<3>) -> index -// CHECK: %[[VAL_12:.*]] = hlfir.get_extent %[[VAL_10]] {dim = 1 : index} : (!fir.shape<3>) -> index -// CHECK: %[[VAL_13:.*]] = hlfir.get_extent %[[VAL_10]] {dim = 2 : index} : (!fir.shape<3>) -> index -// CHECK: %[[VAL_14:.*]]:5 = fir.do_loop %[[VAL_15:.*]] = %[[VAL_5]] to %[[VAL_13]] step %[[VAL_5]] unordered iter_args(%[[VAL_16:.*]] = %[[VAL_8]], %[[VAL_17:.*]] = %[[VAL_8]], %[[VAL_18:.*]] = %[[VAL_8]], %[[VAL_19:.*]] = %[[VAL_7]], %[[VAL_20:.*]] = %[[VAL_6]]) -> (i32, i32, i32, f32, i1) { -// CHECK: %[[VAL_21:.*]]:5 = fir.do_loop %[[VAL_22:.*]] = %[[VAL_5]] to %[[VAL_12]] step %[[VAL_5]] unordered iter_args(%[[VAL_23:.*]] = %[[VAL_16]], %[[VAL_24:.*]] = %[[VAL_17]], %[[VAL_25:.*]] = %[[VAL_18]], %[[VAL_26:.*]] = %[[VAL_19]], %[[VAL_27:.*]] = %[[VAL_20]]) -> (i32, i32, i32, f32, i1) { -// CHECK: %[[VAL_28:.*]]:5 = fir.do_loop %[[VAL_29:.*]] = %[[VAL_5]] to %[[VAL_11]] step %[[VAL_5]] unordered iter_args(%[[VAL_30:.*]] = %[[VAL_23]], %[[VAL_31:.*]] = %[[VAL_24]], %[[VAL_32:.*]] = %[[VAL_25]], %[[VAL_33:.*]] = %[[VAL_26]], %[[VAL_34:.*]] = %[[VAL_27]]) -> (i32, i32, i32, f32, i1) { -// CHECK: %[[VAL_35:.*]] = hlfir.apply %[[VAL_1]], %[[VAL_29]], %[[VAL_22]], %[[VAL_15]] : (!hlfir.expr>, index, index, index) -> !fir.logical<4> -// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_35]] : (!fir.logical<4>) -> i1 -// CHECK: %[[VAL_37:.*]]:5 = fir.if %[[VAL_36]] -> (i32, i32, i32, f32, i1) { -// CHECK: %[[VAL_38:.*]] = hlfir.apply %[[VAL_0]], %[[VAL_29]], %[[VAL_22]], %[[VAL_15]] : (!hlfir.expr, index, index, index) -> f32 -// CHECK: %[[VAL_39:.*]] = arith.cmpf olt, %[[VAL_38]], %[[VAL_33]] fastmath : f32 -// CHECK: %[[VAL_40:.*]] = arith.cmpf une, %[[VAL_33]], %[[VAL_33]] fastmath : f32 -// CHECK: %[[VAL_41:.*]] = arith.cmpf oeq, %[[VAL_38]], %[[VAL_38]] fastmath : f32 -// CHECK: %[[VAL_42:.*]] = arith.andi %[[VAL_40]], %[[VAL_41]] : i1 -// CHECK: %[[VAL_43:.*]] = arith.ori %[[VAL_39]], %[[VAL_42]] : i1 -// CHECK: %[[VAL_44:.*]] = arith.ori %[[VAL_43]], %[[VAL_34]] : i1 -// CHECK: %[[VAL_45:.*]] = fir.convert %[[VAL_29]] : (index) -> i32 -// CHECK: %[[VAL_46:.*]] = arith.select %[[VAL_44]], %[[VAL_45]], %[[VAL_30]] : i32 -// CHECK: %[[VAL_47:.*]] = fir.convert %[[VAL_22]] : (index) -> i32 -// CHECK: %[[VAL_48:.*]] = arith.select %[[VAL_44]], %[[VAL_47]], %[[VAL_31]] : i32 -// CHECK: %[[VAL_49:.*]] = fir.convert %[[VAL_15]] : (index) -> i32 -// CHECK: %[[VAL_50:.*]] = arith.select %[[VAL_44]], %[[VAL_49]], %[[VAL_32]] : i32 -// CHECK: %[[VAL_51:.*]] = arith.select %[[VAL_44]], %[[VAL_38]], %[[VAL_33]] : f32 -// CHECK: fir.result %[[VAL_46]], %[[VAL_48]], %[[VAL_50]], %[[VAL_51]], %[[VAL_4]] : i32, i32, i32, f32, i1 -// CHECK: } else { -// CHECK: fir.result %[[VAL_30]], %[[VAL_31]], %[[VAL_32]], %[[VAL_33]], %[[VAL_34]] : i32, i32, i32, f32, i1 -// CHECK: } -// CHECK: fir.result %[[VAL_52:.*]]#0, %[[VAL_52]]#1, %[[VAL_52]]#2, %[[VAL_52]]#3, %[[VAL_52]]#4 : i32, i32, i32, f32, i1 -// CHECK: } -// CHECK: fir.result %[[VAL_53:.*]]#0, %[[VAL_53]]#1, %[[VAL_53]]#2, %[[VAL_53]]#3, %[[VAL_53]]#4 : i32, i32, i32, f32, i1 -// CHECK: } -// CHECK: fir.result %[[VAL_54:.*]]#0, %[[VAL_54]]#1, %[[VAL_54]]#2, %[[VAL_54]]#3, %[[VAL_54]]#4 : i32, i32, i32, f32, i1 -// CHECK: } -// CHECK: %[[VAL_55:.*]] = fir.convert %[[VAL_56:.*]]#0 : (i32) -> index -// CHECK: %[[VAL_57:.*]] = fir.convert %[[VAL_55]] : (index) -> i32 -// CHECK: %[[VAL_58:.*]] = hlfir.designate %[[VAL_9]] (%[[VAL_5]]) : (!fir.ref>, index) -> !fir.ref -// CHECK: hlfir.assign %[[VAL_57]] to %[[VAL_58]] : i32, !fir.ref -// CHECK: %[[VAL_59:.*]] = fir.convert %[[VAL_56]]#1 : (i32) -> index -// CHECK: %[[VAL_60:.*]] = fir.convert %[[VAL_59]] : (index) -> i32 -// CHECK: %[[VAL_61:.*]] = hlfir.designate %[[VAL_9]] (%[[VAL_3]]) : (!fir.ref>, index) -> !fir.ref -// CHECK: hlfir.assign %[[VAL_60]] to %[[VAL_61]] : i32, !fir.ref -// CHECK: %[[VAL_62:.*]] = fir.convert %[[VAL_56]]#2 : (i32) -> index -// CHECK: %[[VAL_63:.*]] = fir.convert %[[VAL_62]] : (index) -> i32 -// CHECK: %[[VAL_64:.*]] = hlfir.designate %[[VAL_9]] (%[[VAL_2]]) : (!fir.ref>, index) -> !fir.ref -// CHECK: hlfir.assign %[[VAL_63]] to %[[VAL_64]] : i32, !fir.ref -// CHECK: %[[VAL_65:.*]] = hlfir.as_expr %[[VAL_9]] move %[[VAL_4]] : (!fir.ref>, i1) -> !hlfir.expr<3xi32> -// CHECK: return %[[VAL_65]] : !hlfir.expr<3xi32> -// CHECK: } - -func.func @test_partial_var(%input: !fir.box>, %mask: !fir.box>>) -> !hlfir.expr { - %dim = arith.constant 2 : i32 - %0 = hlfir.minloc %input dim %dim mask %mask {fastmath = #arith.fastmath} : (!fir.box>, i32, !fir.box>>) -> !hlfir.expr - return %0 : !hlfir.expr -} -// CHECK-LABEL: func.func @test_partial_var( -// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box>, -// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box>>) -> !hlfir.expr { -// CHECK: %[[VAL_2:.*]] = arith.constant false -// CHECK: %[[VAL_3:.*]] = arith.constant true -// CHECK: %[[VAL_4:.*]] = arith.constant 3.40282347E+38 : f32 -// CHECK: %[[VAL_5:.*]] = arith.constant 0 : i32 -// CHECK: %[[VAL_6:.*]] = arith.constant 2 : index -// CHECK: %[[VAL_7:.*]] = arith.constant 1 : index -// CHECK: %[[VAL_8:.*]] = arith.constant 0 : index -// CHECK: %[[VAL_9:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_8]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_10:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_7]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_11:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_6]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_12:.*]] = fir.shape %[[VAL_9]]#1, %[[VAL_11]]#1 : (index, index) -> !fir.shape<2> -// CHECK: %[[VAL_13:.*]] = fir.is_present %[[VAL_1]] : (!fir.box>>) -> i1 -// CHECK: %[[VAL_14:.*]] = hlfir.elemental %[[VAL_12]] unordered : (!fir.shape<2>) -> !hlfir.expr { -// CHECK: ^bb0(%[[VAL_15:.*]]: index, %[[VAL_16:.*]]: index): -// CHECK: %[[VAL_17:.*]]:3 = fir.do_loop %[[VAL_18:.*]] = %[[VAL_7]] to %[[VAL_10]]#1 step %[[VAL_7]] unordered iter_args(%[[VAL_19:.*]] = %[[VAL_5]], %[[VAL_20:.*]] = %[[VAL_4]], %[[VAL_21:.*]] = %[[VAL_3]]) -> (i32, f32, i1) { -// CHECK: %[[VAL_22:.*]] = fir.if %[[VAL_13]] -> (!fir.logical<4>) { -// CHECK: %[[VAL_23:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_8]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_24:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_7]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_25:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_6]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_26:.*]] = arith.subi %[[VAL_23]]#0, %[[VAL_7]] : index -// CHECK: %[[VAL_27:.*]] = arith.addi %[[VAL_15]], %[[VAL_26]] : index -// CHECK: %[[VAL_28:.*]] = arith.subi %[[VAL_24]]#0, %[[VAL_7]] : index -// CHECK: %[[VAL_29:.*]] = arith.addi %[[VAL_18]], %[[VAL_28]] : index -// CHECK: %[[VAL_30:.*]] = arith.subi %[[VAL_25]]#0, %[[VAL_7]] : index -// CHECK: %[[VAL_31:.*]] = arith.addi %[[VAL_16]], %[[VAL_30]] : index -// CHECK: %[[VAL_32:.*]] = hlfir.designate %[[VAL_1]] (%[[VAL_27]], %[[VAL_29]], %[[VAL_31]]) : (!fir.box>>, index, index, index) -> !fir.ref> -// CHECK: %[[VAL_33:.*]] = fir.load %[[VAL_32]] : !fir.ref> -// CHECK: fir.result %[[VAL_33]] : !fir.logical<4> -// CHECK: } else { -// CHECK: %[[VAL_34:.*]] = fir.convert %[[VAL_3]] : (i1) -> !fir.logical<4> -// CHECK: fir.result %[[VAL_34]] : !fir.logical<4> -// CHECK: } -// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_22]] : (!fir.logical<4>) -> i1 -// CHECK: %[[VAL_36:.*]]:3 = fir.if %[[VAL_35]] -> (i32, f32, i1) { -// CHECK: %[[VAL_37:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_8]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_38:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_7]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_39:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_6]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_40:.*]] = arith.subi %[[VAL_37]]#0, %[[VAL_7]] : index -// CHECK: %[[VAL_41:.*]] = arith.addi %[[VAL_15]], %[[VAL_40]] : index -// CHECK: %[[VAL_42:.*]] = arith.subi %[[VAL_38]]#0, %[[VAL_7]] : index -// CHECK: %[[VAL_43:.*]] = arith.addi %[[VAL_18]], %[[VAL_42]] : index -// CHECK: %[[VAL_44:.*]] = arith.subi %[[VAL_39]]#0, %[[VAL_7]] : index -// CHECK: %[[VAL_45:.*]] = arith.addi %[[VAL_16]], %[[VAL_44]] : index -// CHECK: %[[VAL_46:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_41]], %[[VAL_43]], %[[VAL_45]]) : (!fir.box>, index, index, index) -> !fir.ref -// CHECK: %[[VAL_47:.*]] = fir.load %[[VAL_46]] : !fir.ref -// CHECK: %[[VAL_48:.*]] = arith.cmpf olt, %[[VAL_47]], %[[VAL_20]] fastmath : f32 -// CHECK: %[[VAL_49:.*]] = arith.cmpf une, %[[VAL_20]], %[[VAL_20]] fastmath : f32 -// CHECK: %[[VAL_50:.*]] = arith.cmpf oeq, %[[VAL_47]], %[[VAL_47]] fastmath : f32 -// CHECK: %[[VAL_51:.*]] = arith.andi %[[VAL_49]], %[[VAL_50]] : i1 -// CHECK: %[[VAL_52:.*]] = arith.ori %[[VAL_48]], %[[VAL_51]] : i1 -// CHECK: %[[VAL_53:.*]] = arith.ori %[[VAL_52]], %[[VAL_21]] : i1 -// CHECK: %[[VAL_54:.*]] = fir.convert %[[VAL_18]] : (index) -> i32 -// CHECK: %[[VAL_55:.*]] = arith.select %[[VAL_53]], %[[VAL_54]], %[[VAL_19]] : i32 -// CHECK: %[[VAL_56:.*]] = arith.select %[[VAL_53]], %[[VAL_47]], %[[VAL_20]] : f32 -// CHECK: fir.result %[[VAL_55]], %[[VAL_56]], %[[VAL_2]] : i32, f32, i1 -// CHECK: } else { -// CHECK: fir.result %[[VAL_19]], %[[VAL_20]], %[[VAL_21]] : i32, f32, i1 -// CHECK: } -// CHECK: fir.result %[[VAL_57:.*]]#0, %[[VAL_57]]#1, %[[VAL_57]]#2 : i32, f32, i1 -// CHECK: } -// CHECK: %[[VAL_58:.*]] = arith.cmpi ne, %[[VAL_59:.*]]#0, %[[VAL_5]] : i32 -// CHECK: %[[VAL_60:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_7]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_61:.*]] = fir.convert %[[VAL_59]]#0 : (i32) -> index -// CHECK: %[[VAL_62:.*]] = arith.addi %[[VAL_61]], %[[VAL_60]]#0 : index -// CHECK: %[[VAL_63:.*]] = arith.subi %[[VAL_62]], %[[VAL_7]] : index -// CHECK: %[[VAL_64:.*]] = arith.select %[[VAL_58]], %[[VAL_63]], %[[VAL_61]] : index -// CHECK: %[[VAL_65:.*]] = fir.convert %[[VAL_64]] : (index) -> i32 -// CHECK: hlfir.yield_element %[[VAL_65]] : i32 -// CHECK: } -// CHECK: return %[[VAL_14]] : !hlfir.expr -// CHECK: } - -// Character comparisons are not supported yet. -func.func @test_character(%input: !fir.box>>) -> !hlfir.expr<1xi32> { - %0 = hlfir.minloc %input : (!fir.box>>) -> !hlfir.expr<1xi32> - return %0 : !hlfir.expr<1xi32> -} -// CHECK-LABEL: func.func @test_character( -// CHECK: hlfir.minloc - -// BACK is not supported yet. -func.func @test_back(%input: !hlfir.expr) -> !hlfir.expr<1xi32> { - %back = arith.constant true - %0 = hlfir.minloc %input back %back : (!hlfir.expr, i1) -> !hlfir.expr<1xi32> - return %0 : !hlfir.expr<1xi32> -} -// CHECK-LABEL: func.func @test_back( -// CHECK: hlfir.minloc diff --git a/flang/test/HLFIR/simplify-hlfir-intrinsics-minval.fir b/flang/test/HLFIR/simplify-hlfir-intrinsics-minval.fir deleted file mode 100644 index 4278ac7abd457..0000000000000 --- a/flang/test/HLFIR/simplify-hlfir-intrinsics-minval.fir +++ /dev/null @@ -1,177 +0,0 @@ -// RUN: fir-opt %s --simplify-hlfir-intrinsics | FileCheck %s - -func.func @test_total_expr(%input: !hlfir.expr, %mask: !hlfir.expr>) -> f32 { - %0 = hlfir.minval %input mask %mask {fastmath = #arith.fastmath} : (!hlfir.expr, !hlfir.expr>) -> f32 - return %0 : f32 -} -// CHECK-LABEL: func.func @test_total_expr( -// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !hlfir.expr, -// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !hlfir.expr>) -> f32 { -// CHECK: %[[VAL_2:.*]] = arith.constant 1 : index -// CHECK: %[[VAL_3:.*]] = arith.constant 3.40282347E+38 : f32 -// CHECK: %[[VAL_4:.*]] = hlfir.shape_of %[[VAL_0]] : (!hlfir.expr) -> !fir.shape<2> -// CHECK: %[[VAL_5:.*]] = hlfir.get_extent %[[VAL_4]] {dim = 0 : index} : (!fir.shape<2>) -> index -// CHECK: %[[VAL_6:.*]] = hlfir.get_extent %[[VAL_4]] {dim = 1 : index} : (!fir.shape<2>) -> index -// CHECK: %[[VAL_7:.*]] = fir.do_loop %[[VAL_8:.*]] = %[[VAL_2]] to %[[VAL_6]] step %[[VAL_2]] iter_args(%[[VAL_9:.*]] = %[[VAL_3]]) -> (f32) { -// CHECK: %[[VAL_10:.*]] = fir.do_loop %[[VAL_11:.*]] = %[[VAL_2]] to %[[VAL_5]] step %[[VAL_2]] iter_args(%[[VAL_12:.*]] = %[[VAL_9]]) -> (f32) { -// CHECK: %[[VAL_13:.*]] = hlfir.apply %[[VAL_1]], %[[VAL_11]], %[[VAL_8]] : (!hlfir.expr>, index, index) -> !fir.logical<4> -// CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_13]] : (!fir.logical<4>) -> i1 -// CHECK: %[[VAL_15:.*]] = fir.if %[[VAL_14]] -> (f32) { -// CHECK: %[[VAL_16:.*]] = hlfir.apply %[[VAL_0]], %[[VAL_11]], %[[VAL_8]] : (!hlfir.expr, index, index) -> f32 -// CHECK: %[[VAL_17:.*]] = arith.cmpf olt, %[[VAL_16]], %[[VAL_12]] fastmath : f32 -// CHECK: %[[VAL_18:.*]] = arith.cmpf une, %[[VAL_12]], %[[VAL_12]] fastmath : f32 -// CHECK: %[[VAL_19:.*]] = arith.cmpf oeq, %[[VAL_16]], %[[VAL_16]] fastmath : f32 -// CHECK: %[[VAL_20:.*]] = arith.andi %[[VAL_18]], %[[VAL_19]] : i1 -// CHECK: %[[VAL_21:.*]] = arith.ori %[[VAL_17]], %[[VAL_20]] : i1 -// CHECK: %[[VAL_22:.*]] = arith.select %[[VAL_21]], %[[VAL_16]], %[[VAL_12]] : f32 -// CHECK: fir.result %[[VAL_22]] : f32 -// CHECK: } else { -// CHECK: fir.result %[[VAL_12]] : f32 -// CHECK: } -// CHECK: fir.result %[[VAL_15]] : f32 -// CHECK: } -// CHECK: fir.result %[[VAL_10]] : f32 -// CHECK: } -// CHECK: return %[[VAL_7]] : f32 -// CHECK: } - -func.func @test_partial_expr(%input: !hlfir.expr, %mask: !hlfir.expr>) -> !hlfir.expr { - %dim = arith.constant 1 : i32 - %0 = hlfir.minval %input dim %dim mask %mask {fastmath = #arith.fastmath} : (!hlfir.expr, i32, !hlfir.expr>) -> !hlfir.expr - return %0 : !hlfir.expr -} -// CHECK-LABEL: func.func @test_partial_expr( -// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !hlfir.expr, -// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !hlfir.expr>) -> !hlfir.expr { -// CHECK: %[[VAL_2:.*]] = arith.constant 1 : index -// CHECK: %[[VAL_3:.*]] = arith.constant 1.7976931348623157E+308 : f64 -// CHECK: %[[VAL_4:.*]] = hlfir.shape_of %[[VAL_0]] : (!hlfir.expr) -> !fir.shape<2> -// CHECK: %[[VAL_5:.*]] = hlfir.get_extent %[[VAL_4]] {dim = 0 : index} : (!fir.shape<2>) -> index -// CHECK: %[[VAL_6:.*]] = hlfir.get_extent %[[VAL_4]] {dim = 1 : index} : (!fir.shape<2>) -> index -// CHECK: %[[VAL_7:.*]] = fir.shape %[[VAL_6]] : (index) -> !fir.shape<1> -// CHECK: %[[VAL_8:.*]] = hlfir.elemental %[[VAL_7]] unordered : (!fir.shape<1>) -> !hlfir.expr { -// CHECK: ^bb0(%[[VAL_9:.*]]: index): -// CHECK: %[[VAL_10:.*]] = fir.do_loop %[[VAL_11:.*]] = %[[VAL_2]] to %[[VAL_5]] step %[[VAL_2]] unordered iter_args(%[[VAL_12:.*]] = %[[VAL_3]]) -> (f64) { -// CHECK: %[[VAL_13:.*]] = hlfir.apply %[[VAL_1]], %[[VAL_11]], %[[VAL_9]] : (!hlfir.expr>, index, index) -> !fir.logical<4> -// CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_13]] : (!fir.logical<4>) -> i1 -// CHECK: %[[VAL_15:.*]] = fir.if %[[VAL_14]] -> (f64) { -// CHECK: %[[VAL_16:.*]] = hlfir.apply %[[VAL_0]], %[[VAL_11]], %[[VAL_9]] : (!hlfir.expr, index, index) -> f64 -// CHECK: %[[VAL_17:.*]] = arith.cmpf olt, %[[VAL_16]], %[[VAL_12]] fastmath : f64 -// CHECK: %[[VAL_18:.*]] = arith.cmpf une, %[[VAL_12]], %[[VAL_12]] fastmath : f64 -// CHECK: %[[VAL_19:.*]] = arith.cmpf oeq, %[[VAL_16]], %[[VAL_16]] fastmath : f64 -// CHECK: %[[VAL_20:.*]] = arith.andi %[[VAL_18]], %[[VAL_19]] : i1 -// CHECK: %[[VAL_21:.*]] = arith.ori %[[VAL_17]], %[[VAL_20]] : i1 -// CHECK: %[[VAL_22:.*]] = arith.select %[[VAL_21]], %[[VAL_16]], %[[VAL_12]] : f64 -// CHECK: fir.result %[[VAL_22]] : f64 -// CHECK: } else { -// CHECK: fir.result %[[VAL_12]] : f64 -// CHECK: } -// CHECK: fir.result %[[VAL_15]] : f64 -// CHECK: } -// CHECK: hlfir.yield_element %[[VAL_10]] : f64 -// CHECK: } -// CHECK: return %[[VAL_8]] : !hlfir.expr -// CHECK: } - -func.func @test_total_var(%input: !fir.box>, %mask: !fir.ref>>) -> f16 { - %0 = hlfir.minval %input mask %mask {fastmath = #arith.fastmath} : (!fir.box>, !fir.ref>>) -> f16 - return %0 : f16 -} -// CHECK-LABEL: func.func @test_total_var( -// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box>, -// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref>>) -> f16 { -// CHECK: %[[VAL_2:.*]] = arith.constant 6.550400e+04 : f16 -// CHECK: %[[VAL_3:.*]] = arith.constant 1 : index -// CHECK: %[[VAL_4:.*]] = arith.constant 0 : index -// CHECK: %[[VAL_5:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_6:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_7:.*]] = fir.do_loop %[[VAL_8:.*]] = %[[VAL_3]] to %[[VAL_6]]#1 step %[[VAL_3]] unordered iter_args(%[[VAL_9:.*]] = %[[VAL_2]]) -> (f16) { -// CHECK: %[[VAL_10:.*]] = fir.do_loop %[[VAL_11:.*]] = %[[VAL_3]] to %[[VAL_5]]#1 step %[[VAL_3]] unordered iter_args(%[[VAL_12:.*]] = %[[VAL_9]]) -> (f16) { -// CHECK: %[[VAL_13:.*]] = hlfir.designate %[[VAL_1]] (%[[VAL_11]], %[[VAL_8]]) : (!fir.ref>>, index, index) -> !fir.ref> -// CHECK: %[[VAL_14:.*]] = fir.load %[[VAL_13]] : !fir.ref> -// CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_14]] : (!fir.logical<1>) -> i1 -// CHECK: %[[VAL_16:.*]] = fir.if %[[VAL_15]] -> (f16) { -// CHECK: %[[VAL_17:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_18:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_19:.*]] = arith.subi %[[VAL_17]]#0, %[[VAL_3]] : index -// CHECK: %[[VAL_20:.*]] = arith.addi %[[VAL_11]], %[[VAL_19]] : index -// CHECK: %[[VAL_21:.*]] = arith.subi %[[VAL_18]]#0, %[[VAL_3]] : index -// CHECK: %[[VAL_22:.*]] = arith.addi %[[VAL_8]], %[[VAL_21]] : index -// CHECK: %[[VAL_23:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_20]], %[[VAL_22]]) : (!fir.box>, index, index) -> !fir.ref -// CHECK: %[[VAL_24:.*]] = fir.load %[[VAL_23]] : !fir.ref -// CHECK: %[[VAL_25:.*]] = arith.cmpf olt, %[[VAL_24]], %[[VAL_12]] fastmath : f16 -// CHECK: %[[VAL_26:.*]] = arith.cmpf une, %[[VAL_12]], %[[VAL_12]] fastmath : f16 -// CHECK: %[[VAL_27:.*]] = arith.cmpf oeq, %[[VAL_24]], %[[VAL_24]] fastmath : f16 -// CHECK: %[[VAL_28:.*]] = arith.andi %[[VAL_26]], %[[VAL_27]] : i1 -// CHECK: %[[VAL_29:.*]] = arith.ori %[[VAL_25]], %[[VAL_28]] : i1 -// CHECK: %[[VAL_30:.*]] = arith.select %[[VAL_29]], %[[VAL_24]], %[[VAL_12]] : f16 -// CHECK: fir.result %[[VAL_30]] : f16 -// CHECK: } else { -// CHECK: fir.result %[[VAL_12]] : f16 -// CHECK: } -// CHECK: fir.result %[[VAL_16]] : f16 -// CHECK: } -// CHECK: fir.result %[[VAL_10]] : f16 -// CHECK: } -// CHECK: return %[[VAL_7]] : f16 -// CHECK: } - -func.func @test_partial_var(%input: !fir.box>, %mask: !fir.box>>) -> !hlfir.expr { - %dim = arith.constant 2 : i32 - %0 = hlfir.minval %input dim %dim mask %mask {fastmath = #arith.fastmath} : (!fir.box>, i32, !fir.box>>) -> !hlfir.expr - return %0 : !hlfir.expr -} -// CHECK-LABEL: func.func @test_partial_var( -// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box>, -// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box>>) -> !hlfir.expr { -// CHECK: %[[VAL_2:.*]] = arith.constant true -// CHECK: %[[VAL_3:.*]] = arith.constant 6.550400e+04 : f16 -// CHECK: %[[VAL_4:.*]] = arith.constant 1 : index -// CHECK: %[[VAL_5:.*]] = arith.constant 0 : index -// CHECK: %[[VAL_6:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_7:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_8:.*]] = fir.shape %[[VAL_6]]#1 : (index) -> !fir.shape<1> -// CHECK: %[[VAL_9:.*]] = fir.is_present %[[VAL_1]] : (!fir.box>>) -> i1 -// CHECK: %[[VAL_10:.*]] = hlfir.elemental %[[VAL_8]] unordered : (!fir.shape<1>) -> !hlfir.expr { -// CHECK: ^bb0(%[[VAL_11:.*]]: index): -// CHECK: %[[VAL_12:.*]] = fir.do_loop %[[VAL_13:.*]] = %[[VAL_4]] to %[[VAL_7]]#1 step %[[VAL_4]] unordered iter_args(%[[VAL_14:.*]] = %[[VAL_3]]) -> (f16) { -// CHECK: %[[VAL_15:.*]] = fir.if %[[VAL_9]] -> (!fir.logical<1>) { -// CHECK: %[[VAL_16:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_5]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_17:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_4]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_18:.*]] = arith.subi %[[VAL_16]]#0, %[[VAL_4]] : index -// CHECK: %[[VAL_19:.*]] = arith.addi %[[VAL_11]], %[[VAL_18]] : index -// CHECK: %[[VAL_20:.*]] = arith.subi %[[VAL_17]]#0, %[[VAL_4]] : index -// CHECK: %[[VAL_21:.*]] = arith.addi %[[VAL_13]], %[[VAL_20]] : index -// CHECK: %[[VAL_22:.*]] = hlfir.designate %[[VAL_1]] (%[[VAL_19]], %[[VAL_21]]) : (!fir.box>>, index, index) -> !fir.ref> -// CHECK: %[[VAL_23:.*]] = fir.load %[[VAL_22]] : !fir.ref> -// CHECK: fir.result %[[VAL_23]] : !fir.logical<1> -// CHECK: } else { -// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_2]] : (i1) -> !fir.logical<1> -// CHECK: fir.result %[[VAL_24]] : !fir.logical<1> -// CHECK: } -// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_15]] : (!fir.logical<1>) -> i1 -// CHECK: %[[VAL_26:.*]] = fir.if %[[VAL_25]] -> (f16) { -// CHECK: %[[VAL_27:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_28:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_29:.*]] = arith.subi %[[VAL_27]]#0, %[[VAL_4]] : index -// CHECK: %[[VAL_30:.*]] = arith.addi %[[VAL_11]], %[[VAL_29]] : index -// CHECK: %[[VAL_31:.*]] = arith.subi %[[VAL_28]]#0, %[[VAL_4]] : index -// CHECK: %[[VAL_32:.*]] = arith.addi %[[VAL_13]], %[[VAL_31]] : index -// CHECK: %[[VAL_33:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_30]], %[[VAL_32]]) : (!fir.box>, index, index) -> !fir.ref -// CHECK: %[[VAL_34:.*]] = fir.load %[[VAL_33]] : !fir.ref -// CHECK: %[[VAL_35:.*]] = arith.cmpf olt, %[[VAL_34]], %[[VAL_14]] fastmath : f16 -// CHECK: %[[VAL_36:.*]] = arith.cmpf une, %[[VAL_14]], %[[VAL_14]] fastmath : f16 -// CHECK: %[[VAL_37:.*]] = arith.cmpf oeq, %[[VAL_34]], %[[VAL_34]] fastmath : f16 -// CHECK: %[[VAL_38:.*]] = arith.andi %[[VAL_36]], %[[VAL_37]] : i1 -// CHECK: %[[VAL_39:.*]] = arith.ori %[[VAL_35]], %[[VAL_38]] : i1 -// CHECK: %[[VAL_40:.*]] = arith.select %[[VAL_39]], %[[VAL_34]], %[[VAL_14]] : f16 -// CHECK: fir.result %[[VAL_40]] : f16 -// CHECK: } else { -// CHECK: fir.result %[[VAL_14]] : f16 -// CHECK: } -// CHECK: fir.result %[[VAL_26]] : f16 -// CHECK: } -// CHECK: hlfir.yield_element %[[VAL_12]] : f16 -// CHECK: } -// CHECK: return %[[VAL_10]] : !hlfir.expr -// CHECK: }