[flang-commits] [flang] d9fff42 - [flang] Lower plain DO loops without a secondary-induction iter_arg (#207816)
via flang-commits
flang-commits at lists.llvm.org
Mon Jul 20 04:11:00 PDT 2026
Author: Matsu
Date: 2026-07-20T11:10:54Z
New Revision: d9fff42ccd58cb3d95cff60641011d72d38dc300
URL: https://github.com/llvm/llvm-project/commit/d9fff42ccd58cb3d95cff60641011d72d38dc300
DIFF: https://github.com/llvm/llvm-project/commit/d9fff42ccd58cb3d95cff60641011d72d38dc300.diff
LOG: [flang] Lower plain DO loops without a secondary-induction iter_arg (#207816)
Example:
```fortran
do i = lb, ub, step
...
end do
```
Flang lowers this with the DO variable as a redundant `iter_arg`, which
hides memory recurrences from later analyses. Simply removing it would
require converting the `index` IV to the source integer type each
iteration, potentially blocking vectorization.
Fix: allow `fir.do_loop` to use the DO variable’s integer type directly.
Trip-count and post-loop calculations remain in `index`. This removes
the redundant `iter_arg` without introducing per-iteration conversions.
`do concurrent` and unstructured loops are unaffected.
Added:
Modified:
flang/include/flang/Optimizer/Dialect/FIROps.td
flang/lib/Lower/Bridge.cpp
flang/lib/Optimizer/Dialect/FIROps.cpp
flang/lib/Optimizer/Transforms/AffinePromotion.cpp
flang/lib/Optimizer/Transforms/ControlFlowConverter.cpp
flang/lib/Optimizer/Transforms/FIRToSCF.cpp
flang/test/Fir/FirToSCF/do-loop.fir
flang/test/Fir/loop01.fir
flang/test/Integration/ivdep.f90
flang/test/Lower/OpenACC/acc-cache.f90
flang/test/Lower/OpenACC/acc-declare.f90
flang/test/Lower/OpenMP/default-clause.f90
flang/test/Lower/OpenMP/hlfir-seqloop-parallel.f90
flang/test/Lower/OpenMP/parallel-private-clause-fixes.f90
flang/test/Lower/OpenMP/sections-predetermined-private.f90
flang/test/Lower/OpenMP/shared-loop.f90
flang/test/Lower/OpenMP/unstructured.f90
flang/test/Lower/OpenMP/wsloop-reduction-allocatable-array-minmax.f90
flang/test/Lower/OpenMP/wsloop-variable.f90
flang/test/Lower/allocatable-polymorphic.f90
flang/test/Lower/dispatch.f90
flang/test/Lower/do_concurrent_loop_in_nested_block.f90
flang/test/Lower/do_loop.f90
flang/test/Lower/do_loop_execute_region_wrap.f90
flang/test/Lower/do_loop_unstructured.f90
flang/test/Lower/infinite_loop.f90
flang/test/Lower/inline_directive.f90
flang/test/Lower/ivdep.f90
flang/test/Lower/loops.f90
flang/test/Lower/loops2.f90
flang/test/Lower/mixed_loops.f90
flang/test/Lower/nsw.f90
flang/test/Transforms/DoConcurrent/skip_all_nested_loops.f90
Removed:
################################################################################
diff --git a/flang/include/flang/Optimizer/Dialect/FIROps.td b/flang/include/flang/Optimizer/Dialect/FIROps.td
index df7fdb27586d9..78be358d0f97f 100644
--- a/flang/include/flang/Optimizer/Dialect/FIROps.td
+++ b/flang/include/flang/Optimizer/Dialect/FIROps.td
@@ -2468,6 +2468,7 @@ class region_Op<string mnemonic, list<Trait> traits = []> :
}
def fir_DoLoopOp : region_Op<"do_loop", [AttrSizedOperandSegments,
+ AllTypesMatch<["lowerBound", "upperBound", "step"]>,
DeclareOpInterfaceMethods<LoopLikeOpInterface,
["getYieldedValuesMutable"]>,
DeclareOpInterfaceMethods<RegionBranchOpInterface,
@@ -2475,7 +2476,8 @@ def fir_DoLoopOp : region_Op<"do_loop", [AttrSizedOperandSegments,
let summary = "generalized loop operation";
let description = [{
Generalized high-level looping construct. This operation is similar to
- MLIR's `scf.for`.
+ MLIR's `scf.for`. The bounds, step, and induction variable have the same
+ signless integer or index type.
```
%l = arith.constant 0 : index
@@ -2497,9 +2499,9 @@ def fir_DoLoopOp : region_Op<"do_loop", [AttrSizedOperandSegments,
let hasCustomAssemblyFormat = 1;
let arguments = (ins
- Index:$lowerBound,
- Index:$upperBound,
- Index:$step,
+ AnySignlessIntegerOrIndex:$lowerBound,
+ AnySignlessIntegerOrIndex:$upperBound,
+ AnySignlessIntegerOrIndex:$step,
Variadic<AnyType>:$reduceOperands,
Variadic<AnyType>:$initArgs,
OptionalAttr<UnitAttr>:$unordered,
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 42320728b03d7..909ebf98db47c 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -2832,8 +2832,9 @@ class FirConverter : public Fortran::lower::AbstractConverter {
const IncrementLoopInfo &info,
bool *isConst = nullptr) {
mlir::Location loc = toLocation();
- mlir::Type controlType = info.isStructured() ? builder->getIndexType()
- : info.getLoopVariableType();
+ mlir::Type controlType = info.isStructured() && info.isConcurrent
+ ? builder->getIndexType()
+ : info.getLoopVariableType();
Fortran::lower::StatementContext stmtCtx;
if (expr) {
if (isConst)
@@ -3064,19 +3065,18 @@ class FirConverter : public Fortran::lower::AbstractConverter {
if (genDoConcurrent)
continue;
- // The loop variable is a doLoop op argument.
- mlir::Type loopVarType = info.getLoopVariableType();
+ // Lower the loop without the secondary-induction iter_arg so memory
+ // recurrences (e.g. reductions) stay visible to later analyses. The DO
+ // variable is recomputed from the induction variable in the body; its
+ // post-loop value is materialized in genFIRIncrementLoopEnd.
auto loopOp = fir::DoLoopOp::create(
*builder, loc, lowerValue, upperValue, stepValue,
- /*unordered=*/false,
- /*finalCountValue=*/false,
- builder->createConvert(loc, loopVarType, lowerValue));
+ /*unordered=*/false, /*finalCountValue=*/false,
+ /*iterArgs=*/mlir::ValueRange{});
info.loopOp = loopOp;
builder->setInsertionPointToStart(loopOp.getBody());
- mlir::Value loopValue = loopOp.getRegionIterArgs()[0];
-
- // Update the loop variable value in case it has non-index references.
- fir::StoreOp::create(*builder, loc, loopValue, info.loopVariable);
+ fir::StoreOp::create(*builder, loc, loopOp.getInductionVar(),
+ info.loopVariable);
addLoopAnnotationAttr(info, dirs);
continue;
}
@@ -3217,23 +3217,31 @@ class FirConverter : public Fortran::lower::AbstractConverter {
continue;
}
- // End fir.do_loop.
- // Decrement tripVariable.
+ // End fir.do_loop. The loop carries no secondary-induction iter_arg, so
+ // materialize the Fortran post-loop value lb + tripCount*step after the
+ // loop for later uses of the DO variable. Compute it in the loop's
+ // index type (matching how the loop counts iterations) so the trip
+ // arithmetic does not overflow the DO variable's type for empty
+ // range-extreme loops.
auto doLoopOp = mlir::cast<fir::DoLoopOp>(info.loopOp);
- builder->setInsertionPointToEnd(doLoopOp.getBody());
- // Step loopVariable to help optimizations such as vectorization.
- // Induction variable elimination will clean up as necessary.
- mlir::Value step = builder->createConvert(
- loc, info.getLoopVariableType(), doLoopOp.getStep());
- mlir::Value loopVar =
- fir::LoadOp::create(*builder, loc, info.loopVariable);
- mlir::Value loopVarInc =
- mlir::arith::AddIOp::create(*builder, loc, loopVar, step, iofAttr);
- fir::ResultOp::create(*builder, loc, loopVarInc);
builder->setInsertionPointAfter(doLoopOp);
- // The loop control variable may be used after the loop.
- fir::StoreOp::create(*builder, loc, doLoopOp.getResult(0),
- info.loopVariable);
+ mlir::Type idxTy = builder->getIndexType();
+ mlir::Value lb =
+ builder->createConvert(loc, idxTy, doLoopOp.getLowerBound());
+ mlir::Value ub =
+ builder->createConvert(loc, idxTy, doLoopOp.getUpperBound());
+ mlir::Value st = builder->createConvert(loc, idxTy, doLoopOp.getStep());
+ mlir::Value zero = builder->createIntegerConstant(loc, idxTy, 0);
+ mlir::Value trip = mlir::arith::SubIOp::create(*builder, loc, ub, lb);
+ trip = mlir::arith::AddIOp::create(*builder, loc, trip, st);
+ trip = mlir::arith::DivSIOp::create(*builder, loc, trip, st);
+ mlir::Value empty = mlir::arith::CmpIOp::create(
+ *builder, loc, mlir::arith::CmpIPredicate::slt, trip, zero);
+ trip = mlir::arith::SelectOp::create(*builder, loc, empty, zero, trip);
+ mlir::Value last = mlir::arith::MulIOp::create(*builder, loc, trip, st);
+ last = mlir::arith::AddIOp::create(*builder, loc, lb, last);
+ last = builder->createConvert(loc, info.getLoopVariableType(), last);
+ fir::StoreOp::create(*builder, loc, last, info.loopVariable);
continue;
}
diff --git a/flang/lib/Optimizer/Dialect/FIROps.cpp b/flang/lib/Optimizer/Dialect/FIROps.cpp
index 38c662fb23a99..83495912f06c2 100644
--- a/flang/lib/Optimizer/Dialect/FIROps.cpp
+++ b/flang/lib/Optimizer/Dialect/FIROps.cpp
@@ -3782,7 +3782,7 @@ void fir::DoLoopOp::build(mlir::OpBuilder &builder,
{1, 1, 1, static_cast<int32_t>(reduceOperands.size()),
static_cast<int32_t>(iterArgs.size())}));
if (finalCountValue) {
- result.addTypes(builder.getIndexType());
+ result.addTypes(lb.getType());
result.addAttribute(getFinalValueAttrName(result.name),
builder.getUnitAttr());
}
@@ -3792,7 +3792,7 @@ void fir::DoLoopOp::build(mlir::OpBuilder &builder,
bodyRegion->push_back(new mlir::Block{});
if (iterArgs.empty() && !finalCountValue)
fir::DoLoopOp::ensureTerminator(*bodyRegion, builder, result.location);
- bodyRegion->front().addArgument(builder.getIndexType(), result.location);
+ bodyRegion->front().addArgument(lb.getType(), result.location);
bodyRegion->front().addArguments(
iterArgs.getTypes(),
llvm::SmallVector<mlir::Location>(iterArgs.size(), result.location));
@@ -3815,13 +3815,9 @@ mlir::ParseResult fir::DoLoopOp::parse(mlir::OpAsmParser &parser,
return mlir::failure();
// Parse loop bounds.
- auto indexType = builder.getIndexType();
- if (parser.parseOperand(lb) ||
- parser.resolveOperand(lb, indexType, result.operands) ||
- parser.parseKeyword("to") || parser.parseOperand(ub) ||
- parser.resolveOperand(ub, indexType, result.operands) ||
- parser.parseKeyword("step") || parser.parseOperand(step) ||
- parser.resolveOperand(step, indexType, result.operands))
+ if (parser.parseOperand(lb) || parser.parseKeyword("to") ||
+ parser.parseOperand(ub) || parser.parseKeyword("step") ||
+ parser.parseOperand(step))
return mlir::failure();
if (mlir::succeeded(parser.parseOptionalKeyword("unordered")))
@@ -3876,9 +3872,10 @@ mlir::ParseResult fir::DoLoopOp::parse(mlir::OpAsmParser &parser,
std::get<1>(operand_type), result.operands))
return mlir::failure();
} else if (succeeded(parser.parseOptionalArrow())) {
- if (parser.parseKeyword("index"))
+ mlir::Type finalValueType;
+ if (parser.parseType(finalValueType))
return mlir::failure();
- result.types.push_back(indexType);
+ result.types.push_back(finalValueType);
prependCount = true;
}
@@ -3888,6 +3885,18 @@ mlir::ParseResult fir::DoLoopOp::parse(mlir::OpAsmParser &parser,
{1, 1, 1, static_cast<int32_t>(reduceOperands.size()),
static_cast<int32_t>(iterOperands.size())}));
+ mlir::Type controlType = builder.getIndexType();
+ if (succeeded(parser.parseOptionalColon()) && parser.parseType(controlType))
+ return mlir::failure();
+
+ llvm::SmallVector<mlir::Value> controlOperands;
+ if (parser.resolveOperand(lb, controlType, controlOperands) ||
+ parser.resolveOperand(ub, controlType, controlOperands) ||
+ parser.resolveOperand(step, controlType, controlOperands))
+ return mlir::failure();
+ result.operands.insert(result.operands.begin(), controlOperands.begin(),
+ controlOperands.end());
+
if (parser.parseOptionalAttrDictWithKeyword(result.attributes))
return mlir::failure();
@@ -3895,10 +3904,12 @@ mlir::ParseResult fir::DoLoopOp::parse(mlir::OpAsmParser &parser,
if (prependCount)
result.addAttribute(DoLoopOp::getFinalValueAttrName(result.name),
builder.getUnitAttr());
- else
- argTypes.push_back(indexType);
+ argTypes.push_back(controlType);
// Loop carried variables
- argTypes.append(result.types.begin(), result.types.end());
+ mlir::TypeRange iterArgTypes = result.types;
+ if (prependCount)
+ iterArgTypes = iterArgTypes.drop_front();
+ argTypes.append(iterArgTypes.begin(), iterArgTypes.end());
// Parse the body region.
auto *body = result.addRegion();
if (regionArgs.size() != argTypes.size())
@@ -3930,10 +3941,9 @@ llvm::LogicalResult fir::DoLoopOp::verify() {
// Check that the body defines as single block argument for the induction
// variable.
auto *body = getBody();
- if (!body->getArgument(0).getType().isIndex())
- return emitOpError(
- "expected body first argument to be an index argument for "
- "the induction variable");
+ if (body->getArgument(0).getType() != getLowerBound().getType())
+ return emitOpError("expected induction variable to have the same type as "
+ "the loop control");
auto opNumResults = getNumResults();
if (opNumResults == 0)
@@ -3942,6 +3952,9 @@ llvm::LogicalResult fir::DoLoopOp::verify() {
if (getFinalValue()) {
if (getUnordered())
return emitOpError("unordered loop has no final value");
+ if (getResult(0).getType() != getLowerBound().getType())
+ return emitOpError("expected final value to have the same type as the "
+ "loop control");
opNumResults--;
}
if (getNumIterOperands() != opNumResults)
@@ -4001,6 +4014,8 @@ void fir::DoLoopOp::print(mlir::OpAsmPrinter &p) {
p << " -> " << getResultTypes();
printBlockTerminators = true;
}
+ if (!getInductionVar().getType().isIndex())
+ p << " : " << getInductionVar().getType();
p.printOptionalAttrDictWithKeyword(
(*this)->getAttrs(),
{"unordered", "finalValue", "reduceAttrs", "operandSegmentSizes"});
diff --git a/flang/lib/Optimizer/Transforms/AffinePromotion.cpp b/flang/lib/Optimizer/Transforms/AffinePromotion.cpp
index 6eaee27cf7cbe..a539411373084 100644
--- a/flang/lib/Optimizer/Transforms/AffinePromotion.cpp
+++ b/flang/lib/Optimizer/Transforms/AffinePromotion.cpp
@@ -117,6 +117,8 @@ struct AffineLoopAnalysis {
bool analyzeLoop(fir::DoLoopOp loopOperation,
AffineFunctionAnalysis &functionAnalysis) {
LLVM_DEBUG(llvm::dbgs() << "AffineLoopAnalysis: \n"; loopOperation.dump(););
+ if (!loopOperation.getLowerBound().getType().isIndex())
+ return false;
return analyzeMemoryAccess(loopOperation) &&
analysisResults(loopOperation) &&
analyzeBody(loopOperation, functionAnalysis);
diff --git a/flang/lib/Optimizer/Transforms/ControlFlowConverter.cpp b/flang/lib/Optimizer/Transforms/ControlFlowConverter.cpp
index 72fd50467b3f9..fefee609d817f 100644
--- a/flang/lib/Optimizer/Transforms/ControlFlowConverter.cpp
+++ b/flang/lib/Optimizer/Transforms/ControlFlowConverter.cpp
@@ -78,10 +78,19 @@ class CfgLoopConv : public mlir::OpRewritePattern<fir::DoLoopOp> {
// Initalization block
rewriter.setInsertionPointToEnd(initBlock);
- auto
diff = mlir::arith::SubIOp::create(rewriter, loc, high, low);
- auto distance = mlir::arith::AddIOp::create(rewriter, loc,
diff , step);
+ auto toIndex = [&](mlir::Value value) -> mlir::Value {
+ if (value.getType().isIndex())
+ return value;
+ return fir::ConvertOp::create(rewriter, loc, rewriter.getIndexType(),
+ value);
+ };
+ mlir::Value lowIndex = toIndex(low);
+ mlir::Value highIndex = toIndex(high);
+ mlir::Value stepIndex = toIndex(step);
+ auto
diff = mlir::arith::SubIOp::create(rewriter, loc, highIndex, lowIndex);
+ auto distance = mlir::arith::AddIOp::create(rewriter, loc,
diff , stepIndex);
mlir::Value iters =
- mlir::arith::DivSIOp::create(rewriter, loc, distance, step);
+ mlir::arith::DivSIOp::create(rewriter, loc, distance, stepIndex);
if (forceLoopToExecuteOnce) {
auto zero = mlir::arith::ConstantIndexOp::create(rewriter, loc, 0);
diff --git a/flang/lib/Optimizer/Transforms/FIRToSCF.cpp b/flang/lib/Optimizer/Transforms/FIRToSCF.cpp
index 53ef7163f6b53..477371c1e7385 100644
--- a/flang/lib/Optimizer/Transforms/FIRToSCF.cpp
+++ b/flang/lib/Optimizer/Transforms/FIRToSCF.cpp
@@ -47,8 +47,9 @@ struct DoLoopConversion : public mlir::OpRewritePattern<fir::DoLoopOp> {
mlir::Value high = doLoopOp.getUpperBound();
assert(low && high && "must be a Value");
mlir::Value step = doLoopOp.getStep();
+ bool hasTypedIV = !low.getType().isIndex();
mlir::SmallVector<mlir::Value> iterArgs;
- if (hasFinalValue)
+ if (hasTypedIV || hasFinalValue)
iterArgs.push_back(low);
iterArgs.append(doLoopOp.getIterOperands().begin(),
doLoopOp.getIterOperands().end());
@@ -58,16 +59,25 @@ struct DoLoopConversion : public mlir::OpRewritePattern<fir::DoLoopOp> {
// must be a positive value.
// For easier conversion, we calculate the trip count and use a canonical
// induction variable.
- auto
diff = mlir::arith::SubIOp::create(rewriter, loc, high, low);
- auto distance = mlir::arith::AddIOp::create(rewriter, loc,
diff , step);
+ auto toIndex = [&](mlir::Value value) -> mlir::Value {
+ if (value.getType().isIndex())
+ return value;
+ return fir::ConvertOp::create(rewriter, loc, rewriter.getIndexType(),
+ value);
+ };
+ mlir::Value lowIndex = toIndex(low);
+ mlir::Value highIndex = toIndex(high);
+ mlir::Value stepIndex = toIndex(step);
+ auto
diff = mlir::arith::SubIOp::create(rewriter, loc, highIndex, lowIndex);
+ auto distance = mlir::arith::AddIOp::create(rewriter, loc,
diff , stepIndex);
auto tripCount =
- mlir::arith::DivSIOp::create(rewriter, loc, distance, step);
+ mlir::arith::DivSIOp::create(rewriter, loc, distance, stepIndex);
auto zero = mlir::arith::ConstantIndexOp::create(rewriter, loc, 0);
auto one = mlir::arith::ConstantIndexOp::create(rewriter, loc, 1);
// Create the scf.for or scf.parallel operation
mlir::Operation *scfLoopOp = nullptr;
- if (isUnordered && parallelUnorderedLoop) {
+ if (isUnordered && parallelUnorderedLoop && !hasTypedIV) {
scfLoopOp = mlir::scf::ParallelOp::create(rewriter, loc, {zero},
{tripCount}, {one}, iterArgs);
} else {
@@ -88,14 +98,21 @@ struct DoLoopConversion : public mlir::OpRewritePattern<fir::DoLoopOp> {
std::prev(loopOps.end()));
rewriter.setInsertionPointToStart(&scfLoopBody);
- mlir::Value iv = mlir::arith::MulIOp::create(
- rewriter, loc, scfLoopLikeOp.getSingleInductionVar().value(), step);
- iv = mlir::arith::AddIOp::create(rewriter, loc, low, iv);
+ mlir::Value iv;
+ if (hasTypedIV) {
+ iv = scfLoopLikeOp.getRegionIterArgs().front();
+ } else {
+ iv = mlir::arith::MulIOp::create(
+ rewriter, loc, scfLoopLikeOp.getSingleInductionVar().value(), step);
+ iv = mlir::arith::AddIOp::create(rewriter, loc, low, iv);
+ }
mlir::Value firIV = doLoopOp.getInductionVar();
firIV.replaceAllUsesWith(iv);
mlir::Value finalValue;
- if (hasFinalValue) {
+ if (hasTypedIV) {
+ finalValue = mlir::arith::AddIOp::create(rewriter, loc, iv, step);
+ } else if (hasFinalValue) {
// Prefer re-using an existing `arith.addi` in the moved loop body if it
// already computes the next `iv + step`.
if (!results.empty()) {
@@ -110,21 +127,23 @@ struct DoLoopConversion : public mlir::OpRewritePattern<fir::DoLoopOp> {
finalValue = mlir::arith::AddIOp::create(rewriter, loc, iv, step);
}
- if (hasFinalValue || !results.empty()) {
+ if (hasTypedIV || hasFinalValue || !results.empty()) {
rewriter.setInsertionPointToEnd(&scfLoopBody);
llvm::SmallVector<mlir::Value> yieldOperands;
- if (hasFinalValue) {
+ if (hasTypedIV || hasFinalValue) {
yieldOperands.push_back(finalValue);
+ }
+ if (hasFinalValue)
llvm::append_range(yieldOperands, results.drop_front());
- } else {
+ else
llvm::append_range(yieldOperands, results);
- }
mlir::scf::YieldOp::create(rewriter, resultOp->getLoc(), yieldOperands);
}
rewriter.replaceAllUsesWith(
doLoopOp.getRegionIterArgs(),
- hasFinalValue ? scfLoopLikeOp.getRegionIterArgs().drop_front()
- : scfLoopLikeOp.getRegionIterArgs());
+ hasTypedIV || hasFinalValue
+ ? scfLoopLikeOp.getRegionIterArgs().drop_front()
+ : scfLoopLikeOp.getRegionIterArgs());
// Copy loop annotations from the fir.do_loop to scf loop op.
if (auto ann = doLoopOp.getLoopAnnotation())
@@ -135,7 +154,10 @@ struct DoLoopConversion : public mlir::OpRewritePattern<fir::DoLoopOp> {
if (auto parDims = doLoopOp->getAttr(mlir::acc::GPUParallelDimsAttr::name))
scfLoopOp->setAttr(mlir::acc::GPUParallelDimsAttr::name, parDims);
- rewriter.replaceOp(doLoopOp, scfLoopOp);
+ mlir::ValueRange scfResults = scfLoopOp->getResults();
+ if (hasTypedIV && !hasFinalValue)
+ scfResults = scfResults.drop_front();
+ rewriter.replaceOp(doLoopOp, scfResults);
return mlir::success();
}
diff --git a/flang/test/Fir/FirToSCF/do-loop.fir b/flang/test/Fir/FirToSCF/do-loop.fir
index 8883d795b5d2d..f81dbfc52015c 100644
--- a/flang/test/Fir/FirToSCF/do-loop.fir
+++ b/flang/test/Fir/FirToSCF/do-loop.fir
@@ -34,6 +34,32 @@ func.func @simple_loop(%arg0: !fir.ref<!fir.array<100xi32>>) {
// -----
+// CHECK-LABEL: func.func @typed_loop(
+// CHECK-SAME: %[[LB:.*]]: i32, %[[UB:.*]]: i32, %[[STEP:.*]]: i32,
+// CHECK-SAME: %[[ADDR:.*]]: !fir.ref<i32>) {
+// CHECK: %[[LB_IDX:.*]] = fir.convert %[[LB]] : (i32) -> index
+// CHECK: %[[UB_IDX:.*]] = fir.convert %[[UB]] : (i32) -> index
+// CHECK: %[[STEP_IDX:.*]] = fir.convert %[[STEP]] : (i32) -> index
+// CHECK: %[[DIFF:.*]] = arith.subi %[[UB_IDX]], %[[LB_IDX]] : index
+// CHECK: %[[DISTANCE:.*]] = arith.addi %[[DIFF]], %[[STEP_IDX]] : index
+// CHECK: %[[TRIP:.*]] = arith.divsi %[[DISTANCE]], %[[STEP_IDX]] : index
+// CHECK: %[[C0:.*]] = arith.constant 0 : index
+// CHECK: %[[C1:.*]] = arith.constant 1 : index
+// CHECK: scf.for %{{.*}} = %[[C0]] to %[[TRIP]] step %[[C1]] iter_args(%[[IV:.*]] = %[[LB]]) -> (i32) {
+// CHECK: %[[NEXT:.*]] = arith.addi %[[IV]], %[[STEP]] : i32
+// CHECK: fir.store %[[IV]] to %[[ADDR]] : !fir.ref<i32>
+// CHECK: scf.yield %[[NEXT]] : i32
+// CHECK: }
+func.func @typed_loop(%lb: i32, %ub: i32, %step: i32,
+ %addr: !fir.ref<i32>) {
+ fir.do_loop %iv = %lb to %ub step %step : i32 {
+ fir.store %iv to %addr : !fir.ref<i32>
+ }
+ return
+}
+
+// -----
+
// CHECK-LABEL: func.func @loop_with_negtive_step(
// CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.array<100xi32>>) {
// CHECK: %[[VAL_0:.*]] = arith.constant 100 : index
diff --git a/flang/test/Fir/loop01.fir b/flang/test/Fir/loop01.fir
index 30d10b9bbdb97..038626932829c 100644
--- a/flang/test/Fir/loop01.fir
+++ b/flang/test/Fir/loop01.fir
@@ -48,6 +48,33 @@ func.func private @f2() -> i1
// -----
+func.func @typed_loop(%lo: i32, %up: i32, %step: i32,
+ %addr: !fir.ref<i32>) {
+ fir.do_loop %iv = %lo to %up step %step : i32 {
+ fir.store %iv to %addr : !fir.ref<i32>
+ }
+ return
+}
+
+// CHECK-LABEL: func @typed_loop(
+// CHECK-SAME: %[[LO:.*]]: i32, %[[UP:.*]]: i32, %[[STEP:.*]]: i32,
+// CHECK-SAME: %[[ADDR:.*]]: !fir.ref<i32>) {
+// CHECK: %[[LO_IDX:.*]] = fir.convert %[[LO]] : (i32) -> index
+// CHECK: %[[UP_IDX:.*]] = fir.convert %[[UP]] : (i32) -> index
+// CHECK: %[[STEP_IDX:.*]] = fir.convert %[[STEP]] : (i32) -> index
+// CHECK: %[[DIFF:.*]] = arith.subi %[[UP_IDX]], %[[LO_IDX]] : index
+// CHECK: %[[DISTANCE:.*]] = arith.addi %[[DIFF]], %[[STEP_IDX]] : index
+// CHECK: %[[TRIP:.*]] = arith.divsi %[[DISTANCE]], %[[STEP_IDX]] : index
+// CHECK: br ^bb1(%[[LO]], %[[TRIP]] : i32, index)
+// CHECK: ^bb1(%[[IV:.*]]: i32, %[[COUNT:.*]]: index):
+// CHECK: fir.store %[[IV]] to %[[ADDR]] : !fir.ref<i32>
+// CHECK: %[[NEXT:.*]] = arith.addi %[[IV]], %[[STEP]] overflow<nsw> : i32
+// CHECK: %[[ONE:.*]] = arith.constant 1 : index
+// CHECK: %[[COUNT_NEXT:.*]] = arith.subi %[[COUNT]], %[[ONE]] : index
+// CHECK: br ^bb1(%[[NEXT]], %[[COUNT_NEXT]] : i32, index)
+
+// -----
+
func.func @x2(%lo : index, %up : index, %ok : i1) {
%c1 = arith.constant 1 : index
%unused = fir.iterate_while (%i = %lo to %up step %c1) and (%ok1 = %ok) {
diff --git a/flang/test/Integration/ivdep.f90 b/flang/test/Integration/ivdep.f90
index d72ab23af7ad2..9882fe148262f 100644
--- a/flang/test/Integration/ivdep.f90
+++ b/flang/test/Integration/ivdep.f90
@@ -16,8 +16,6 @@ subroutine ivdep_test1
!CHECK: %[[VAL_13:.*]] = add nuw nsw i64 %[[VAL_12]], 0
!CHECK: %[[VAL_14:.*]] = getelementptr nusw nuw i32, ptr {{.*}}, i64 %[[VAL_13]]
!CHECK: store i32 %[[VAL_8]], ptr %[[VAL_14]], align 4, !llvm.access.group [[DISTRINCT]]
- !CHECK: %[[VAL_15:.*]] = load i32, ptr {{.*}}, align 4, !llvm.access.group [[DISTRINCT]]
- !CHECK: %[[VAL_16:.*]] = add nsw i32 %[[VAL_15]], 1
!CHECK: %[[VAL_17:.*]] = sub i64 {{.*}}, 1
!CHECK: br label {{.*}}, !llvm.loop ![[ANNOTATION:.*]]
end do
@@ -54,8 +52,6 @@ subroutine ivdep_test2
!CHECK: %[[VAL_28:.*]] = add nuw nsw i64 %[[VAL_27]], 0
!CHECK: %[[VAL_29:.*]] = getelementptr nusw nuw i32, ptr {{.*}}, i64 %[[VAL_28]]
!CHECK: store i32 %[[VAL_24]], ptr %[[VAL_29]], align 4, !llvm.access.group [[DISTRINCT1]]
- !CHECK: %[[VAL_30:.*]] = load i32, ptr {{.*}}, align 4, !llvm.access.group [[DISTRINCT1]]
- !CHECK: %[[VAL_31:.*]] = add nsw i32 %[[VAL_30]], 1
!CHECK: %[[VAL_32:.*]] = sub i64 {{.*}}, 1
!CHECK: br label {{.*}}, !llvm.loop ![[ANNOTATION1:.*]]
end do
@@ -93,8 +89,6 @@ subroutine ivdep_test3
!CHECK: %[[VAL_29:.*]] = getelementptr nusw nuw i32, ptr {{.*}}, i64 %[[VAL_28]]
!CHECK: store i32 %[[VAL_24]], ptr %[[VAL_29]], align 4, !llvm.access.group [[DISTRINCT2]]
!CHECK: call void @_QFivdep_test3Pfoo(), !llvm.access.group [[DISTRINCT2]]
- !CHECK: %[[VAL_30:.*]] = load i32, ptr {{.*}}, align 4, !llvm.access.group [[DISTRINCT2]]
- !CHECK: %[[VAL_31:.*]] = add nsw i32 %[[VAL_30]], 1
!CHECK: %[[VAL_32:.*]] = sub i64 {{.*}}, 1
!CHECK: br label {{.*}}, !llvm.loop ![[ANNOTATION2:.*]]
end do
diff --git a/flang/test/Lower/OpenACC/acc-cache.f90 b/flang/test/Lower/OpenACC/acc-cache.f90
index eb32f3b704198..17fc445be8d04 100644
--- a/flang/test/Lower/OpenACC/acc-cache.f90
+++ b/flang/test/Lower/OpenACC/acc-cache.f90
@@ -242,9 +242,9 @@ subroutine test_cache_2d_loop_vars()
! CHECK: %[[I_DECL:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFtest_cache_2d_loop_varsEi"}
! CHECK: fir.store %[[I_IV]] to %[[I_DECL]]#0 : !fir.ref<i32>
! Inner loop j (non-acc loop, fir.do_loop)
-! CHECK: fir.do_loop %[[J_IV:.*]] = {{.*}} iter_args(%[[J_ITER:.*]] = {{.*}})
+! CHECK: fir.do_loop %[[J_IV:.*]] = {{.*}} to {{.*}} step {{.*}} : i32 {
! Inner loop iterator j is stored to j variable
-! CHECK: fir.store %[[J_ITER]] to %[[J_REF:.*]] : !fir.ref<i32>
+! CHECK: fir.store %[[J_IV]] to %[[J_REF:.*]] : !fir.ref<i32>
! Dimension 1 bounds from j: lowerbound = j-1, upperbound = j
! CHECK: %[[BOUND1:.*]] = acc.bounds lowerbound(%{{.*}} : index) upperbound(%{{.*}} : index) extent(%{{.*}} : index) stride(%{{.*}} : index) startIdx(%{{.*}} : index)
! Dimension 2 bounds from i: lowerbound = i-1, upperbound = i
diff --git a/flang/test/Lower/OpenACC/acc-declare.f90 b/flang/test/Lower/OpenACC/acc-declare.f90
index 349f5c84d5316..5f87a784eaf30 100644
--- a/flang/test/Lower/OpenACC/acc-declare.f90
+++ b/flang/test/Lower/OpenACC/acc-declare.f90
@@ -20,7 +20,7 @@ subroutine acc_declare_copy()
! CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOCA]](%{{.*}}) {acc.declare = #acc.declare<dataClause = acc_copy>, uniq_name = "_QMacc_declareFacc_declare_copyEa"} : (!fir.ref<!fir.array<100xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<100xi32>>, !fir.ref<!fir.array<100xi32>>)
! CHECK: %[[COPYIN:.*]] = acc.copyin varPtr(%[[DECL]]#0 : !fir.ref<!fir.array<100xi32>>) -> !fir.ref<!fir.array<100xi32>> {dataClause = #acc<data_clause acc_copy>, name = "a"}
! CHECK: %[[TOKEN:.*]] = acc.declare_enter dataOperands(%[[COPYIN]] : !fir.ref<!fir.array<100xi32>>)
-! CHECK: %{{.*}} = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%{{.*}} = %{{.*}}) -> (i32) {
+! CHECK: fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} {
! CHECK: }
! CHECK: acc.declare_exit token(%[[TOKEN]]) dataOperands(%[[COPYIN]] : !fir.ref<!fir.array<100xi32>>)
! CHECK: acc.copyout accPtr(%[[COPYIN]] : !fir.ref<!fir.array<100xi32>>) to varPtr(%[[DECL]]#0 : !fir.ref<!fir.array<100xi32>>) {dataClause = #acc<data_clause acc_copy>, name = "a"}
@@ -40,7 +40,7 @@ subroutine acc_declare_create()
! CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ALLOCA]](%{{.*}}) {acc.declare = #acc.declare<dataClause = acc_create>, uniq_name = "_QMacc_declareFacc_declare_createEa"} : (!fir.ref<!fir.array<100xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<100xi32>>, !fir.ref<!fir.array<100xi32>>)
! CHECK: %[[CREATE:.*]] = acc.create varPtr(%[[DECL]]#0 : !fir.ref<!fir.array<100xi32>>) -> !fir.ref<!fir.array<100xi32>> {name = "a"}
! CHECK: %[[TOKEN:.*]] = acc.declare_enter dataOperands(%[[CREATE]] : !fir.ref<!fir.array<100xi32>>)
-! CHECK: %{{.*}} = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%{{.*}} = %{{.*}}) -> (i32) {
+! CHECK: fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} {
! CHECK: }
! CHECK: acc.declare_exit token(%[[TOKEN]]) dataOperands(%[[CREATE]] : !fir.ref<!fir.array<100xi32>>)
! CHECK: acc.delete accPtr(%[[CREATE]] : !fir.ref<!fir.array<100xi32>>) {dataClause = #acc<data_clause acc_create>, name = "a"}
@@ -60,7 +60,7 @@ subroutine acc_declare_present(a)
! CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ARG0]](%{{.*}}) dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {acc.declare = #acc.declare<dataClause = acc_present>, uniq_name = "_QMacc_declareFacc_declare_presentEa"} : (!fir.ref<!fir.array<100xi32>>, !fir.shape<1>, !fir.dscope) -> (!fir.ref<!fir.array<100xi32>>, !fir.ref<!fir.array<100xi32>>)
! CHECK: %[[PRESENT:.*]] = acc.present varPtr(%[[DECL]]#0 : !fir.ref<!fir.array<100xi32>>) -> !fir.ref<!fir.array<100xi32>> {name = "a"}
! CHECK: %[[TOKEN:.*]] = acc.declare_enter dataOperands(%[[PRESENT]] : !fir.ref<!fir.array<100xi32>>)
-! CHECK: %{{.*}} = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%arg{{.*}} = %{{.*}}) -> (i32)
+! CHECK: fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} {
! CHECK: acc.declare_exit token(%[[TOKEN]]) dataOperands(%[[PRESENT]] : !fir.ref<!fir.array<100xi32>>)
! CHECK: acc.delete accPtr(%[[PRESENT]] : !fir.ref<!fir.array<100xi32>>) {dataClause = #acc<data_clause acc_present>, name = "a"}
@@ -98,7 +98,7 @@ subroutine acc_declare_copyin()
! CHECK: %[[COPYIN_A:.*]] = acc.copyin varPtr(%[[ADECL]]#0 : !fir.ref<!fir.array<100xi32>>) -> !fir.ref<!fir.array<100xi32>> {name = "a"}
! CHECK: %[[COPYIN_B:.*]] = acc.copyin varPtr(%[[BDECL]]#0 : !fir.ref<!fir.array<10xi32>>) -> !fir.ref<!fir.array<10xi32>> {dataClause = #acc<data_clause acc_copyin_readonly>, name = "b"}
! CHECK: acc.declare_enter dataOperands(%[[COPYIN_A]], %[[COPYIN_B]] : !fir.ref<!fir.array<100xi32>>, !fir.ref<!fir.array<10xi32>>)
-! CHECK: %{{.*}} = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%arg{{.*}} = %{{.*}}) -> (i32)
+! CHECK: fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} {
! CHECK: acc.delete accPtr(%[[COPYIN_A]] : !fir.ref<!fir.array<100xi32>>) {dataClause = #acc<data_clause acc_copyin>, name = "a"}
! CHECK: acc.delete accPtr(%[[COPYIN_B]] : !fir.ref<!fir.array<10xi32>>) {dataClause = #acc<data_clause acc_copyin_readonly>, name = "b"}
@@ -116,7 +116,7 @@ subroutine acc_declare_copyout()
! CHECK: %[[ADECL:.*]]:2 = hlfir.declare %[[A]](%{{.*}}) {acc.declare = #acc.declare<dataClause = acc_copyout>, uniq_name = "_QMacc_declareFacc_declare_copyoutEa"} : (!fir.ref<!fir.array<100xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<100xi32>>, !fir.ref<!fir.array<100xi32>>)
! CHECK: %[[CREATE:.*]] = acc.create varPtr(%[[ADECL]]#0 : !fir.ref<!fir.array<100xi32>>) -> !fir.ref<!fir.array<100xi32>> {dataClause = #acc<data_clause acc_copyout>, name = "a"}
! CHECK: %[[TOKEN:.*]] = acc.declare_enter dataOperands(%[[CREATE]] : !fir.ref<!fir.array<100xi32>>)
-! CHECK: %{{.*}} = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%arg{{.*}} = %{{.*}}) -> (i32)
+! CHECK: fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} {
! CHECK: acc.declare_exit token(%[[TOKEN]]) dataOperands(%[[CREATE]] : !fir.ref<!fir.array<100xi32>>)
! CHECK: acc.copyout accPtr(%[[CREATE]] : !fir.ref<!fir.array<100xi32>>) to varPtr(%[[ADECL]]#0 : !fir.ref<!fir.array<100xi32>>) {name = "a"}
! CHECK: return
@@ -135,7 +135,7 @@ subroutine acc_declare_deviceptr(a)
! CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ARG0]](%{{.*}}) dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {acc.declare = #acc.declare<dataClause = acc_deviceptr>, uniq_name = "_QMacc_declareFacc_declare_deviceptrEa"} : (!fir.ref<!fir.array<100xi32>>, !fir.shape<1>, !fir.dscope) -> (!fir.ref<!fir.array<100xi32>>, !fir.ref<!fir.array<100xi32>>)
! CHECK: %[[DEVICEPTR:.*]] = acc.deviceptr varPtr(%[[DECL]]#0 : !fir.ref<!fir.array<100xi32>>) -> !fir.ref<!fir.array<100xi32>> {name = "a"}
! CHECK: acc.declare_enter dataOperands(%[[DEVICEPTR]] : !fir.ref<!fir.array<100xi32>>)
-! CHECK: %{{.*}} = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%arg{{.*}} = %{{.*}}) -> (i32)
+! CHECK: fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} {
subroutine acc_declare_link(a)
integer :: a(100), i
@@ -151,7 +151,7 @@ subroutine acc_declare_link(a)
! CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ARG0]](%{{.*}}) dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {acc.declare = #acc.declare<dataClause = acc_declare_link>, uniq_name = "_QMacc_declareFacc_declare_linkEa"} : (!fir.ref<!fir.array<100xi32>>, !fir.shape<1>, !fir.dscope) -> (!fir.ref<!fir.array<100xi32>>, !fir.ref<!fir.array<100xi32>>)
! CHECK: %[[LINK:.*]] = acc.declare_link varPtr(%[[DECL]]#0 : !fir.ref<!fir.array<100xi32>>) -> !fir.ref<!fir.array<100xi32>> {name = "a"}
! CHECK: acc.declare_enter dataOperands(%[[LINK]] : !fir.ref<!fir.array<100xi32>>)
-! CHECK: %{{.*}} = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%arg{{.*}} = %{{.*}}) -> (i32)
+! CHECK: fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} {
subroutine acc_declare_device_resident(a)
integer :: a(100), i
@@ -167,7 +167,7 @@ subroutine acc_declare_device_resident(a)
! CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ARG0]](%{{.*}}) dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {acc.declare = #acc.declare<dataClause = acc_declare_device_resident>, uniq_name = "_QMacc_declareFacc_declare_device_residentEa"} : (!fir.ref<!fir.array<100xi32>>, !fir.shape<1>, !fir.dscope) -> (!fir.ref<!fir.array<100xi32>>, !fir.ref<!fir.array<100xi32>>)
! CHECK: %[[DEVICERES:.*]] = acc.declare_device_resident varPtr(%[[DECL]]#0 : !fir.ref<!fir.array<100xi32>>) -> !fir.ref<!fir.array<100xi32>> {name = "a"}
! CHECK: %[[TOKEN:.*]] = acc.declare_enter dataOperands(%[[DEVICERES]] : !fir.ref<!fir.array<100xi32>>)
-! CHECK: %{{.*}} = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%arg{{.*}} = %{{.*}}) -> (i32)
+! CHECK: fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} {
! CHECK: acc.declare_exit token(%[[TOKEN]]) dataOperands(%[[DEVICERES]] : !fir.ref<!fir.array<100xi32>>)
! CHECK: acc.delete accPtr(%[[DEVICERES]] : !fir.ref<!fir.array<100xi32>>) {dataClause = #acc<data_clause acc_declare_device_resident>, name = "a"}
@@ -296,7 +296,7 @@ subroutine acc_declare_multiple_directive(a, b)
! CHECK: %[[COPYIN:.*]] = acc.copyin varPtr(%[[DECL_A]]#0 : !fir.ref<!fir.array<100xi32>>) -> !fir.ref<!fir.array<100xi32>> {dataClause = #acc<data_clause acc_copy>, name = "a"}
! CHECK: %[[CREATE:.*]] = acc.create varPtr(%[[DECL_B]]#0 : !fir.ref<!fir.array<100xi32>>) -> !fir.ref<!fir.array<100xi32>> {dataClause = #acc<data_clause acc_copyout>, name = "b"}
! CHECK: acc.declare_enter dataOperands(%[[COPYIN]], %[[CREATE]] : !fir.ref<!fir.array<100xi32>>, !fir.ref<!fir.array<100xi32>>)
-! CHECK: %{{.*}} = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%{{.*}} = %{{.*}}) -> (i32) {
+! CHECK: fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} {
! CHECK: acc.copyout accPtr(%[[CREATE]] : !fir.ref<!fir.array<100xi32>>) to varPtr(%[[DECL_B]]#0 : !fir.ref<!fir.array<100xi32>>) {name = "b"}
diff --git a/flang/test/Lower/OpenMP/default-clause.f90 b/flang/test/Lower/OpenMP/default-clause.f90
index c16d19c129b8f..511abf64c202f 100644
--- a/flang/test/Lower/OpenMP/default-clause.f90
+++ b/flang/test/Lower/OpenMP/default-clause.f90
@@ -463,12 +463,12 @@ subroutine nested_constructs
!CHECK: %[[INNER_J_DECL:.*]]:2 = hlfir.declare %[[INNER_J]] {{.*}}
!$omp parallel default(private) firstprivate(y)
-!CHECK: {{.*}} = fir.do_loop {{.*}} {
+!CHECK: fir.do_loop {{.*}} {
do i = 1, 10
!CHECK: %[[CONST_1:.*]] = arith.constant 1 : i32
!CHECK: hlfir.assign %[[CONST_1]] to %[[INNER_Y_DECL]]#0 : i32, !fir.ref<i32>
y = 1
-!CHECK: {{.*}} = fir.do_loop {{.*}} {
+!CHECK: fir.do_loop {{.*}} {
do j = 1, 10
!CHECK: %[[CONST_20:.*]] = arith.constant 20 : i32
!CHECK: hlfir.assign %[[CONST_20]] to %[[INNER_Z_DECL]]#0 : i32, !fir.ref<i32>
diff --git a/flang/test/Lower/OpenMP/hlfir-seqloop-parallel.f90 b/flang/test/Lower/OpenMP/hlfir-seqloop-parallel.f90
index 7324b3c49fd6f..9f0c1974efcb4 100644
--- a/flang/test/Lower/OpenMP/hlfir-seqloop-parallel.f90
+++ b/flang/test/Lower/OpenMP/hlfir-seqloop-parallel.f90
@@ -22,9 +22,21 @@ subroutine sb1
!CHECK: %[[I_DECL:.*]]:2 = hlfir.declare %[[I_ADDR]] {uniq_name = "_QFsb1Ei"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
!CHECK: omp.parallel private({{.*}} %[[I_DECL]]#0 -> %[[I_PVT_ADDR:.*]] : {{.*}}) {
!CHECK: %[[I_PVT_DECL:.*]]:2 = hlfir.declare %[[I_PVT_ADDR]] {uniq_name = "_QFsb1Ei"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
-!CHECK: %[[I_FINAL_VAL:.*]] = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%[[I_VAL:.*]] = %{{.*}}) -> (i32) {
+!CHECK: fir.do_loop %[[I_VAL:.*]] = %[[I_LB:.*]] to %[[I_UB:.*]] step %[[I_ST:.*]] : i32 {
!CHECK: fir.store %[[I_VAL]] to %[[I_PVT_DECL]]#0 : !fir.ref<i32>
!CHECK: }
+!CHECK: %[[I_LB_IDX:.*]] = fir.convert %[[I_LB]] : (i32) -> index
+!CHECK: %[[I_UB_IDX:.*]] = fir.convert %[[I_UB]] : (i32) -> index
+!CHECK: %[[I_ST_IDX:.*]] = fir.convert %[[I_ST]] : (i32) -> index
+!CHECK: %[[I_C0:.*]] = arith.constant 0 : index
+!CHECK: %[[I_D:.*]] = arith.subi %[[I_UB_IDX]], %[[I_LB_IDX]] : index
+!CHECK: %[[I_A:.*]] = arith.addi %[[I_D]], %[[I_ST_IDX]] : index
+!CHECK: %[[I_TR:.*]] = arith.divsi %[[I_A]], %[[I_ST_IDX]] : index
+!CHECK: %[[I_CMP:.*]] = arith.cmpi slt, %[[I_TR]], %[[I_C0]] : index
+!CHECK: %[[I_SEL:.*]] = arith.select %[[I_CMP]], %[[I_C0]], %[[I_TR]] : index
+!CHECK: %[[I_M:.*]] = arith.muli %[[I_SEL]], %[[I_ST_IDX]] : index
+!CHECK: %[[I_IDX:.*]] = arith.addi %[[I_LB_IDX]], %[[I_M]] : index
+!CHECK: %[[I_FINAL_VAL:.*]] = fir.convert %[[I_IDX]] : (index) -> i32
!CHECK: fir.store %[[I_FINAL_VAL]] to %[[I_PVT_DECL]]#0 : !fir.ref<i32>
!CHECK: omp.terminator
!CHECK: }
@@ -58,19 +70,55 @@ subroutine sb2
!CHECK: %[[I_PVT_DECL:.*]]:2 = hlfir.declare %[[I_PVT_ADDR]] {uniq_name = "_QFsb2Ei"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
-!CHECK: %[[FINAL_J_VAL:.*]] = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%[[J_VAL:.*]] = %{{.*}}) -> (i32) {
+!CHECK: fir.do_loop %[[J_VAL:.*]] = %[[J_LB:.*]] to %[[J_UB:.*]] step %[[J_ST:.*]] : i32 {
!CHECK: fir.store %[[J_VAL]] to %[[J_PVT_DECL]]#0 : !fir.ref<i32>
!CHECK: fir.if %{{.*}} {
-!CHECK: %[[FINAL_I_VAL:.*]] = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%[[I_VAL:.*]] = %{{.*}}) -> (i32) {
+!CHECK: fir.do_loop %[[I_VAL:.*]] = %[[I_LB:.*]] to %[[I_UB:.*]] step %[[I_ST:.*]] : i32 {
!CHECK: fir.store %[[I_VAL]] to %[[I_PVT_DECL]]#0 : !fir.ref<i32>
!CHECK: }
+!CHECK: %[[I_LB_IDX:.*]] = fir.convert %[[I_LB]] : (i32) -> index
+!CHECK: %[[I_UB_IDX:.*]] = fir.convert %[[I_UB]] : (i32) -> index
+!CHECK: %[[I_ST_IDX:.*]] = fir.convert %[[I_ST]] : (i32) -> index
+!CHECK: %[[I_C0:.*]] = arith.constant 0 : index
+!CHECK: %[[I_D:.*]] = arith.subi %[[I_UB_IDX]], %[[I_LB_IDX]] : index
+!CHECK: %[[I_A:.*]] = arith.addi %[[I_D]], %[[I_ST_IDX]] : index
+!CHECK: %[[I_TR:.*]] = arith.divsi %[[I_A]], %[[I_ST_IDX]] : index
+!CHECK: %[[I_CMP:.*]] = arith.cmpi slt, %[[I_TR]], %[[I_C0]] : index
+!CHECK: %[[I_SEL:.*]] = arith.select %[[I_CMP]], %[[I_C0]], %[[I_TR]] : index
+!CHECK: %[[I_M:.*]] = arith.muli %[[I_SEL]], %[[I_ST_IDX]] : index
+!CHECK: %[[I_IDX:.*]] = arith.addi %[[I_LB_IDX]], %[[I_M]] : index
+!CHECK: %[[FINAL_I_VAL:.*]] = fir.convert %[[I_IDX]] : (index) -> i32
!CHECK: fir.store %[[FINAL_I_VAL]] to %[[I_PVT_DECL]]#0 : !fir.ref<i32>
!CHECK: }
-!CHECK: %[[FINAL_I_VAL:.*]] = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%[[I_VAL:.*]] = %{{.*}}) -> (i32) {
-!CHECK: fir.store %[[I_VAL]] to %[[I_PVT_DECL]]#0 : !fir.ref<i32>
+!CHECK: fir.do_loop %[[I_VAL2:.*]] = %[[I2_LB:.*]] to %[[I2_UB:.*]] step %[[I2_ST:.*]] : i32 {
+!CHECK: fir.store %[[I_VAL2]] to %[[I_PVT_DECL]]#0 : !fir.ref<i32>
!CHECK: }
-!CHECK: fir.store %[[FINAL_I_VAL]] to %[[I_PVT_DECL]]#0 : !fir.ref<i32>
+!CHECK: %[[I2_LB_IDX:.*]] = fir.convert %[[I2_LB]] : (i32) -> index
+!CHECK: %[[I2_UB_IDX:.*]] = fir.convert %[[I2_UB]] : (i32) -> index
+!CHECK: %[[I2_ST_IDX:.*]] = fir.convert %[[I2_ST]] : (i32) -> index
+!CHECK: %[[I2_C0:.*]] = arith.constant 0 : index
+!CHECK: %[[I2_D:.*]] = arith.subi %[[I2_UB_IDX]], %[[I2_LB_IDX]] : index
+!CHECK: %[[I2_A:.*]] = arith.addi %[[I2_D]], %[[I2_ST_IDX]] : index
+!CHECK: %[[I2_TR:.*]] = arith.divsi %[[I2_A]], %[[I2_ST_IDX]] : index
+!CHECK: %[[I2_CMP:.*]] = arith.cmpi slt, %[[I2_TR]], %[[I2_C0]] : index
+!CHECK: %[[I2_SEL:.*]] = arith.select %[[I2_CMP]], %[[I2_C0]], %[[I2_TR]] : index
+!CHECK: %[[I2_M:.*]] = arith.muli %[[I2_SEL]], %[[I2_ST_IDX]] : index
+!CHECK: %[[I2_IDX:.*]] = arith.addi %[[I2_LB_IDX]], %[[I2_M]] : index
+!CHECK: %[[FINAL_I_VAL2:.*]] = fir.convert %[[I2_IDX]] : (index) -> i32
+!CHECK: fir.store %[[FINAL_I_VAL2]] to %[[I_PVT_DECL]]#0 : !fir.ref<i32>
!CHECK: }
+!CHECK: %[[J_LB_IDX:.*]] = fir.convert %[[J_LB]] : (i32) -> index
+!CHECK: %[[J_UB_IDX:.*]] = fir.convert %[[J_UB]] : (i32) -> index
+!CHECK: %[[J_ST_IDX:.*]] = fir.convert %[[J_ST]] : (i32) -> index
+!CHECK: %[[J_C0:.*]] = arith.constant 0 : index
+!CHECK: %[[J_D:.*]] = arith.subi %[[J_UB_IDX]], %[[J_LB_IDX]] : index
+!CHECK: %[[J_A:.*]] = arith.addi %[[J_D]], %[[J_ST_IDX]] : index
+!CHECK: %[[J_TR:.*]] = arith.divsi %[[J_A]], %[[J_ST_IDX]] : index
+!CHECK: %[[J_CMP:.*]] = arith.cmpi slt, %[[J_TR]], %[[J_C0]] : index
+!CHECK: %[[J_SEL:.*]] = arith.select %[[J_CMP]], %[[J_C0]], %[[J_TR]] : index
+!CHECK: %[[J_M:.*]] = arith.muli %[[J_SEL]], %[[J_ST_IDX]] : index
+!CHECK: %[[J_IDX:.*]] = arith.addi %[[J_LB_IDX]], %[[J_M]] : index
+!CHECK: %[[FINAL_J_VAL:.*]] = fir.convert %[[J_IDX]] : (index) -> i32
!CHECK: fir.store %[[FINAL_J_VAL]] to %[[J_PVT_DECL]]#0 : !fir.ref<i32>
!CHECK: omp.terminator
!CHECK: }
diff --git a/flang/test/Lower/OpenMP/parallel-private-clause-fixes.f90 b/flang/test/Lower/OpenMP/parallel-private-clause-fixes.f90
index e2fbd8b7d1ac9..38a42fed442c1 100644
--- a/flang/test/Lower/OpenMP/parallel-private-clause-fixes.f90
+++ b/flang/test/Lower/OpenMP/parallel-private-clause-fixes.f90
@@ -53,25 +53,28 @@
! CHECK-DAG: %[[PRIV_J_DECL:.*]]:2 = hlfir.declare %[[PRIV_J]] {uniq_name = "_QFmultiple_private_fixEj"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
! CHECK-DAG: %[[PRIV_X_DECL:.*]]:2 = hlfir.declare %[[PRIV_X]] {uniq_name = "_QFmultiple_private_fixEx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
! CHECK: hlfir.assign %[[VAL_6]] to %[[PRIV_I_DECL]]#0 : i32, !fir.ref<i32>
-! CHECK: %[[VAL_7:.*]] = arith.constant 1 : i32
-! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_7]] : (i32) -> index
-! CHECK: %[[VAL_9:.*]] = fir.load %[[GAMA_DECL]]#0 : !fir.ref<i32>
-! CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_9]] : (i32) -> index
-! CHECK: %[[VAL_11:.*]] = arith.constant 1 : index
-! CHECK: %[[LB:.*]] = fir.convert %[[VAL_8]] : (index) -> i32
-! CHECK: %[[VAL_12:.*]] = fir.do_loop %[[VAL_13:[^ ]*]] =
-! CHECK-SAME: %[[VAL_8]] to %[[VAL_10]] step %[[VAL_11]]
-! CHECK-SAME: iter_args(%[[IV:.*]] = %[[LB]]) -> (i32) {
-! CHECK: fir.store %[[IV]] to %[[PRIV_J_DECL]]#0 : !fir.ref<i32>
+! CHECK: %[[VAL_8:.*]] = arith.constant 1 : i32
+! CHECK: %[[VAL_10:.*]] = fir.load %[[GAMA_DECL]]#0 : !fir.ref<i32>
+! CHECK: %[[VAL_11:.*]] = arith.constant 1 : i32
+! CHECK: fir.do_loop %[[VAL_13:[^ ]*]] = %[[VAL_8]] to %[[VAL_10]] step %[[VAL_11]] : i32 {
+! CHECK: fir.store %[[VAL_13]] to %[[PRIV_J_DECL]]#0 : !fir.ref<i32>
! CHECK: %[[LOAD:.*]] = fir.load %[[PRIV_I_DECL]]#0 : !fir.ref<i32>
! CHECK: %[[VAL_15:.*]] = fir.load %[[PRIV_J_DECL]]#0 : !fir.ref<i32>
! CHECK: %[[VAL_16:.*]] = arith.addi %[[LOAD]], %[[VAL_15]] : i32
! CHECK: hlfir.assign %[[VAL_16]] to %[[PRIV_X_DECL]]#0 : i32, !fir.ref<i32>
-! CHECK: %[[STEPCAST:.*]] = fir.convert %[[VAL_11]] : (index) -> i32
-! CHECK: %[[IVLOAD:.*]] = fir.load %[[PRIV_J_DECL]]#0 : !fir.ref<i32>
-! CHECK: %[[IVINC:.*]] = arith.addi %[[IVLOAD]], %[[STEPCAST]] overflow<nsw> :
-! CHECK: fir.result %[[IVINC]] : i32
! CHECK: }
+! CHECK: %[[VAL_8_IDX:.*]] = fir.convert %[[VAL_8]] : (i32) -> index
+! CHECK: %[[VAL_10_IDX:.*]] = fir.convert %[[VAL_10]] : (i32) -> index
+! CHECK: %[[VAL_11_IDX:.*]] = fir.convert %[[VAL_11]] : (i32) -> index
+! CHECK: %[[C0:.*]] = arith.constant 0 : index
+! CHECK: %[[DIFF:.*]] = arith.subi %[[VAL_10_IDX]], %[[VAL_8_IDX]] : index
+! CHECK: %[[ADD:.*]] = arith.addi %[[DIFF]], %[[VAL_11_IDX]] : index
+! CHECK: %[[TRIP:.*]] = arith.divsi %[[ADD]], %[[VAL_11_IDX]] : index
+! CHECK: %[[CMP:.*]] = arith.cmpi slt, %[[TRIP]], %[[C0]] : index
+! CHECK: %[[SEL:.*]] = arith.select %[[CMP]], %[[C0]], %[[TRIP]] : index
+! CHECK: %[[MUL:.*]] = arith.muli %[[SEL]], %[[VAL_11_IDX]] : index
+! CHECK: %[[IDX:.*]] = arith.addi %[[VAL_8_IDX]], %[[MUL]] : index
+! CHECK: %[[VAL_12:.*]] = fir.convert %[[IDX]] : (index) -> i32
! CHECK: fir.store %[[VAL_12]] to %[[PRIV_J_DECL]]#0 : !fir.ref<i32>
! CHECK: omp.yield
! CHECK: }
diff --git a/flang/test/Lower/OpenMP/sections-predetermined-private.f90 b/flang/test/Lower/OpenMP/sections-predetermined-private.f90
index 3313feb3d7021..95a7cdc7b653d 100644
--- a/flang/test/Lower/OpenMP/sections-predetermined-private.f90
+++ b/flang/test/Lower/OpenMP/sections-predetermined-private.f90
@@ -15,15 +15,41 @@
! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_3]] {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
! CHECK: omp.sections {
! CHECK: omp.section {
-! CHECK: %[[VAL_11:.*]] = fir.do_loop %[[VAL_12:.*]] = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%{{.*}} = %{{.*}} -> (i32) {
+! CHECK: fir.do_loop %[[VAL_12:.*]] = %[[LB1:.*]] to %[[UB1:.*]] step %[[ST1:.*]] : i32 {
+! CHECK: fir.store %[[VAL_12]] to %[[VAL_4]]#0 : !fir.ref<i32>
! CHECK: }
-! CHECK: fir.store %[[VAL_11]] to %[[VAL_4]]#0 : !fir.ref<i32>
+! CHECK: %[[LB1IDX:.*]] = fir.convert %[[LB1]] : (i32) -> index
+! CHECK: %[[UB1IDX:.*]] = fir.convert %[[UB1]] : (i32) -> index
+! CHECK: %[[ST1IDX:.*]] = fir.convert %[[ST1]] : (i32) -> index
+! CHECK: %[[C01:.*]] = arith.constant 0 : index
+! CHECK: %[[D1:.*]] = arith.subi %[[UB1IDX]], %[[LB1IDX]] : index
+! CHECK: %[[A1:.*]] = arith.addi %[[D1]], %[[ST1IDX]] : index
+! CHECK: %[[TR1:.*]] = arith.divsi %[[A1]], %[[ST1IDX]] : index
+! CHECK: %[[CMP1:.*]] = arith.cmpi slt, %[[TR1]], %[[C01]] : index
+! CHECK: %[[SEL1:.*]] = arith.select %[[CMP1]], %[[C01]], %[[TR1]] : index
+! CHECK: %[[M1:.*]] = arith.muli %[[SEL1]], %[[ST1IDX]] : index
+! CHECK: %[[LAST1IDX:.*]] = arith.addi %[[LB1IDX]], %[[M1]] : index
+! CHECK: %[[LAST1:.*]] = fir.convert %[[LAST1IDX]] : (index) -> i32
+! CHECK: fir.store %[[LAST1]] to %[[VAL_4]]#0 : !fir.ref<i32>
! CHECK: omp.terminator
! CHECK: }
! CHECK: omp.section {
-! CHECK: %[[VAL_25:.*]] = fir.do_loop %[[VAL_26:.*]] = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%{{.*}} = %{{.*}}) -> (i32) {
+! CHECK: fir.do_loop %[[VAL_26:.*]] = %[[LB2:.*]] to %[[UB2:.*]] step %[[ST2:.*]] : i32 {
+! CHECK: fir.store %[[VAL_26]] to %[[VAL_4]]#0 : !fir.ref<i32>
! CHECK: }
-! CHECK: fir.store %[[VAL_25]] to %[[VAL_4]]#0 : !fir.ref<i32>
+! CHECK: %[[LB2IDX:.*]] = fir.convert %[[LB2]] : (i32) -> index
+! CHECK: %[[UB2IDX:.*]] = fir.convert %[[UB2]] : (i32) -> index
+! CHECK: %[[ST2IDX:.*]] = fir.convert %[[ST2]] : (i32) -> index
+! CHECK: %[[C02:.*]] = arith.constant 0 : index
+! CHECK: %[[D2:.*]] = arith.subi %[[UB2IDX]], %[[LB2IDX]] : index
+! CHECK: %[[A2:.*]] = arith.addi %[[D2]], %[[ST2IDX]] : index
+! CHECK: %[[TR2:.*]] = arith.divsi %[[A2]], %[[ST2IDX]] : index
+! CHECK: %[[CMP2:.*]] = arith.cmpi slt, %[[TR2]], %[[C02]] : index
+! CHECK: %[[SEL2:.*]] = arith.select %[[CMP2]], %[[C02]], %[[TR2]] : index
+! CHECK: %[[M2:.*]] = arith.muli %[[SEL2]], %[[ST2IDX]] : index
+! CHECK: %[[LAST2IDX:.*]] = arith.addi %[[LB2IDX]], %[[M2]] : index
+! CHECK: %[[LAST2:.*]] = fir.convert %[[LAST2IDX]] : (index) -> i32
+! CHECK: fir.store %[[LAST2]] to %[[VAL_4]]#0 : !fir.ref<i32>
! CHECK: omp.terminator
! CHECK: }
! CHECK: omp.terminator
diff --git a/flang/test/Lower/OpenMP/shared-loop.f90 b/flang/test/Lower/OpenMP/shared-loop.f90
index eb277efb2d3de..5ea4bbb0b260d 100644
--- a/flang/test/Lower/OpenMP/shared-loop.f90
+++ b/flang/test/Lower/OpenMP/shared-loop.f90
@@ -9,14 +9,23 @@
! CHECK: omp.parallel {
! CHECK: omp.sections {
! CHECK: omp.section {
-! CHECK: %[[RES:.*]] = fir.do_loop %[[ARG0:.*]] = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%[[ARG1:.*]] =
-! CHECK: fir.store %[[ARG1]] to %[[DECL_I]]#0
+! CHECK: fir.do_loop %[[ARG0:.*]] = %[[LB:.*]] to %[[UB:.*]] step %[[STEP:.*]] : i32 {
+! CHECK: fir.store %[[ARG0]] to %[[DECL_I]]#0
! CHECK: hlfir.assign
-! CHECK: %[[LOAD_I:.*]] = fir.load %[[DECL_I]]#0
-! CHECK: %[[RES_I:.*]] = arith.addi %[[LOAD_I]], %{{.*}}
-! CHECK: fir.result %[[RES_I]]
! CHECK: }
-! CHECK: fir.store %[[RES]] to %[[DECL_I]]#0
+! CHECK: %[[LBIDX:.*]] = fir.convert %[[LB]] : (i32) -> index
+! CHECK: %[[UBIDX:.*]] = fir.convert %[[UB]] : (i32) -> index
+! CHECK: %[[STEPIDX:.*]] = fir.convert %[[STEP]] : (i32) -> index
+! CHECK: %[[C0:.*]] = arith.constant 0 : index
+! CHECK: %[[DIFF:.*]] = arith.subi %[[UBIDX]], %[[LBIDX]] : index
+! CHECK: %[[ADDT:.*]] = arith.addi %[[DIFF]], %[[STEPIDX]] : index
+! CHECK: %[[TRIP:.*]] = arith.divsi %[[ADDT]], %[[STEPIDX]] : index
+! CHECK: %[[CMP:.*]] = arith.cmpi slt, %[[TRIP]], %[[C0]] : index
+! CHECK: %[[SEL:.*]] = arith.select %[[CMP]], %[[C0]], %[[TRIP]] : index
+! CHECK: %[[MUL:.*]] = arith.muli %[[SEL]], %[[STEPIDX]] : index
+! CHECK: %[[IDX:.*]] = arith.addi %[[LBIDX]], %[[MUL]] : index
+! CHECK: %[[LAST:.*]] = fir.convert %[[IDX]] : (index) -> i32
+! CHECK: fir.store %[[LAST]] to %[[DECL_I]]#0
! CHECK: omp.terminator
! CHECK: }
! CHECK: omp.terminator
@@ -47,15 +56,24 @@ subroutine omploop
! CHECK: %[[DECL_PRIV_I:.*]]:2 = hlfir.declare %[[ALLOC_PRIV_I]]
! CHECK: omp.sections {
! CHECK: omp.section {
-! CHECK: %[[RES:.*]] = fir.do_loop %[[ARG0:.*]] = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%[[ARG1:.*]] =
-! CHECK-NOT: fir.store %[[ARG1]] to %[[DECL_I]]#1
-! CHECK: fir.store %[[ARG1]] to %[[DECL_PRIV_I]]#0
+! CHECK: fir.do_loop %[[ARG0:.*]] = %[[LB:.*]] to %[[UB:.*]] step %[[STEP:.*]] : i32 {
+! CHECK-NOT: fir.store %{{.*}} to %[[DECL_I]]#1
+! CHECK: fir.store %[[ARG0]] to %[[DECL_PRIV_I]]#0
! CHECK: hlfir.assign
-! CHECK: %[[LOAD_I:.*]] = fir.load %[[DECL_PRIV_I]]#0
-! CHECK: %[[RES_I:.*]] = arith.addi %[[LOAD_I]], %{{.*}}
-! CHECK: fir.result %[[RES_I]]
! CHECK: }
-! CHECK: fir.store %[[RES]] to %[[DECL_PRIV_I]]#0
+! CHECK: %[[LBIDX:.*]] = fir.convert %[[LB]] : (i32) -> index
+! CHECK: %[[UBIDX:.*]] = fir.convert %[[UB]] : (i32) -> index
+! CHECK: %[[STEPIDX:.*]] = fir.convert %[[STEP]] : (i32) -> index
+! CHECK: %[[C0:.*]] = arith.constant 0 : index
+! CHECK: %[[DIFF:.*]] = arith.subi %[[UBIDX]], %[[LBIDX]] : index
+! CHECK: %[[ADDT:.*]] = arith.addi %[[DIFF]], %[[STEPIDX]] : index
+! CHECK: %[[TRIP:.*]] = arith.divsi %[[ADDT]], %[[STEPIDX]] : index
+! CHECK: %[[CMP:.*]] = arith.cmpi slt, %[[TRIP]], %[[C0]] : index
+! CHECK: %[[SEL:.*]] = arith.select %[[CMP]], %[[C0]], %[[TRIP]] : index
+! CHECK: %[[MUL:.*]] = arith.muli %[[SEL]], %[[STEPIDX]] : index
+! CHECK: %[[IDX:.*]] = arith.addi %[[LBIDX]], %[[MUL]] : index
+! CHECK: %[[LAST:.*]] = fir.convert %[[IDX]] : (index) -> i32
+! CHECK: fir.store %[[LAST]] to %[[DECL_PRIV_I]]#0
! CHECK: omp.terminator
! CHECK: }
! CHECK: omp.terminator
@@ -87,15 +105,24 @@ subroutine omploop2
! CHECK: %[[DECL_PRIV_I:.*]]:2 = hlfir.declare %[[ALLOC_PRIV_I]]
! CHECK: omp.sections {
! CHECK: omp.section {
-! CHECK: %[[RES:.*]] = fir.do_loop %[[ARG0:.*]] = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%[[ARG1:.*]] =
-! CHECK-NOT: fir.store %[[ARG1]] to %[[DECL_I]]#1
-! CHECK: fir.store %[[ARG1]] to %[[DECL_PRIV_I]]#0
+! CHECK: fir.do_loop %[[ARG0:.*]] = %[[LB:.*]] to %[[UB:.*]] step %[[STEP:.*]] : i32 {
+! CHECK-NOT: fir.store %{{.*}} to %[[DECL_I]]#1
+! CHECK: fir.store %[[ARG0]] to %[[DECL_PRIV_I]]#0
! CHECK: hlfir.assign
-! CHECK: %[[LOAD_I:.*]] = fir.load %[[DECL_PRIV_I]]#0
-! CHECK: %[[RES_I:.*]] = arith.addi %[[LOAD_I]], %{{.*}}
-! CHECK: fir.result %[[RES_I]]
! CHECK: }
-! CHECK: fir.store %[[RES]] to %[[DECL_PRIV_I]]#0
+! CHECK: %[[LBIDX:.*]] = fir.convert %[[LB]] : (i32) -> index
+! CHECK: %[[UBIDX:.*]] = fir.convert %[[UB]] : (i32) -> index
+! CHECK: %[[STEPIDX:.*]] = fir.convert %[[STEP]] : (i32) -> index
+! CHECK: %[[C0:.*]] = arith.constant 0 : index
+! CHECK: %[[DIFF:.*]] = arith.subi %[[UBIDX]], %[[LBIDX]] : index
+! CHECK: %[[ADDT:.*]] = arith.addi %[[DIFF]], %[[STEPIDX]] : index
+! CHECK: %[[TRIP:.*]] = arith.divsi %[[ADDT]], %[[STEPIDX]] : index
+! CHECK: %[[CMP:.*]] = arith.cmpi slt, %[[TRIP]], %[[C0]] : index
+! CHECK: %[[SEL:.*]] = arith.select %[[CMP]], %[[C0]], %[[TRIP]] : index
+! CHECK: %[[MUL:.*]] = arith.muli %[[SEL]], %[[STEPIDX]] : index
+! CHECK: %[[IDX:.*]] = arith.addi %[[LBIDX]], %[[MUL]] : index
+! CHECK: %[[LAST:.*]] = fir.convert %[[IDX]] : (index) -> i32
+! CHECK: fir.store %[[LAST]] to %[[DECL_PRIV_I]]#0
! CHECK: omp.terminator
! CHECK: }
! CHECK: omp.terminator
diff --git a/flang/test/Lower/OpenMP/unstructured.f90 b/flang/test/Lower/OpenMP/unstructured.f90
index b60c1f5b7ef82..5d680576d26c6 100644
--- a/flang/test/Lower/OpenMP/unstructured.f90
+++ b/flang/test/Lower/OpenMP/unstructured.f90
@@ -101,7 +101,6 @@ subroutine ss2(n) ! unstructured OpenMP construct; loop exit inside construct
! CHECK: omp.yield
! CHECK: }
! CHECK: }
-! CHECK: fir.result
! CHECK: }
! CHECK: omp.terminator
! CHECK: }
@@ -217,7 +216,6 @@ subroutine ss5() ! EXIT inside OpenMP wsloop (inside parallel)
! CHECK: omp.yield
! CHECK: }
! CHECK: }
-! CHECK: fir.result
! CHECK: }
! CHECK: omp.terminator
! CHECK: }
@@ -263,7 +261,6 @@ subroutine ss6() ! EXIT inside OpenMP wsloop in a do loop (inside parallel)
! CHECK: }
! CHECK: omp.terminator
! CHECK: }
-! CHECK: fir.result
! CHECK: }
! CHECK: return
subroutine ss7() ! EXIT inside OpenMP parallel do (inside do loop)
diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-allocatable-array-minmax.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-allocatable-array-minmax.f90
index 07b472ed2ee5c..6a158f38419b4 100644
--- a/flang/test/Lower/OpenMP/wsloop-reduction-allocatable-array-minmax.f90
+++ b/flang/test/Lower/OpenMP/wsloop-reduction-allocatable-array-minmax.f90
@@ -196,26 +196,31 @@ program reduce15
! CHECK: hlfir.assign %[[VAL_34]] to %[[VAL_5]]#0 realloc : i32, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
! CHECK: %[[VAL_35:.*]] = arith.constant 5 : i32
! CHECK: hlfir.assign %[[VAL_35]] to %[[VAL_7]]#0 realloc : i32, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
-! CHECK: %[[VAL_36:.*]] = arith.constant 1 : i32
-! CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_36]] : (i32) -> index
-! CHECK: %[[VAL_38:.*]] = arith.constant 10 : i32
-! CHECK: %[[VAL_39:.*]] = fir.convert %[[VAL_38]] : (i32) -> index
-! CHECK: %[[VAL_40:.*]] = arith.constant 1 : index
-! CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_37]] : (index) -> i32
-! CHECK: %[[VAL_42:.*]] = fir.do_loop %[[VAL_43:.*]] = %[[VAL_37]] to %[[VAL_39]] step %[[VAL_40]] iter_args(%[[VAL_44:.*]] = %[[VAL_41]]) -> (i32) {
-! CHECK: fir.store %[[VAL_44]] to %[[VAL_3]]#0 : !fir.ref<i32>
+! CHECK: %[[VAL_37:.*]] = arith.constant 1 : i32
+! CHECK: %[[VAL_39:.*]] = arith.constant 10 : i32
+! CHECK: %[[VAL_40:.*]] = arith.constant 1 : i32
+! CHECK: fir.do_loop %[[VAL_43:.*]] = %[[VAL_37]] to %[[VAL_39]] step %[[VAL_40]] : i32 {
+! CHECK: fir.store %[[VAL_43]] to %[[VAL_3]]#0 : !fir.ref<i32>
! CHECK: %[[VAL_45:.*]] = fir.load %[[VAL_3]]#0 : !fir.ref<i32>
! CHECK: %[[VAL_46:.*]] = fir.load %[[VAL_1]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
! CHECK: %[[VAL_47:.*]] = fir.load %[[VAL_3]]#0 : !fir.ref<i32>
! CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_47]] : (i32) -> i64
! CHECK: %[[VAL_49:.*]] = hlfir.designate %[[VAL_46]] (%[[VAL_48]]) : (!fir.box<!fir.heap<!fir.array<?xi32>>>, i64) -> !fir.ref<i32>
! CHECK: hlfir.assign %[[VAL_45]] to %[[VAL_49]] : i32, !fir.ref<i32>
-! CHECK: %[[VAL_51:.*]] = fir.convert %[[VAL_40]] : (index) -> i32
-! CHECK: %[[VAL_52:.*]] = fir.load %[[VAL_3]]#0 : !fir.ref<i32>
-! CHECK: %[[VAL_53:.*]] = arith.addi %[[VAL_52]], %[[VAL_51]] overflow<nsw> : i32
-! CHECK: fir.result %[[VAL_53]] : i32
! CHECK: }
-! CHECK: fir.store %[[VAL_54:.*]] to %[[VAL_3]]#0 : !fir.ref<i32>
+! CHECK: %[[VAL_37_IDX:.*]] = fir.convert %[[VAL_37]] : (i32) -> index
+! CHECK: %[[VAL_39_IDX:.*]] = fir.convert %[[VAL_39]] : (i32) -> index
+! CHECK: %[[VAL_40_IDX:.*]] = fir.convert %[[VAL_40]] : (i32) -> index
+! CHECK: %[[VAL_C0:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_DIFF:.*]] = arith.subi %[[VAL_39_IDX]], %[[VAL_37_IDX]] : index
+! CHECK: %[[VAL_ADD:.*]] = arith.addi %[[VAL_DIFF]], %[[VAL_40_IDX]] : index
+! CHECK: %[[VAL_TRIP:.*]] = arith.divsi %[[VAL_ADD]], %[[VAL_40_IDX]] : index
+! CHECK: %[[VAL_CMP:.*]] = arith.cmpi slt, %[[VAL_TRIP]], %[[VAL_C0]] : index
+! CHECK: %[[VAL_SEL:.*]] = arith.select %[[VAL_CMP]], %[[VAL_C0]], %[[VAL_TRIP]] : index
+! CHECK: %[[VAL_MUL:.*]] = arith.muli %[[VAL_SEL]], %[[VAL_40_IDX]] : index
+! CHECK: %[[VAL_IDX:.*]] = arith.addi %[[VAL_37_IDX]], %[[VAL_MUL]] : index
+! CHECK: %[[VAL_54:.*]] = fir.convert %[[VAL_IDX]] : (index) -> i32
+! CHECK: fir.store %[[VAL_54]] to %[[VAL_3]]#0 : !fir.ref<i32>
! CHECK: omp.parallel {
! CHECK: %[[VAL_57:.*]] = arith.constant 1 : i32
! CHECK: %[[VAL_58:.*]] = arith.constant 10 : i32
diff --git a/flang/test/Lower/OpenMP/wsloop-variable.f90 b/flang/test/Lower/OpenMP/wsloop-variable.f90
index 60d970f3f0bac..a3f8baadfb101 100644
--- a/flang/test/Lower/OpenMP/wsloop-variable.f90
+++ b/flang/test/Lower/OpenMP/wsloop-variable.f90
@@ -133,26 +133,33 @@ subroutine wsloop_variable_sub
!CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_27]] : (i32) -> i16
!CHECK: hlfir.assign %[[VAL_28]] to %[[VAL_3]]#0 : i16, !fir.ref<i16>
!CHECK: %[[VAL_29:.*]] = fir.load %[[VAL_7]]#0 : !fir.ref<i128>
-!CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (i128) -> index
+!CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (i128) -> i64
!CHECK: %[[VAL_31:.*]] = arith.constant 100 : i32
-!CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_31]] : (i32) -> index
+!CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_31]] : (i32) -> i64
!CHECK: %[[VAL_33:.*]] = fir.load %[[VAL_15]]#0 : !fir.ref<i32>
-!CHECK: %[[VAL_34:.*]] = fir.convert %[[VAL_33]] : (i32) -> index
-!CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_30]] : (index) -> i64
-!CHECK: %[[VAL_36:.*]] = fir.do_loop %[[VAL_37:.*]] = %[[VAL_30]] to %[[VAL_32]] step %[[VAL_34]] iter_args(%[[VAL_38:.*]] = %[[VAL_35]]) -> (i64) {
-!CHECK: fir.store %[[VAL_38]] to %[[VAL_17]]#0 : !fir.ref<i64>
+!CHECK: %[[VAL_34:.*]] = fir.convert %[[VAL_33]] : (i32) -> i64
+!CHECK: fir.do_loop %[[VAL_37:.*]] = %[[VAL_30]] to %[[VAL_32]] step %[[VAL_34]] : i64 {
+!CHECK: fir.store %[[VAL_37]] to %[[VAL_17]]#0 : !fir.ref<i64>
!CHECK: %[[VAL_39:.*]] = fir.load %[[VAL_3]]#0 : !fir.ref<i16>
!CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_39]] : (i16) -> i64
!CHECK: %[[VAL_41:.*]] = fir.load %[[VAL_17]]#0 : !fir.ref<i64>
!CHECK: %[[VAL_42:.*]] = arith.addi %[[VAL_40]], %[[VAL_41]] : i64
!CHECK: %[[VAL_43:.*]] = fir.convert %[[VAL_42]] : (i64) -> f32
!CHECK: hlfir.assign %[[VAL_43]] to %[[VAL_21]]#0 : f32, !fir.ref<f32>
-!CHECK: %[[VAL_45:.*]] = fir.convert %[[VAL_34]] : (index) -> i64
-!CHECK: %[[VAL_46:.*]] = fir.load %[[VAL_17]]#0 : !fir.ref<i64>
-!CHECK: %[[VAL_47:.*]] = arith.addi %[[VAL_46]], %[[VAL_45]] overflow<nsw> : i64
-!CHECK: fir.result %[[VAL_47]] : i64
!CHECK: }
-!CHECK: fir.store %[[VAL_48:.*]] to %[[VAL_17]]#0 : !fir.ref<i64>
+!CHECK: %[[VAL_30_IDX:.*]] = fir.convert %[[VAL_30]] : (i64) -> index
+!CHECK: %[[VAL_32_IDX:.*]] = fir.convert %[[VAL_32]] : (i64) -> index
+!CHECK: %[[VAL_34_IDX:.*]] = fir.convert %[[VAL_34]] : (i64) -> index
+!CHECK: %[[VAL_C0:.*]] = arith.constant 0 : index
+!CHECK: %[[VAL_DIFF:.*]] = arith.subi %[[VAL_32_IDX]], %[[VAL_30_IDX]] : index
+!CHECK: %[[VAL_ADD:.*]] = arith.addi %[[VAL_DIFF]], %[[VAL_34_IDX]] : index
+!CHECK: %[[VAL_TRIP:.*]] = arith.divsi %[[VAL_ADD]], %[[VAL_34_IDX]] : index
+!CHECK: %[[VAL_CMP:.*]] = arith.cmpi slt, %[[VAL_TRIP]], %[[VAL_C0]] : index
+!CHECK: %[[VAL_SEL:.*]] = arith.select %[[VAL_CMP]], %[[VAL_C0]], %[[VAL_TRIP]] : index
+!CHECK: %[[VAL_MUL:.*]] = arith.muli %[[VAL_SEL]], %[[VAL_34_IDX]] : index
+!CHECK: %[[VAL_LAST:.*]] = arith.addi %[[VAL_30_IDX]], %[[VAL_MUL]] : index
+!CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_LAST]] : (index) -> i64
+!CHECK: fir.store %[[VAL_48]] to %[[VAL_17]]#0 : !fir.ref<i64>
!CHECK: omp.yield
!CHECK: }
!CHECK: }
diff --git a/flang/test/Lower/allocatable-polymorphic.f90 b/flang/test/Lower/allocatable-polymorphic.f90
index 9e4f04b45516e..8a0cb1bbc7033 100644
--- a/flang/test/Lower/allocatable-polymorphic.f90
+++ b/flang/test/Lower/allocatable-polymorphic.f90
@@ -332,12 +332,12 @@ subroutine test_allocatable()
! CHECK: %[[C2_REBOX:.*]] = fir.rebox %[[C2_LOAD2]] : (!fir.class<!fir.heap<!fir.type<_QMpolyTp1{a:i32,b:i32}>>>) -> !fir.class<!fir.type<_QMpolyTp1{a:i32,b:i32}>>
! CHECK: fir.dispatch "proc2"(%[[C2_REBOX]] : !fir.class<!fir.type<_QMpolyTp1{a:i32,b:i32}>>) (%[[C2_REBOX]] : !fir.class<!fir.type<_QMpolyTp1{a:i32,b:i32}>>) {pass_arg_pos = 0 : i32}
-! CHECK-LABEL: %{{.*}} = fir.do_loop
+! CHECK-LABEL: fir.do_loop
! CHECK: %[[C3_LOAD:.*]] = fir.load %[[C3_DECL]]#0 : !fir.ref<!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMpolyTp1{a:i32,b:i32}>>>>>
! CHECK: %[[DESIGNATE_C3:.*]] = hlfir.designate %[[C3_LOAD]] (%{{.*}}) : (!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMpolyTp1{a:i32,b:i32}>>>>, i64) -> !fir.class<!fir.type<_QMpolyTp1{a:i32,b:i32}>>
! CHECK: fir.dispatch "proc2"(%[[DESIGNATE_C3]] : !fir.class<!fir.type<_QMpolyTp1{a:i32,b:i32}>>) (%[[DESIGNATE_C3]] : !fir.class<!fir.type<_QMpolyTp1{a:i32,b:i32}>>) {pass_arg_pos = 0 : i32}
-! CHECK-LABEL: %{{.*}} = fir.do_loop
+! CHECK-LABEL: fir.do_loop
! CHECK: %[[C4_LOAD:.*]] = fir.load %[[C4_DECL]]#0 : !fir.ref<!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMpolyTp1{a:i32,b:i32}>>>>>
! CHECK: %[[DESIGNATE_C4:.*]] = hlfir.designate %[[C4_LOAD]] (%{{.*}}) : (!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMpolyTp1{a:i32,b:i32}>>>>, i64) -> !fir.class<!fir.type<_QMpolyTp1{a:i32,b:i32}>>
! CHECK: fir.dispatch "proc2"(%[[DESIGNATE_C4]] : !fir.class<!fir.type<_QMpolyTp1{a:i32,b:i32}>>) (%[[DESIGNATE_C4]] : !fir.class<!fir.type<_QMpolyTp1{a:i32,b:i32}>>) {pass_arg_pos = 0 : i32}
diff --git a/flang/test/Lower/dispatch.f90 b/flang/test/Lower/dispatch.f90
index a66287d2b4fd6..0dee190398ccc 100644
--- a/flang/test/Lower/dispatch.f90
+++ b/flang/test/Lower/dispatch.f90
@@ -250,11 +250,11 @@ subroutine check_dispatch_dynamic_array(p, t)
! CHECK-SAME: %[[ARG1:.*]]: !fir.box<!fir.array<?x!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>> {fir.bindc_name = "t"}) {
! CHECK: %[[ARG0_DECL:.*]]:2 = hlfir.declare %[[ARG0]] dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {uniq_name = "_QMcall_dispatchFcheck_dispatch_dynamic_arrayEp"} : (!fir.class<!fir.array<?x!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>, !fir.dscope) -> (!fir.class<!fir.array<?x!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>, !fir.class<!fir.array<?x!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>)
! CHECK: %[[ARG1_DECL:.*]]:2 = hlfir.declare %[[ARG1]] dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {uniq_name = "_QMcall_dispatchFcheck_dispatch_dynamic_arrayEt"} : (!fir.box<!fir.array<?x!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>, !fir.dscope) -> (!fir.box<!fir.array<?x!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>, !fir.box<!fir.array<?x!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>)
-! CHECK: %{{.*}} = fir.do_loop {{.*}} {
+! CHECK: fir.do_loop {{.*}} {
! CHECK: %[[DESIGNATE:.*]] = hlfir.designate %[[ARG0_DECL]]#0 (%{{.*}}) : (!fir.class<!fir.array<?x!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>, i64) -> !fir.class<!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>
! CHECK: fir.dispatch "tbp_pass"(%[[DESIGNATE]] : !fir.class<!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>) (%[[DESIGNATE]] : !fir.class<!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>) {pass_arg_pos = 0 : i32}
-! CHECK: %{{.*}} = fir.do_loop {{.*}} {
+! CHECK: fir.do_loop {{.*}} {
! CHECK: %[[DESIGNATE:.*]] = hlfir.designate %[[ARG1_DECL]]#0 (%{{.*}}) : (!fir.box<!fir.array<?x!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>, i64) -> !fir.ref<!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>
! CHECK: %[[EMBOX:.*]] = fir.embox %[[DESIGNATE]] : (!fir.ref<!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>) -> !fir.box<!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>
! CHECK: %[[CONV:.*]] = fir.convert %[[EMBOX]] : (!fir.box<!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>) -> !fir.class<!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>
@@ -278,12 +278,12 @@ subroutine check_dispatch_allocatable_array(p, t)
! CHECK-SAME: %[[ARG1:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>>> {fir.bindc_name = "t"}) {
! CHECK: %[[ARG0_DECL:.*]]:2 = hlfir.declare %[[ARG0]] dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QMcall_dispatchFcheck_dispatch_allocatable_arrayEp"} : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>>>, !fir.dscope) -> (!fir.ref<!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>>>, !fir.ref<!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>>>)
! CHECK: %[[ARG1_DECL:.*]]:2 = hlfir.declare %[[ARG1]] dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QMcall_dispatchFcheck_dispatch_allocatable_arrayEt"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>>>)
-! CHECK: %{{.*}} = fir.do_loop {{.*}} {
+! CHECK: fir.do_loop {{.*}} {
! CHECK: %[[LOAD_ARG0:.*]] = fir.load %[[ARG0_DECL]]#0 : !fir.ref<!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>>>
! CHECK: %[[DESIGNATE:.*]] = hlfir.designate %[[LOAD_ARG0]] (%{{.*}}) : (!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>>, i64) -> !fir.class<!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>
! CHECK: fir.dispatch "tbp_pass"(%[[DESIGNATE]] : !fir.class<!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>) (%[[DESIGNATE]] : !fir.class<!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>) {pass_arg_pos = 0 : i32}
-! CHECK: %{{.*}} = fir.do_loop {{.*}} {
+! CHECK: fir.do_loop {{.*}} {
! CHECK: %[[LOAD_ARG1:.*]] = fir.load %[[ARG1_DECL]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>>>
! CHECK: %[[DESIGNATE:.*]] = hlfir.designate %[[LOAD_ARG1]] (%{{.*}}) : (!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>>, i64) -> !fir.ref<!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>
! CHECK: %[[EMBOX:.*]] = fir.embox %[[DESIGNATE]] : (!fir.ref<!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>) -> !fir.box<!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>
@@ -309,12 +309,12 @@ subroutine check_dispatch_pointer_array(p, t)
! CHECK: %[[ARG0_DECL:.*]]:2 = hlfir.declare %[[ARG0]] dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMcall_dispatchFcheck_dispatch_pointer_arrayEp"} : (!fir.ref<!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>>>, !fir.dscope) -> (!fir.ref<!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>>>, !fir.ref<!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>>>)
! CHECK: %[[ARG1_DECL:.*]]:2 = hlfir.declare %[[ARG1]] dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMcall_dispatchFcheck_dispatch_pointer_arrayEt"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>>>)
-! CHECK: %{{.*}} = fir.do_loop {{.*}} {
+! CHECK: fir.do_loop {{.*}} {
! CHECK: %[[LOAD_ARG0:.*]] = fir.load %[[ARG0_DECL]]#0 : !fir.ref<!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>>>
! CHECK: %[[DESIGNATE:.*]] = hlfir.designate %[[LOAD_ARG0]] (%{{.*}}) : (!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>>, i64) -> !fir.class<!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>
! CHECK: fir.dispatch "tbp_pass"(%[[DESIGNATE]] : !fir.class<!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>) (%[[DESIGNATE]] : !fir.class<!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>) {pass_arg_pos = 0 : i32}
-! CHECK: %{{.*}} = fir.do_loop {{.*}} {
+! CHECK: fir.do_loop {{.*}} {
! CHECK: %[[LOAD_ARG1:.*]] = fir.load %[[ARG1_DECL]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>>>
! CHECK: %[[DESIGNATE:.*]] = hlfir.designate %[[LOAD_ARG1]] (%{{.*}}) : (!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>>, i64) -> !fir.ref<!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>
! CHECK: %[[EMBOX:.*]] = fir.embox %[[DESIGNATE]] : (!fir.ref<!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>) -> !fir.box<!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>
@@ -337,7 +337,7 @@ subroutine check_dispatch_dynamic_array_copy(p, o)
! CHECK: %[[ARG1_DECL:.*]]:2 = hlfir.declare %[[ARG1]] dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {uniq_name = "_QMcall_dispatchFcheck_dispatch_dynamic_array_copyEo"} : (!fir.class<!fir.array<?x!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>, !fir.dscope) -> (!fir.class<!fir.array<?x!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>, !fir.class<!fir.array<?x!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>)
! CHECK: %[[ARG0_DECL:.*]]:2 = hlfir.declare %[[ARG0]] dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {uniq_name = "_QMcall_dispatchFcheck_dispatch_dynamic_array_copyEp"} : (!fir.class<!fir.array<?x!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>, !fir.dscope) -> (!fir.class<!fir.array<?x!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>, !fir.class<!fir.array<?x!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>)
-! CHECK: %{{.*}} = fir.do_loop {{.*}} {
+! CHECK: fir.do_loop {{.*}} {
! CHECK: %[[DESIGNATE0:.*]] = hlfir.designate %[[ARG0_DECL]]#0 (%{{.*}}) : (!fir.class<!fir.array<?x!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>, i64) -> !fir.class<!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>
! CHECK: %[[DESIGNATE1:.*]] = hlfir.designate %[[ARG1_DECL]]#0 (%{{.*}}) : (!fir.class<!fir.array<?x!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>>, i64) -> !fir.class<!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>
! CHECK: fir.dispatch "pass_with_class_arg"(%[[DESIGNATE0]] : !fir.class<!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>) (%[[DESIGNATE0]], %[[DESIGNATE1]] : !fir.class<!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>, !fir.class<!fir.type<_QMcall_dispatchTp1{a:i32,b:i32}>>) {pass_arg_pos = 0 : i32}
diff --git a/flang/test/Lower/do_concurrent_loop_in_nested_block.f90 b/flang/test/Lower/do_concurrent_loop_in_nested_block.f90
index 79bde5eed7817..9026423e94ac1 100644
--- a/flang/test/Lower/do_concurrent_loop_in_nested_block.f90
+++ b/flang/test/Lower/do_concurrent_loop_in_nested_block.f90
@@ -17,8 +17,8 @@ subroutine loop_in_nested_block
! CHECK: fir.do_concurrent {
! CHECK: fir.do_concurrent.loop {{.*}} local(@{{.*}} %[[OUTER_J_DECL]]#0 -> %[[LOCAL_J_ARG:.*]] : !fir.ref<i32>) {
! CHECK: %[[LOCAL_J_DECL:.*]]:2 = hlfir.declare %[[LOCAL_J_ARG]]
-! CHECK: fir.do_loop {{.*}} iter_args(%[[NESTED_LOOP_ARG:.*]] = {{.*}}) {
-! CHECK: fir.store %[[NESTED_LOOP_ARG]] to %[[LOCAL_J_DECL]]#0
+! CHECK: fir.do_loop %[[NESTED_IV:.*]] = {{.*}} to {{.*}} step {{.*}} : i32 {
+! CHECK: fir.store %[[NESTED_IV]] to %[[LOCAL_J_DECL]]#0
! CHECK: }
! CHECK: }
! CHECK: }
diff --git a/flang/test/Lower/do_loop.f90 b/flang/test/Lower/do_loop.f90
index b98a0e7108113..e4992373bcb70 100644
--- a/flang/test/Lower/do_loop.f90
+++ b/flang/test/Lower/do_loop.f90
@@ -2,8 +2,9 @@
! RUN: %flang_fc1 -emit-hlfir -fwrapv -o - %s | FileCheck %s --check-prefix=NO-NSW
! Simple tests for structured ordered loops with loop-control.
-! Tests the structure of the loop, storage to index variable and return and
-! storage of the final value of the index variable.
+! The DO variable is recomputed from the induction variable inside the loop
+! body (no secondary-induction iter_arg), and its Fortran post-loop value is
+! materialized after the loop.
! NO-NSW-NOT: overflow<nsw>
@@ -15,23 +16,26 @@ subroutine simple_loop
integer :: i
! CHECK: %[[C1:.*]] = arith.constant 1 : i32
- ! CHECK: %[[C1_CVT:.*]] = fir.convert %[[C1]] : (i32) -> index
! CHECK: %[[C5:.*]] = arith.constant 5 : i32
- ! CHECK: %[[C5_CVT:.*]] = fir.convert %[[C5]] : (i32) -> index
- ! CHECK: %[[C1_STEP:.*]] = arith.constant 1 : index
- ! CHECK: %[[LB:.*]] = fir.convert %[[C1_CVT]] : (index) -> i32
- ! CHECK: %[[LI_RES:.*]] = fir.do_loop %[[LI:[^ ]*]] =
- ! CHECK-SAME: %[[C1_CVT]] to %[[C5_CVT]] step %[[C1_STEP]]
- ! CHECK-SAME: iter_args(%[[IV:.*]] = %[[LB]]) -> (i32) {
+ ! CHECK: %[[C1_STEP:.*]] = arith.constant 1 : i32
+ ! CHECK: fir.do_loop %[[LI:[^ ]*]] = %[[C1]] to %[[C5]] step %[[C1_STEP]] : i32 {
do i=1,5
- ! CHECK: fir.store %[[IV]] to %[[I_DECL]]#0 : !fir.ref<i32>
- ! CHECK: %[[STEPCAST:.*]] = fir.convert %[[C1_STEP]] : (index) -> i32
- ! CHECK: %[[IVLOAD:.*]] = fir.load %[[I_DECL]]#0 : !fir.ref<i32>
- ! CHECK: %[[IVINC:.*]] = arith.addi %[[IVLOAD]], %[[STEPCAST]] overflow<nsw> : i32
- ! CHECK: fir.result %[[IVINC]] : i32
+ ! CHECK: fir.store %[[LI]] to %[[I_DECL]]#0 : !fir.ref<i32>
! CHECK: }
end do
- ! CHECK: fir.store %[[LI_RES]] to %[[I_DECL]]#0 : !fir.ref<i32>
+ ! CHECK: %[[C1_CVT:.*]] = fir.convert %[[C1]] : (i32) -> index
+ ! CHECK: %[[C5_CVT:.*]] = fir.convert %[[C5]] : (i32) -> index
+ ! CHECK: %[[C1_STEP_CVT:.*]] = fir.convert %[[C1_STEP]] : (i32) -> index
+ ! CHECK: %[[C0:.*]] = arith.constant 0 : index
+ ! CHECK: %[[DIFF:.*]] = arith.subi %[[C5_CVT]], %[[C1_CVT]] : index
+ ! CHECK: %[[ADD:.*]] = arith.addi %[[DIFF]], %[[C1_STEP_CVT]] : index
+ ! CHECK: %[[TRIP:.*]] = arith.divsi %[[ADD]], %[[C1_STEP_CVT]] : index
+ ! CHECK: %[[CMP:.*]] = arith.cmpi slt, %[[TRIP]], %[[C0]] : index
+ ! CHECK: %[[SEL:.*]] = arith.select %[[CMP]], %[[C0]], %[[TRIP]] : index
+ ! CHECK: %[[MUL:.*]] = arith.muli %[[SEL]], %[[C1_STEP_CVT]] : index
+ ! CHECK: %[[LASTIDX:.*]] = arith.addi %[[C1_CVT]], %[[MUL]] : index
+ ! CHECK: %[[LAST:.*]] = fir.convert %[[LASTIDX]] : (index) -> i32
+ ! CHECK: fir.store %[[LAST]] to %[[I_DECL]]#0 : !fir.ref<i32>
! CHECK: %[[I:.*]] = fir.load %[[I_DECL]]#0 : !fir.ref<i32>
! CHECK: %{{.*}} = fir.call @_FortranAioOutputInteger32(%{{.*}}, %[[I]]) {{.*}}: (!fir.ref<i8>, i32) -> i1
print *, i
@@ -52,27 +56,17 @@ subroutine nested_loop
integer :: i, j
asum = 0
! CHECK: %[[S_I:.*]] = arith.constant 1 : i32
- ! CHECK: %[[S_I_CVT:.*]] = fir.convert %[[S_I]] : (i32) -> index
! CHECK: %[[E_I:.*]] = arith.constant 5 : i32
- ! CHECK: %[[E_I_CVT:.*]] = fir.convert %[[E_I]] : (i32) -> index
- ! CHECK: %[[ST_I:.*]] = arith.constant 1 : index
- ! CHECK: %[[I_LB:.*]] = fir.convert %[[S_I_CVT]] : (index) -> i32
- ! CHECK: %[[I_RES:.*]] = fir.do_loop %[[LI:[^ ]*]] =
- ! CHECK-SAME: %[[S_I_CVT]] to %[[E_I_CVT]] step %[[ST_I]]
- ! CHECK-SAME: iter_args(%[[I_IV:.*]] = %[[I_LB]]) -> (i32) {
+ ! CHECK: %[[ST_I:.*]] = arith.constant 1 : i32
+ ! CHECK: fir.do_loop %[[LI:[^ ]*]] = %[[S_I]] to %[[E_I]] step %[[ST_I]] : i32 {
do i=1,5
- ! CHECK: fir.store %[[I_IV]] to %[[I_DECL]]#0 : !fir.ref<i32>
+ ! CHECK: fir.store %[[LI]] to %[[I_DECL]]#0 : !fir.ref<i32>
! CHECK: %[[S_J:.*]] = arith.constant 1 : i32
- ! CHECK: %[[S_J_CVT:.*]] = fir.convert %[[S_J]] : (i32) -> index
! CHECK: %[[E_J:.*]] = arith.constant 5 : i32
- ! CHECK: %[[E_J_CVT:.*]] = fir.convert %[[E_J]] : (i32) -> index
- ! CHECK: %[[ST_J:.*]] = arith.constant 1 : index
- ! CHECK: %[[J_LB:.*]] = fir.convert %[[S_J_CVT]] : (index) -> i32
- ! CHECK: %[[J_RES:.*]] = fir.do_loop %[[LJ:[^ ]*]] =
- ! CHECK-SAME: %[[S_J_CVT]] to %[[E_J_CVT]] step %[[ST_J]]
- ! CHECK-SAME: iter_args(%[[J_IV:.*]] = %[[J_LB]]) -> (i32) {
+ ! CHECK: %[[ST_J:.*]] = arith.constant 1 : i32
+ ! CHECK: fir.do_loop %[[LJ:[^ ]*]] = %[[S_J]] to %[[E_J]] step %[[ST_J]] : i32 {
do j=1,5
- ! CHECK: fir.store %[[J_IV]] to %[[J_DECL]]#0 : !fir.ref<i32>
+ ! CHECK: fir.store %[[LJ]] to %[[J_DECL]]#0 : !fir.ref<i32>
! CHECK: %[[ASUM:.*]] = fir.load %[[ASUM_DECL]]#0 : !fir.ref<i32>
! CHECK: %[[I:.*]] = fir.load %[[I_DECL]]#0 : !fir.ref<i32>
! CHECK: %[[I_CVT:.*]] = fir.convert %[[I]] : (i32) -> i64
@@ -83,20 +77,36 @@ subroutine nested_loop
! CHECK: %[[ASUM_NEW:.*]] = arith.addi %[[ASUM]], %[[ARR_VAL]] : i32
! CHECK: hlfir.assign %[[ASUM_NEW]] to %[[ASUM_DECL]]#0 : i32, !fir.ref<i32>
asum = asum + arr(i,j)
- ! CHECK: %[[J_STEPCAST:.*]] = fir.convert %[[ST_J]] : (index) -> i32
- ! CHECK: %[[J_IVLOAD:.*]] = fir.load %[[J_DECL]]#0 : !fir.ref<i32>
- ! CHECK: %[[J_IVINC:.*]] = arith.addi %[[J_IVLOAD]], %[[J_STEPCAST]] overflow<nsw> : i32
- ! CHECK: fir.result %[[J_IVINC]] : i32
! CHECK: }
end do
- ! CHECK: fir.store %[[J_RES]] to %[[J_DECL]]#0 : !fir.ref<i32>
- ! CHECK: %[[I_STEPCAST:.*]] = fir.convert %[[ST_I]] : (index) -> i32
- ! CHECK: %[[I_IVLOAD:.*]] = fir.load %[[I_DECL]]#0 : !fir.ref<i32>
- ! CHECK: %[[I_IVINC:.*]] = arith.addi %[[I_IVLOAD]], %[[I_STEPCAST]] overflow<nsw> : i32
- ! CHECK: fir.result %[[I_IVINC]] : i32
+ ! CHECK: %[[S_J_CVT:.*]] = fir.convert %[[S_J]] : (i32) -> index
+ ! CHECK: %[[E_J_CVT:.*]] = fir.convert %[[E_J]] : (i32) -> index
+ ! CHECK: %[[ST_J_CVT:.*]] = fir.convert %[[ST_J]] : (i32) -> index
+ ! CHECK: %[[J_C0:.*]] = arith.constant 0 : index
+ ! CHECK: %[[J_DIFF:.*]] = arith.subi %[[E_J_CVT]], %[[S_J_CVT]] : index
+ ! CHECK: %[[J_ADD:.*]] = arith.addi %[[J_DIFF]], %[[ST_J_CVT]] : index
+ ! CHECK: %[[J_TRIP:.*]] = arith.divsi %[[J_ADD]], %[[ST_J_CVT]] : index
+ ! CHECK: %[[J_CMP:.*]] = arith.cmpi slt, %[[J_TRIP]], %[[J_C0]] : index
+ ! CHECK: %[[J_SEL:.*]] = arith.select %[[J_CMP]], %[[J_C0]], %[[J_TRIP]] : index
+ ! CHECK: %[[J_MUL:.*]] = arith.muli %[[J_SEL]], %[[ST_J_CVT]] : index
+ ! CHECK: %[[J_LASTIDX:.*]] = arith.addi %[[S_J_CVT]], %[[J_MUL]] : index
+ ! CHECK: %[[J_LAST:.*]] = fir.convert %[[J_LASTIDX]] : (index) -> i32
+ ! CHECK: fir.store %[[J_LAST]] to %[[J_DECL]]#0 : !fir.ref<i32>
! CHECK: }
end do
- ! CHECK: fir.store %[[I_RES]] to %[[I_DECL]]#0 : !fir.ref<i32>
+ ! CHECK: %[[S_I_CVT:.*]] = fir.convert %[[S_I]] : (i32) -> index
+ ! CHECK: %[[E_I_CVT:.*]] = fir.convert %[[E_I]] : (i32) -> index
+ ! CHECK: %[[ST_I_CVT:.*]] = fir.convert %[[ST_I]] : (i32) -> index
+ ! CHECK: %[[I_C0:.*]] = arith.constant 0 : index
+ ! CHECK: %[[I_DIFF:.*]] = arith.subi %[[E_I_CVT]], %[[S_I_CVT]] : index
+ ! CHECK: %[[I_ADD:.*]] = arith.addi %[[I_DIFF]], %[[ST_I_CVT]] : index
+ ! CHECK: %[[I_TRIP:.*]] = arith.divsi %[[I_ADD]], %[[ST_I_CVT]] : index
+ ! CHECK: %[[I_CMP:.*]] = arith.cmpi slt, %[[I_TRIP]], %[[I_C0]] : index
+ ! CHECK: %[[I_SEL:.*]] = arith.select %[[I_CMP]], %[[I_C0]], %[[I_TRIP]] : index
+ ! CHECK: %[[I_MUL:.*]] = arith.muli %[[I_SEL]], %[[ST_I_CVT]] : index
+ ! CHECK: %[[I_LASTIDX:.*]] = arith.addi %[[S_I_CVT]], %[[I_MUL]] : index
+ ! CHECK: %[[I_LAST:.*]] = fir.convert %[[I_LASTIDX]] : (index) -> i32
+ ! CHECK: fir.store %[[I_LAST]] to %[[I_DECL]]#0 : !fir.ref<i32>
end subroutine
! Test a downcounting loop
@@ -107,24 +117,26 @@ subroutine down_counting_loop()
! CHECK: %[[I_DECL:.*]]:2 = hlfir.declare %[[I_REF]]
! CHECK: %[[C5:.*]] = arith.constant 5 : i32
- ! CHECK: %[[C5_CVT:.*]] = fir.convert %[[C5]] : (i32) -> index
! CHECK: %[[C1:.*]] = arith.constant 1 : i32
- ! CHECK: %[[C1_CVT:.*]] = fir.convert %[[C1]] : (i32) -> index
! CHECK: %[[CMINUS1:.*]] = arith.constant -1 : i32
- ! CHECK: %[[CMINUS1_STEP_CVT:.*]] = fir.convert %[[CMINUS1]] : (i32) -> index
- ! CHECK: %[[I_LB:.*]] = fir.convert %[[C5_CVT]] : (index) -> i32
- ! CHECK: %[[I_RES:.*]] = fir.do_loop %[[LI:[^ ]*]] =
- ! CHECK-SAME: %[[C5_CVT]] to %[[C1_CVT]] step %[[CMINUS1_STEP_CVT]]
- ! CHECK-SAME: iter_args(%[[I_IV:.*]] = %[[I_LB]]) -> (i32) {
+ ! CHECK: fir.do_loop %[[LI:[^ ]*]] = %[[C5]] to %[[C1]] step %[[CMINUS1]] : i32 {
do i=5,1,-1
- ! CHECK: fir.store %[[I_IV]] to %[[I_DECL]]#0 : !fir.ref<i32>
- ! CHECK: %[[I_STEPCAST:.*]] = fir.convert %[[CMINUS1_STEP_CVT]] : (index) -> i32
- ! CHECK: %[[I_IVLOAD:.*]] = fir.load %[[I_DECL]]#0 : !fir.ref<i32>
- ! CHECK: %[[I_IVINC:.*]] = arith.addi %[[I_IVLOAD]], %[[I_STEPCAST]] overflow<nsw> : i32
- ! CHECK: fir.result %[[I_IVINC]] : i32
+ ! CHECK: fir.store %[[LI]] to %[[I_DECL]]#0 : !fir.ref<i32>
! CHECK: }
end do
- ! CHECK: fir.store %[[I_RES]] to %[[I_DECL]]#0 : !fir.ref<i32>
+ ! CHECK: %[[C5_CVT:.*]] = fir.convert %[[C5]] : (i32) -> index
+ ! CHECK: %[[C1_CVT:.*]] = fir.convert %[[C1]] : (i32) -> index
+ ! CHECK: %[[CMINUS1_STEP_CVT:.*]] = fir.convert %[[CMINUS1]] : (i32) -> index
+ ! CHECK: %[[C0:.*]] = arith.constant 0 : index
+ ! CHECK: %[[DIFF:.*]] = arith.subi %[[C1_CVT]], %[[C5_CVT]] : index
+ ! CHECK: %[[ADD:.*]] = arith.addi %[[DIFF]], %[[CMINUS1_STEP_CVT]] : index
+ ! CHECK: %[[TRIP:.*]] = arith.divsi %[[ADD]], %[[CMINUS1_STEP_CVT]] : index
+ ! CHECK: %[[CMP:.*]] = arith.cmpi slt, %[[TRIP]], %[[C0]] : index
+ ! CHECK: %[[SEL:.*]] = arith.select %[[CMP]], %[[C0]], %[[TRIP]] : index
+ ! CHECK: %[[MUL:.*]] = arith.muli %[[SEL]], %[[CMINUS1_STEP_CVT]] : index
+ ! CHECK: %[[LASTIDX:.*]] = arith.addi %[[C5_CVT]], %[[MUL]] : index
+ ! CHECK: %[[LAST:.*]] = fir.convert %[[LASTIDX]] : (index) -> i32
+ ! CHECK: fir.store %[[LAST]] to %[[I_DECL]]#0 : !fir.ref<i32>
end subroutine
! Test a general loop with a variable step
@@ -138,24 +150,26 @@ subroutine loop_with_variable_step(s,e,st)
! CHECK-DAG: %[[I_REF:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFloop_with_variable_stepEi"}
! CHECK-DAG: %[[I_DECL:.*]]:2 = hlfir.declare %[[I_REF]]
! CHECK: %[[S:.*]] = fir.load %[[S_DECL]]#0 : !fir.ref<i32>
- ! CHECK: %[[S_CVT:.*]] = fir.convert %[[S]] : (i32) -> index
! CHECK: %[[E:.*]] = fir.load %[[E_DECL]]#0 : !fir.ref<i32>
- ! CHECK: %[[E_CVT:.*]] = fir.convert %[[E]] : (i32) -> index
! CHECK: %[[ST:.*]] = fir.load %[[ST_DECL]]#0 : !fir.ref<i32>
- ! CHECK: %[[ST_CVT:.*]] = fir.convert %[[ST]] : (i32) -> index
- ! CHECK: %[[I_LB:.*]] = fir.convert %[[S_CVT]] : (index) -> i32
- ! CHECK: %[[I_RES:.*]] = fir.do_loop %[[LI:[^ ]*]] =
- ! CHECK-SAME: %[[S_CVT]] to %[[E_CVT]] step %[[ST_CVT]]
- ! CHECK-SAME: iter_args(%[[I_IV:.*]] = %[[I_LB]]) -> (i32) {
+ ! CHECK: fir.do_loop %[[LI:[^ ]*]] = %[[S]] to %[[E]] step %[[ST]] : i32 {
do i=s,e,st
- ! CHECK: fir.store %[[I_IV]] to %[[I_DECL]]#0 : !fir.ref<i32>
- ! CHECK: %[[I_STEPCAST:.*]] = fir.convert %[[ST_CVT]] : (index) -> i32
- ! CHECK: %[[I_IVLOAD:.*]] = fir.load %[[I_DECL]]#0 : !fir.ref<i32>
- ! CHECK: %[[I_IVINC:.*]] = arith.addi %[[I_IVLOAD]], %[[I_STEPCAST]] overflow<nsw> : i32
- ! CHECK: fir.result %[[I_IVINC]] : i32
+ ! CHECK: fir.store %[[LI]] to %[[I_DECL]]#0 : !fir.ref<i32>
! CHECK: }
end do
- ! CHECK: fir.store %[[I_RES]] to %[[I_DECL]]#0 : !fir.ref<i32>
+ ! CHECK: %[[S_CVT:.*]] = fir.convert %[[S]] : (i32) -> index
+ ! CHECK: %[[E_CVT:.*]] = fir.convert %[[E]] : (i32) -> index
+ ! CHECK: %[[ST_CVT:.*]] = fir.convert %[[ST]] : (i32) -> index
+ ! CHECK: %[[C0:.*]] = arith.constant 0 : index
+ ! CHECK: %[[DIFF:.*]] = arith.subi %[[E_CVT]], %[[S_CVT]] : index
+ ! CHECK: %[[ADD:.*]] = arith.addi %[[DIFF]], %[[ST_CVT]] : index
+ ! CHECK: %[[TRIP:.*]] = arith.divsi %[[ADD]], %[[ST_CVT]] : index
+ ! CHECK: %[[CMP:.*]] = arith.cmpi slt, %[[TRIP]], %[[C0]] : index
+ ! CHECK: %[[SEL:.*]] = arith.select %[[CMP]], %[[C0]], %[[TRIP]] : index
+ ! CHECK: %[[MUL:.*]] = arith.muli %[[SEL]], %[[ST_CVT]] : index
+ ! CHECK: %[[LASTIDX:.*]] = arith.addi %[[S_CVT]], %[[MUL]] : index
+ ! CHECK: %[[LAST:.*]] = fir.convert %[[LASTIDX]] : (index) -> i32
+ ! CHECK: fir.store %[[LAST]] to %[[I_DECL]]#0 : !fir.ref<i32>
end subroutine
! Test usage of pointer variables as index, start, end and step variables
@@ -188,28 +202,30 @@ subroutine loop_with_pointer_variables(s,e,st)
! CHECK: %[[S_BOX:.*]] = fir.load %[[S_PTR_DECL]]#0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
! CHECK: %[[S_PTR:.*]] = fir.box_addr %[[S_BOX]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
! CHECK: %[[S:.*]] = fir.load %[[S_PTR]] : !fir.ptr<i32>
-! CHECK: %[[S_CVT:.*]] = fir.convert %[[S]] : (i32) -> index
! CHECK: %[[E_BOX:.*]] = fir.load %[[E_PTR_DECL]]#0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
! CHECK: %[[E_PTR:.*]] = fir.box_addr %[[E_BOX]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
! CHECK: %[[E:.*]] = fir.load %[[E_PTR]] : !fir.ptr<i32>
-! CHECK: %[[E_CVT:.*]] = fir.convert %[[E]] : (i32) -> index
! CHECK: %[[ST_BOX:.*]] = fir.load %[[ST_PTR_DECL]]#0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
! CHECK: %[[ST_PTR:.*]] = fir.box_addr %[[ST_BOX]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
! CHECK: %[[ST:.*]] = fir.load %[[ST_PTR]] : !fir.ptr<i32>
-! CHECK: %[[ST_CVT:.*]] = fir.convert %[[ST]] : (i32) -> index
-! CHECK: %[[I_LB:.*]] = fir.convert %[[S_CVT]] : (index) -> i32
-! CHECK: %[[I_RES:.*]] = fir.do_loop %[[LI:[^ ]*]] =
-! CHECK-SAME: %[[S_CVT]] to %[[E_CVT]] step %[[ST_CVT]]
-! CHECK-SAME: iter_args(%[[I_IV:.*]] = %[[I_LB]]) -> (i32) {
+! CHECK: fir.do_loop %[[LI:[^ ]*]] = %[[S]] to %[[E]] step %[[ST]] : i32 {
do iptr=sptr,eptr,stptr
-! CHECK: fir.store %[[I_IV]] to %[[I_PTR]] : !fir.ptr<i32>
-! CHECK: %[[I_STEPCAST:.*]] = fir.convert %[[ST_CVT]] : (index) -> i32
-! CHECK: %[[I_IVLOAD:.*]] = fir.load %[[I_PTR]] : !fir.ptr<i32>
-! CHECK: %[[I_IVINC:.*]] = arith.addi %[[I_IVLOAD]], %[[I_STEPCAST]] overflow<nsw> : i32
-! CHECK: fir.result %[[I_IVINC]] : i32
- end do
+! CHECK: fir.store %[[LI]] to %[[I_PTR]] : !fir.ptr<i32>
! CHECK: }
-! CHECK: fir.store %[[I_RES]] to %[[I_PTR]] : !fir.ptr<i32>
+ end do
+! CHECK: %[[S_CVT:.*]] = fir.convert %[[S]] : (i32) -> index
+! CHECK: %[[E_CVT:.*]] = fir.convert %[[E]] : (i32) -> index
+! CHECK: %[[ST_CVT:.*]] = fir.convert %[[ST]] : (i32) -> index
+! CHECK: %[[C0:.*]] = arith.constant 0 : index
+! CHECK: %[[DIFF:.*]] = arith.subi %[[E_CVT]], %[[S_CVT]] : index
+! CHECK: %[[ADD:.*]] = arith.addi %[[DIFF]], %[[ST_CVT]] : index
+! CHECK: %[[TRIP:.*]] = arith.divsi %[[ADD]], %[[ST_CVT]] : index
+! CHECK: %[[CMP:.*]] = arith.cmpi slt, %[[TRIP]], %[[C0]] : index
+! CHECK: %[[SEL:.*]] = arith.select %[[CMP]], %[[C0]], %[[TRIP]] : index
+! CHECK: %[[MUL:.*]] = arith.muli %[[SEL]], %[[ST_CVT]] : index
+! CHECK: %[[LASTIDX:.*]] = arith.addi %[[S_CVT]], %[[MUL]] : index
+! CHECK: %[[LAST:.*]] = fir.convert %[[LASTIDX]] : (index) -> i32
+! CHECK: fir.store %[[LAST]] to %[[I_PTR]] : !fir.ptr<i32>
end subroutine
! Test usage of non-default integer kind for loop control and loop index variable
@@ -223,26 +239,28 @@ subroutine loop_with_non_default_integer(s,e,st)
! CHECK-DAG: %[[I_DECL:.*]]:2 = hlfir.declare %[[I_REF]]
integer(kind=8):: i
! CHECK: %[[S:.*]] = fir.load %[[S_DECL]]#0 : !fir.ref<i64>
- ! CHECK: %[[S_CVT:.*]] = fir.convert %[[S]] : (i64) -> index
! CHECK: %[[E:.*]] = fir.load %[[E_DECL]]#0 : !fir.ref<i64>
- ! CHECK: %[[E_CVT:.*]] = fir.convert %[[E]] : (i64) -> index
! CHECK: %[[ST:.*]] = fir.load %[[ST_DECL]]#0 : !fir.ref<i64>
- ! CHECK: %[[ST_CVT:.*]] = fir.convert %[[ST]] : (i64) -> index
integer(kind=8) :: s, e, st
- ! CHECK: %[[I_LB:.*]] = fir.convert %[[S_CVT]] : (index) -> i64
- ! CHECK: %[[I_RES:.*]] = fir.do_loop %[[LI:[^ ]*]] =
- ! CHECK-SAME: %[[S_CVT]] to %[[E_CVT]] step %[[ST_CVT]]
- ! CHECK-SAME: iter_args(%[[I_IV:.*]] = %[[I_LB]]) -> (i64) {
+ ! CHECK: fir.do_loop %[[LI:[^ ]*]] = %[[S]] to %[[E]] step %[[ST]] : i64 {
do i=s,e,st
- ! CHECK: fir.store %[[I_IV]] to %[[I_DECL]]#0 : !fir.ref<i64>
- ! CHECK: %[[I_STEPCAST:.*]] = fir.convert %[[ST_CVT]] : (index) -> i64
- ! CHECK: %[[I_IVLOAD:.*]] = fir.load %[[I_DECL]]#0 : !fir.ref<i64>
- ! CHECK: %[[I_IVINC:.*]] = arith.addi %[[I_IVLOAD]], %[[I_STEPCAST]] overflow<nsw> : i64
- ! CHECK: fir.result %[[I_IVINC]] : i64
- end do
+ ! CHECK: fir.store %[[LI]] to %[[I_DECL]]#0 : !fir.ref<i64>
! CHECK: }
- ! CHECK: fir.store %[[I_RES]] to %[[I_DECL]]#0 : !fir.ref<i64>
+ end do
+ ! CHECK: %[[S_CVT:.*]] = fir.convert %[[S]] : (i64) -> index
+ ! CHECK: %[[E_CVT:.*]] = fir.convert %[[E]] : (i64) -> index
+ ! CHECK: %[[ST_CVT:.*]] = fir.convert %[[ST]] : (i64) -> index
+ ! CHECK: %[[C0:.*]] = arith.constant 0 : index
+ ! CHECK: %[[DIFF:.*]] = arith.subi %[[E_CVT]], %[[S_CVT]] : index
+ ! CHECK: %[[ADD:.*]] = arith.addi %[[DIFF]], %[[ST_CVT]] : index
+ ! CHECK: %[[TRIP:.*]] = arith.divsi %[[ADD]], %[[ST_CVT]] : index
+ ! CHECK: %[[CMP:.*]] = arith.cmpi slt, %[[TRIP]], %[[C0]] : index
+ ! CHECK: %[[SEL:.*]] = arith.select %[[CMP]], %[[C0]], %[[TRIP]] : index
+ ! CHECK: %[[MUL:.*]] = arith.muli %[[SEL]], %[[ST_CVT]] : index
+ ! CHECK: %[[LASTIDX:.*]] = arith.addi %[[S_CVT]], %[[MUL]] : index
+ ! CHECK: %[[LAST:.*]] = fir.convert %[[LASTIDX]] : (index) -> i64
+ ! CHECK: fir.store %[[LAST]] to %[[I_DECL]]#0 : !fir.ref<i64>
end subroutine
! Test real loop control.
diff --git a/flang/test/Lower/do_loop_execute_region_wrap.f90 b/flang/test/Lower/do_loop_execute_region_wrap.f90
index 92bb4e41e9b3f..0725f50c17343 100644
--- a/flang/test/Lower/do_loop_execute_region_wrap.f90
+++ b/flang/test/Lower/do_loop_execute_region_wrap.f90
@@ -20,7 +20,6 @@ subroutine wrapped_unstructured(n, a)
! CHECK: fir.unreachable
! CHECK: scf.yield
! CHECK: }
-! CHECK: fir.result
! Unstructured DO with a GOTO targeting a label outside the construct that
! is reachable on a path distinct from the loop's natural exit: not wrapped.
@@ -141,8 +140,6 @@ subroutine outer_structured_inner_wrapped(n, a)
! CHECK: fir.unreachable
! CHECK: scf.yield
! CHECK: }
-! CHECK: fir.result
-! CHECK: fir.result
! Structured outer DO containing an unstructured inner DO (the inner DO has
! an EXIT that targets its own construct exit). isUnstructured does not
@@ -168,4 +165,3 @@ subroutine outer_fir_do_loop_inner_unstructured_do(n, a)
! CHECK: cf.cond_br
! CHECK: scf.yield
! CHECK: }
-! CHECK: fir.result
diff --git a/flang/test/Lower/do_loop_unstructured.f90 b/flang/test/Lower/do_loop_unstructured.f90
index 99b8cddd083fa..3d22a3e277812 100644
--- a/flang/test/Lower/do_loop_unstructured.f90
+++ b/flang/test/Lower/do_loop_unstructured.f90
@@ -112,8 +112,8 @@ subroutine nested_unstructured()
! CHECK: %[[LOOP_VAR_J_DECL:.*]]:2 = hlfir.declare %[[LOOP_VAR_J_REF]]
! CHECK: %[[LOOP_VAR_K_REF:.*]] = fir.alloca i32 {bindc_name = "k", uniq_name = "_QFnested_unstructuredEk"}
! CHECK: %[[LOOP_VAR_K_DECL:.*]]:2 = hlfir.declare %[[LOOP_VAR_K_REF]]
-! CHECK: fir.do_loop %{{[^ ]+}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%{{[^ ]+}} = %{{.*}}) -> (i32) {
-! CHECK: fir.do_loop %{{[^ ]+}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%{{[^ ]+}} = %{{.*}}) -> (i32) {
+! CHECK: fir.do_loop %{{[^ ]+}} = %{{.*}} to %{{.*}} step %{{.*}} : i32 {
+! CHECK: fir.do_loop %{{[^ ]+}} = %{{.*}} to %{{.*}} step %{{.*}} : i32 {
! CHECK: scf.execute_region no_inline {
! CHECK: cf.br ^[[HEADER_K:.*]]
! CHECK: ^[[HEADER_K]]:
@@ -131,9 +131,7 @@ subroutine nested_unstructured()
! CHECK: ^[[EXIT_K]]:
! CHECK: scf.yield
! CHECK: }
-! CHECK: fir.result %{{.*}} : i32
! CHECK: }
-! CHECK: fir.result %{{.*}} : i32
! CHECK: }
! CHECK: return
@@ -169,13 +167,23 @@ subroutine nested_structured_in_unstructured()
! CHECK: %[[COND:.*]] = arith.cmpi sgt, %[[TRIP_VAR]], %[[ZERO]] : i32
! CHECK: cf.cond_br %[[COND]], ^[[BODY:.*]], ^[[EXIT:.*]]
! CHECK: ^[[BODY]]:
-! CHECK: %{{.*}} = fir.do_loop %[[J_INDEX:[^ ]*]] =
-! CHECK-SAME: %{{.*}} to %{{.*}} step %[[ST:[^ ]*]]
-! CHECK-SAME: iter_args(%[[J_IV:.*]] = %{{.*}}) -> (i32) {
+! CHECK: fir.do_loop %[[J_IV:[^ ]*]] =
+! CHECK-SAME: %[[J_LB:[^ ]*]] to %[[J_UB:[^ ]*]] step %[[J_ST:[^ ]*]] : i32 {
! CHECK: fir.store %[[J_IV]] to %[[LOOP_VAR_J_DECL]]#0 : !fir.ref<i32>
-! CHECK: %[[LOOP_VAR_J:.*]] = fir.load %[[LOOP_VAR_J_DECL]]#0 : !fir.ref<i32>
-! CHECK: %[[LOOP_VAR_J_NEXT:.*]] = arith.addi %[[LOOP_VAR_J]], %{{[^ ]*}} overflow<nsw> : i32
! CHECK: }
+! CHECK: %[[J_LBIDX:.*]] = fir.convert %[[J_LB]] : (i32) -> index
+! CHECK: %[[J_UBIDX:.*]] = fir.convert %[[J_UB]] : (i32) -> index
+! CHECK: %[[J_STIDX:.*]] = fir.convert %[[J_ST]] : (i32) -> index
+! CHECK: %[[J_C0:.*]] = arith.constant 0 : index
+! CHECK: %[[J_DIFF:.*]] = arith.subi %[[J_UBIDX]], %[[J_LBIDX]] : index
+! CHECK: %[[J_ADD:.*]] = arith.addi %[[J_DIFF]], %[[J_STIDX]] : index
+! CHECK: %[[J_TRIP:.*]] = arith.divsi %[[J_ADD]], %[[J_STIDX]] : index
+! CHECK: %[[J_CMP:.*]] = arith.cmpi slt, %[[J_TRIP]], %[[J_C0]] : index
+! CHECK: %[[J_SEL:.*]] = arith.select %[[J_CMP]], %[[J_C0]], %[[J_TRIP]] : index
+! CHECK: %[[J_MUL:.*]] = arith.muli %[[J_SEL]], %[[J_STIDX]] : index
+! CHECK: %[[J_LASTIDX:.*]] = arith.addi %[[J_LBIDX]], %[[J_MUL]] : index
+! CHECK: %[[J_LAST:.*]] = fir.convert %[[J_LASTIDX]] : (index) -> i32
+! CHECK: fir.store %[[J_LAST]] to %[[LOOP_VAR_J_DECL]]#0 : !fir.ref<i32>
! CHECK: %[[TRIP_VAR_I:.*]] = fir.load %[[TRIP_VAR_I_REF]] : !fir.ref<i32>
! CHECK: %[[C1_3:.*]] = arith.constant 1 : i32
! CHECK: %[[TRIP_VAR_I_NEXT:.*]] = arith.subi %[[TRIP_VAR_I]], %[[C1_3]] : i32
diff --git a/flang/test/Lower/infinite_loop.f90 b/flang/test/Lower/infinite_loop.f90
index 64fe0bc1b965a..e9cf0dfb16a59 100644
--- a/flang/test/Lower/infinite_loop.f90
+++ b/flang/test/Lower/infinite_loop.f90
@@ -82,7 +82,7 @@ subroutine structured_loop_in_infinite(i)
! CHECK-DAG: %[[C100:.*]] = arith.constant 100 : i32
! CHECK-DAG: %[[C1:.*]] = arith.constant 1 : i32
! CHECK-DAG: %[[C10:.*]] = arith.constant 10 : i32
-! CHECK-DAG: %[[C1_1:.*]] = arith.constant 1 : index
+! CHECK-DAG: %[[C0:.*]] = arith.constant 0 : index
! CHECK-DAG: %[[I_DECL:.*]] = fir.declare %[[I_REF]] {{.*}}
! CHECK-DAG: %[[J_REF:.*]] = fir.alloca i32 {bindc_name = "j", uniq_name = "_QFstructured_loop_in_infiniteEj"}
! CHECK-DAG: %[[J_DECL:.*]] = fir.declare %[[J_REF]] {{.*}}
@@ -94,19 +94,22 @@ subroutine structured_loop_in_infinite(i)
! CHECK: ^[[EXIT]]:
! CHECK: cf.br ^[[RETURN:.*]]
! CHECK: ^[[BODY2:.*]]:
+! CHECK: fir.do_loop %[[J:[^ ]*]] =
+! CHECK-SAME: %[[C1]] to %[[C10]] step %[[C1]] : i32 {
+! CHECK: fir.store %[[J]] to %[[J_DECL]] : !fir.ref<i32>
+! CHECK: }
! CHECK: %[[C1_INDEX:.*]] = fir.convert %[[C1]] : (i32) -> index
! CHECK: %[[C10_INDEX:.*]] = fir.convert %[[C10]] : (i32) -> index
-! CHECK: %[[J_LB:.*]] = fir.convert %[[C1_INDEX]] : (index) -> i32
-! CHECK: %[[J_FINAL:.*]] = fir.do_loop %[[J:[^ ]*]] =
-! CHECK-SAME: %[[C1_INDEX]] to %[[C10_INDEX]] step %[[C1_1]]
-! CHECK-SAME: iter_args(%[[J_IV:.*]] = %[[J_LB]]) -> (i32) {
-! CHECK: fir.store %[[J_IV]] to %[[J_DECL]] : !fir.ref<i32>
-! CHECK: %[[J_STEPCAST:.*]] = fir.convert %[[C1_1]] : (index) -> i32
-! CHECK: %[[J_IVLOAD:.*]] = fir.load %[[J_DECL]] : !fir.ref<i32>
-! CHECK: %[[J_IVINC:.*]] = arith.addi %[[J_IVLOAD]], %[[J_STEPCAST]] overflow<nsw> : i32
-! CHECK: fir.result %[[J_IVINC]] : i32
-! CHECK: }
-! CHECK: fir.store %[[J_FINAL]] to %[[J_DECL]] : !fir.ref<i32>
+! CHECK: %[[C1_STEP_INDEX:.*]] = fir.convert %[[C1]] : (i32) -> index
+! CHECK: %[[J_DIFF:.*]] = arith.subi %[[C10_INDEX]], %[[C1_INDEX]] : index
+! CHECK: %[[J_ADD:.*]] = arith.addi %[[J_DIFF]], %[[C1_STEP_INDEX]] : index
+! CHECK: %[[J_TRIP:.*]] = arith.divsi %[[J_ADD]], %[[C1_STEP_INDEX]] : index
+! CHECK: %[[J_CMP:.*]] = arith.cmpi slt, %[[J_TRIP]], %[[C0]] : index
+! CHECK: %[[J_SEL:.*]] = arith.select %[[J_CMP]], %[[C0]], %[[J_TRIP]] : index
+! CHECK: %[[J_MUL:.*]] = arith.muli %[[J_SEL]], %[[C1_STEP_INDEX]] : index
+! CHECK: %[[J_LASTIDX:.*]] = arith.addi %[[C1_INDEX]], %[[J_MUL]] : index
+! CHECK: %[[J_LAST:.*]] = fir.convert %[[J_LASTIDX]] : (index) -> i32
+! CHECK: fir.store %[[J_LAST]] to %[[J_DECL]] : !fir.ref<i32>
! CHECK: cf.br ^[[BODY1]]
! CHECK: ^[[RETURN]]:
! CHECK: return
diff --git a/flang/test/Lower/inline_directive.f90 b/flang/test/Lower/inline_directive.f90
index 5748690d5914d..d77b170780f53 100644
--- a/flang/test/Lower/inline_directive.f90
+++ b/flang/test/Lower/inline_directive.f90
@@ -36,14 +36,14 @@ subroutine test_inline()
!dir$ forceinline
do i = 1, 100
- !CHECK: fir.do_loop %[[ARG_0:.*]] = %[[FROM:.*]] to %[[TO:.*]] step %[[C1:.*]] iter_args(%[[ARG_1:.*]] = {{.*}}) -> (i32) {
+ !CHECK: fir.do_loop %[[ARG_0:.*]] = %[[FROM:.*]] to %[[TO:.*]] step %[[C1:.*]] {
!CHECK: fir.call @_QFtest_inlinePf(%[[VAL_1]], %[[VAL_3]]) fastmath<contract> {inline_attr = #fir.inline_attrs<always_inline>} : (!fir.ref<i32>, !fir.ref<i32>) -> ()
call f(x, y)
enddo
!dir$ inline
do i = 1, 100
- !CHECK: fir.do_loop %[[ARG_0:.*]] = %[[FROM:.*]] to %[[TO:.*]] step %[[C1:.*]] iter_args(%[[ARG_1:.*]] = {{.*}}) -> (i32) {
+ !CHECK: fir.do_loop %[[ARG_0:.*]] = %[[FROM:.*]] to %[[TO:.*]] step %[[C1:.*]] {
!CHECK: fir.call @_QFtest_inlinePf(%[[VAL_1]], %[[VAL_3]]) fastmath<contract> {inline_attr = #fir.inline_attrs<inline_hint>} : (!fir.ref<i32>, !fir.ref<i32>) -> ()
call f(x, y)
enddo
diff --git a/flang/test/Lower/ivdep.f90 b/flang/test/Lower/ivdep.f90
index 69f54cd1b0604..d1ea01425b635 100644
--- a/flang/test/Lower/ivdep.f90
+++ b/flang/test/Lower/ivdep.f90
@@ -23,10 +23,6 @@ subroutine ivdep_test1
!CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_10]] : (i32) -> i64
!CHECK: %[[VAL_12:.*]] = hlfir.designate %[[VAL_2:.*]]#0 (%[[VAL_11]]) : (!fir.ref<!fir.array<10xi32>>, i64)
!CHECK: hlfir.assign %[[VAL_9]] to %[[VAL_12]] {access_groups = [#access_group]} : i32, !fir.ref<i32>
- !CHECK: %[[VAL_14:.*]] = fir.convert %[[C1:.*]] : (index) -> i32
- !CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_4]]#0 {accessGroups = [#access_group]}
- !CHECK: %[[VAL_16:.*]] = arith.addi %[[VAL_15]], %[[VAL_14]] overflow<nsw> : i32
- !CHECK: fir.result %[[VAL_16]] : i32
end do
end subroutine ivdep_test1
@@ -53,10 +49,6 @@ subroutine ivdep_test2
!CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_24]] : (i32) -> i64
!CHECK: %[[VAL_26:.*]] = hlfir.designate %[[VAL_2:.*]]#0 (%[[VAL_25]]) : (!fir.ref<!fir.array<10xi32>>, i64)
!CHECK: hlfir.assign %[[VAL_23]] to %[[VAL_26]] {access_groups = [#access_group1]} : i32, !fir.ref<i32>
- !CHECK: %[[VAL_28:.*]] = fir.convert %[[C1:.*]] : (index) -> i32
- !CHECK: %[[VAL_29:.*]] = fir.load %[[VAL_10]]#0 {accessGroups = [#access_group1]}
- !CHECK: %[[VAL_30:.*]] = arith.addi %[[VAL_29]], %[[VAL_28]] overflow<nsw> : i32
- !CHECK: fir.result %[[VAL_30]] : i32
end do
end subroutine ivdep_test2
@@ -84,10 +76,6 @@ subroutine ivdep_test3
!CHECK: %[[VAL_26:.*]] = hlfir.designate %[[VAL_2:.*]]#0 (%[[VAL_25]]) : (!fir.ref<!fir.array<10xi32>>, i64)
!CHECK: hlfir.assign %[[VAL_23]] to %[[VAL_26]] {access_groups = [#access_group2]} : i32, !fir.ref<i32>
!CHECK: fir.call @_QFivdep_test3Pfoo() fastmath<contract> {accessGroups = [#access_group2]}
- !CHECK: %[[VAL_28:.*]] = fir.convert %[[C1:.*]] : (index) -> i32
- !CHECK: %[[VAL_29:.*]] = fir.load %[[VAL_10]]#0 {accessGroups = [#access_group2]}
- !CHECK: %[[VAL_30:.*]] = arith.addi %[[VAL_29]], %[[VAL_28]] overflow<nsw> : i32
- !CHECK: fir.result %[[VAL_30]] : i32
end do
contains
subroutine foo()
diff --git a/flang/test/Lower/loops.f90 b/flang/test/Lower/loops.f90
index bb66f79d5564a..7c500b7a85199 100644
--- a/flang/test/Lower/loops.f90
+++ b/flang/test/Lower/loops.f90
@@ -31,7 +31,7 @@ subroutine loop_test
a(i,j,k) = a(i,j,k) + 1
enddo
- ! CHECK-COUNT-3: fir.do_loop {{[^un]*}} -> (i32)
+ ! CHECK-COUNT-3: fir.do_loop {{[^un]*}}
asum = 0
do i=1,5
do j=1,5
@@ -118,7 +118,7 @@ subroutine lis(n)
! CHECK: %[[V_P_ALLOC:[0-9]+]] = fir.alloca !fir.box<!fir.ptr<!fir.array<?x?x?xi32>>> {bindc_name = "p", pinned, uniq_name = "_QFlisEp"}
! CHECK: fir.store %{{.*}} to %[[V_P_ALLOC]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?x?x?xi32>>>>
! CHECK: %[[V_P_DECL:.*]]:2 = hlfir.declare %[[V_P_ALLOC]]
- ! CHECK: fir.do_loop %arg3 = %{{.*}} to %{{.*}} step %c1{{.*}} iter_args(%arg4 = %{{.*}}) -> (i32) {
+ ! CHECK: fir.do_loop %arg3 = %{{.*}} to %{{.*}} step %c1{{.*}} {
! CHECK: fir.do_concurrent {
! CHECK: fir.alloca i32 {bindc_name = "m"}
! CHECK: fir.do_concurrent.loop (%{{.*}}) = (%{{.*}}) to (%{{.*}}) step (%{{.*}}) {
diff --git a/flang/test/Lower/loops2.f90 b/flang/test/Lower/loops2.f90
index b24e8b6401ce6..e38900dc57ff6 100644
--- a/flang/test/Lower/loops2.f90
+++ b/flang/test/Lower/loops2.f90
@@ -15,9 +15,22 @@ subroutine test_pointer()
! CHECK: %[[PTR:.*]]:2 = hlfir.declare %{{.*}} {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMtest_loop_varEi_pointer"}
! CHECK: %[[BOX:.*]] = fir.load %[[PTR]]#0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
! CHECK: %[[ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
-! CHECK: %[[LOOP:.*]] = fir.do_loop
-! CHECK: fir.store %{{.*}} to %[[ADDR]] : !fir.ptr<i32>
-! CHECK: fir.store %[[LOOP]] to %[[ADDR]] : !fir.ptr<i32>
+! CHECK: fir.do_loop %[[IV:.*]] = %[[LB:.*]] to %[[UB:.*]] step %[[STEP:.*]] : i32 {
+! CHECK: fir.store %[[IV]] to %[[ADDR]] : !fir.ptr<i32>
+! CHECK: }
+! CHECK: %[[LBIDX:.*]] = fir.convert %[[LB]] : (i32) -> index
+! CHECK: %[[UBIDX:.*]] = fir.convert %[[UB]] : (i32) -> index
+! CHECK: %[[STEPIDX:.*]] = fir.convert %[[STEP]] : (i32) -> index
+! CHECK: %[[C0:.*]] = arith.constant 0 : index
+! CHECK: %[[DIFF:.*]] = arith.subi %[[UBIDX]], %[[LBIDX]] : index
+! CHECK: %[[ADD:.*]] = arith.addi %[[DIFF]], %[[STEPIDX]] : index
+! CHECK: %[[TRIP:.*]] = arith.divsi %[[ADD]], %[[STEPIDX]] : index
+! CHECK: %[[CMP:.*]] = arith.cmpi slt, %[[TRIP]], %[[C0]] : index
+! CHECK: %[[SEL:.*]] = arith.select %[[CMP]], %[[C0]], %[[TRIP]] : index
+! CHECK: %[[MUL:.*]] = arith.muli %[[SEL]], %[[STEPIDX]] : index
+! CHECK: %[[LASTIDX:.*]] = arith.addi %[[LBIDX]], %[[MUL]] : index
+! CHECK: %[[LAST:.*]] = fir.convert %[[LASTIDX]] : (index) -> i32
+! CHECK: fir.store %[[LAST]] to %[[ADDR]] : !fir.ptr<i32>
end subroutine
! CHECK-LABEL: func.func @_QMtest_loop_varPtest_allocatable
@@ -27,9 +40,22 @@ subroutine test_allocatable()
! CHECK: %[[ALLOC:.*]]:2 = hlfir.declare %{{.*}} {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QMtest_loop_varEi_allocatable"}
! CHECK: %[[BOX:.*]] = fir.load %[[ALLOC]]#0 : !fir.ref<!fir.box<!fir.heap<i32>>>
! CHECK: %[[ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
-! CHECK: %[[LOOP:.*]] = fir.do_loop
-! CHECK: fir.store %{{.*}} to %[[ADDR]] : !fir.heap<i32>
-! CHECK: fir.store %[[LOOP]] to %[[ADDR]] : !fir.heap<i32>
+! CHECK: fir.do_loop %[[IV:.*]] = %[[LB:.*]] to %[[UB:.*]] step %[[STEP:.*]] : i32 {
+! CHECK: fir.store %[[IV]] to %[[ADDR]] : !fir.heap<i32>
+! CHECK: }
+! CHECK: %[[LBIDX:.*]] = fir.convert %[[LB]] : (i32) -> index
+! CHECK: %[[UBIDX:.*]] = fir.convert %[[UB]] : (i32) -> index
+! CHECK: %[[STEPIDX:.*]] = fir.convert %[[STEP]] : (i32) -> index
+! CHECK: %[[C0:.*]] = arith.constant 0 : index
+! CHECK: %[[DIFF:.*]] = arith.subi %[[UBIDX]], %[[LBIDX]] : index
+! CHECK: %[[ADD:.*]] = arith.addi %[[DIFF]], %[[STEPIDX]] : index
+! CHECK: %[[TRIP:.*]] = arith.divsi %[[ADD]], %[[STEPIDX]] : index
+! CHECK: %[[CMP:.*]] = arith.cmpi slt, %[[TRIP]], %[[C0]] : index
+! CHECK: %[[SEL:.*]] = arith.select %[[CMP]], %[[C0]], %[[TRIP]] : index
+! CHECK: %[[MUL:.*]] = arith.muli %[[SEL]], %[[STEPIDX]] : index
+! CHECK: %[[LASTIDX:.*]] = arith.addi %[[LBIDX]], %[[MUL]] : index
+! CHECK: %[[LAST:.*]] = fir.convert %[[LASTIDX]] : (index) -> i32
+! CHECK: fir.store %[[LAST]] to %[[ADDR]] : !fir.heap<i32>
end subroutine
! CHECK-LABEL: func.func @_QMtest_loop_varPtest_real_pointer
diff --git a/flang/test/Lower/mixed_loops.f90 b/flang/test/Lower/mixed_loops.f90
index 2a5aa40ff22cd..9c774caccf131 100644
--- a/flang/test/Lower/mixed_loops.f90
+++ b/flang/test/Lower/mixed_loops.f90
@@ -12,7 +12,7 @@ subroutine while_inside_do_loop
! CHECK-DAG: %[[J:.*]]:2 = hlfir.declare %[[J_ADDR]]
integer :: i, j
- ! CHECK: fir.do_loop %{{[^ ]+}} = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%[[I_IV:.*]] = %{{.*}}) -> (i32) {
+ ! CHECK: fir.do_loop %[[I_IV:.*]] = %{{.*}} to %{{.*}} step %{{.*}} : i32 {
! CHECK: fir.store %[[I_IV]] to %[[I]]#0 : !fir.ref<i32>
do i=8,13
! CHECK: %[[C3:.*]] = arith.constant 3 : i32
@@ -38,7 +38,6 @@ subroutine while_inside_do_loop
! CHECK: ^[[EXIT2]]:
! CHECK: scf.yield
! CHECK: }
- ! CHECK: fir.result %{{.*}} : i32
end do
! CHECK: }
@@ -74,19 +73,31 @@ subroutine do_inside_while_loop
do while (j .lt. 21)
! CHECK: ^[[BODY1]]: // pred: ^[[HDR1]]
- ! CHECK: %{{.*}} = fir.do_loop %{{.*}} = {{.*}} to {{.*}} step {{.*}} iter_args(%[[I_IV:.*]] = {{.*}}) -> (i32) {
- ! CHECK: fir.store %[[I_IV]] to %[[I]]#0 : !fir.ref<i32>
- ! CHECK: %[[C2:.*]] = arith.constant 2 : i32
- ! CHECK: %[[J2VAL:.*]] = fir.load %[[J]]#0 : !fir.ref<i32>
- ! CHECK: %[[JINC:.*]] = arith.muli %[[C2]], %[[J2VAL]] : i32
- ! CHECK: hlfir.assign %[[JINC]] to %[[J]]#0 : i32, !fir.ref<i32>
- ! CHECK: %[[I_IVLOAD:.*]] = fir.load %[[I]]#0 : !fir.ref<i32>
- ! CHECK: %[[I_IVINC:.*]] = arith.addi %[[I_IVLOAD]], {{.*}} overflow<nsw> : i32
- ! CHECK: fir.result %[[I_IVINC]] : i32
+ ! CHECK-DAG: %[[C8:.*]] = arith.constant 8 : i32
+ ! CHECK-DAG: %[[C13:.*]] = arith.constant 13 : i32
+ ! CHECK-DAG: %[[C1:.*]] = arith.constant 1 : i32
+ ! CHECK: fir.do_loop %[[LI:.*]] = %[[LB:.*]] to %[[UB:.*]] step %[[STEP:.*]] : i32 {
+ ! CHECK: fir.store %[[LI]] to %[[I]]#0 : !fir.ref<i32>
+ ! CHECK: %[[C2:.*]] = arith.constant 2 : i32
+ ! CHECK: %[[J2VAL:.*]] = fir.load %[[J]]#0 : !fir.ref<i32>
+ ! CHECK: %[[JINC:.*]] = arith.muli %[[C2]], %[[J2VAL]] : i32
+ ! CHECK: hlfir.assign %[[JINC]] to %[[J]]#0 : i32, !fir.ref<i32>
do i=8,13
j=j*2
- ! CHECK: fir.store %{{.*}} to %[[I]]#0 : !fir.ref<i32>
+ ! CHECK: %[[LBIDX:.*]] = fir.convert %[[LB]] : (i32) -> index
+ ! CHECK: %[[UBIDX:.*]] = fir.convert %[[UB]] : (i32) -> index
+ ! CHECK: %[[STEPIDX:.*]] = fir.convert %[[STEP]] : (i32) -> index
+ ! CHECK: %[[C0:.*]] = arith.constant 0 : index
+ ! CHECK: %[[DIFF:.*]] = arith.subi %[[UBIDX]], %[[LBIDX]] : index
+ ! CHECK: %[[ADD:.*]] = arith.addi %[[DIFF]], %[[STEPIDX]] : index
+ ! CHECK: %[[TRIP:.*]] = arith.divsi %[[ADD]], %[[STEPIDX]] : index
+ ! CHECK: %[[CMP:.*]] = arith.cmpi slt, %[[TRIP]], %[[C0]] : index
+ ! CHECK: %[[SEL:.*]] = arith.select %[[CMP]], %[[C0]], %[[TRIP]] : index
+ ! CHECK: %[[MUL:.*]] = arith.muli %[[SEL]], %[[STEPIDX]] : index
+ ! CHECK: %[[LASTIDX:.*]] = arith.addi %[[LBIDX]], %[[MUL]] : index
+ ! CHECK: %[[LAST:.*]] = fir.convert %[[LASTIDX]] : (index) -> i32
+ ! CHECK: fir.store %[[LAST]] to %[[I]]#0 : !fir.ref<i32>
end do
! CHECK: cf.br ^[[HDR1]]
diff --git a/flang/test/Lower/nsw.f90 b/flang/test/Lower/nsw.f90
index 4bc932ac38508..fa18dbff97ecc 100644
--- a/flang/test/Lower/nsw.f90
+++ b/flang/test/Lower/nsw.f90
@@ -77,14 +77,15 @@ subroutine loop_params(a,lb,ub,st)
! CHECK: %[[VAL_14:.*]] = fir.load %[[VAL_9]] : !fir.ref<i32>
! CHECK: %[[VAL_16:.*]] = fir.load %[[VAL_10]] : !fir.ref<i32>
! CHECK: %[[VAL_25:.*]] = arith.addi %[[VAL_14]], %[[VAL_5]] overflow<nsw> : i32
-! CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_25]] : (i32) -> index
-! CHECK: %[[VAL_27:.*]] = arith.subi %[[VAL_16]], %[[VAL_5]] overflow<nsw> : i32
-! CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_27]] : (i32) -> index
-! CHECK: %[[VAL_29:.*]] = fir.load %[[VAL_13]] : !fir.ref<i32>
-! CHECK: %[[VAL_30:.*]] = arith.muli %[[VAL_29]], %[[VAL_4]] overflow<nsw> : i32
-! CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (i32) -> index
-! CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_26]] : (index) -> i32
-! CHECK: %[[VAL_33:.*]] = fir.do_loop %[[VAL_34:.*]] = %[[VAL_26]] to %[[VAL_28]] step %[[VAL_31]] iter_args(%[[VAL_35:.*]] = %[[VAL_32]]) -> (i32) {
+! CHECK: %[[VAL_26:.*]] = arith.subi %[[VAL_16]], %[[VAL_5]] overflow<nsw> : i32
+! CHECK: %[[VAL_27:.*]] = fir.load %[[VAL_13]] : !fir.ref<i32>
+! CHECK: %[[VAL_28:.*]] = arith.muli %[[VAL_27]], %[[VAL_4]] overflow<nsw> : i32
+! CHECK: fir.do_loop %[[VAL_29:.*]] = %[[VAL_25]] to %[[VAL_26]] step %[[VAL_28]] : i32 {
+! CHECK: fir.store %[[VAL_29]] to %[[VAL_12]] : !fir.ref<i32>
+! CHECK: }
+! CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_25]] : (i32) -> index
+! CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_26]] : (i32) -> index
+! CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_28]] : (i32) -> index
subroutine loop_params2(a,lb,ub,st)
integer :: i, lb, ub, st
diff --git a/flang/test/Transforms/DoConcurrent/skip_all_nested_loops.f90 b/flang/test/Transforms/DoConcurrent/skip_all_nested_loops.f90
index ebacd0353b90b..f147a2bfb664d 100644
--- a/flang/test/Transforms/DoConcurrent/skip_all_nested_loops.f90
+++ b/flang/test/Transforms/DoConcurrent/skip_all_nested_loops.f90
@@ -48,7 +48,7 @@ program main
! COMMON: omp.wsloop {
! COMMON: omp.loop_nest ({{[^[:space:]]+}}) {{.*}} {
-! COMMON: fir.do_loop {{.*}} iter_args(%[[J_IV:.*]] = {{.*}}) -> {{.*}} {
+! COMMON: fir.do_loop %[[J_IV:.*]] = {{.*}} to {{.*}} step {{.*}} : i32 {
! HOST: fir.store %[[J_IV]] to %[[ORIG_J_DECL]]#0
! DEVICE: fir.store %[[J_IV]] to %[[TARGET_J_DECL]]#0
More information about the flang-commits
mailing list