@@ -49,8 +49,9 @@ struct AffineIfAnalysis;
4949// / second when doing rewrite.
5050struct AffineFunctionAnalysis {
5151 explicit AffineFunctionAnalysis (mlir::func::FuncOp funcOp) {
52- for (fir::DoLoopOp op : funcOp.getOps <fir::DoLoopOp>())
53- loopAnalysisMap.try_emplace (op, op, *this );
52+ funcOp->walk ([&](fir::DoLoopOp doloop) {
53+ loopAnalysisMap.try_emplace (doloop, doloop, *this );
54+ });
5455 }
5556
5657 AffineLoopAnalysis getChildLoopAnalysis (fir::DoLoopOp op) const ;
@@ -102,10 +103,23 @@ struct AffineLoopAnalysis {
102103 return true ;
103104 }
104105
106+ bool analysisResults (fir::DoLoopOp loopOperation) {
107+ if (loopOperation.getFinalValue () &&
108+ !loopOperation.getResult (0 ).use_empty ()) {
109+ LLVM_DEBUG (
110+ llvm::dbgs ()
111+ << " AffineLoopAnalysis: cannot promote loop final value\n " ;);
112+ return false ;
113+ }
114+
115+ return true ;
116+ }
117+
105118 bool analyzeLoop (fir::DoLoopOp loopOperation,
106119 AffineFunctionAnalysis &functionAnalysis) {
107120 LLVM_DEBUG (llvm::dbgs () << " AffineLoopAnalysis: \n " ; loopOperation.dump (););
108121 return analyzeMemoryAccess (loopOperation) &&
122+ analysisResults (loopOperation) &&
109123 analyzeBody (loopOperation, functionAnalysis);
110124 }
111125
@@ -461,14 +475,28 @@ class AffineLoopConversion : public mlir::OpRewritePattern<fir::DoLoopOp> {
461475 LLVM_ATTRIBUTE_UNUSED auto loopAnalysis =
462476 functionAnalysis.getChildLoopAnalysis (loop);
463477 auto &loopOps = loop.getBody ()->getOperations ();
478+ auto resultOp = cast<fir::ResultOp>(loop.getBody ()->getTerminator ());
479+ auto results = resultOp.getOperands ();
480+ auto loopResults = loop->getResults ();
464481 auto loopAndIndex = createAffineFor (loop, rewriter);
465482 auto affineFor = loopAndIndex.first ;
466483 auto inductionVar = loopAndIndex.second ;
467484
485+ if (loop.getFinalValue ()) {
486+ results = results.drop_front ();
487+ loopResults = loopResults.drop_front ();
488+ }
489+
468490 rewriter.startOpModification (affineFor.getOperation ());
469491 affineFor.getBody ()->getOperations ().splice (
470492 std::prev (affineFor.getBody ()->end ()), loopOps, loopOps.begin (),
471493 std::prev (loopOps.end ()));
494+ rewriter.replaceAllUsesWith (loop.getRegionIterArgs (),
495+ affineFor.getRegionIterArgs ());
496+ if (!results.empty ()) {
497+ rewriter.setInsertionPointToEnd (affineFor.getBody ());
498+ rewriter.create <affine::AffineYieldOp>(resultOp->getLoc (), results);
499+ }
472500 rewriter.finalizeOpModification (affineFor.getOperation ());
473501
474502 rewriter.startOpModification (loop.getOperation ());
@@ -479,7 +507,8 @@ class AffineLoopConversion : public mlir::OpRewritePattern<fir::DoLoopOp> {
479507
480508 LLVM_DEBUG (llvm::dbgs () << " AffineLoopConversion: loop rewriten to:\n " ;
481509 affineFor.dump (););
482- rewriter.replaceOp (loop, affineFor.getOperation ()->getResults ());
510+ rewriter.replaceAllUsesWith (loopResults, affineFor->getResults ());
511+ rewriter.eraseOp (loop);
483512 return success ();
484513 }
485514
@@ -503,7 +532,7 @@ class AffineLoopConversion : public mlir::OpRewritePattern<fir::DoLoopOp> {
503532 ValueRange (op.getUpperBound ()),
504533 mlir::AffineMap::get (0 , 1 ,
505534 1 + mlir::getAffineSymbolExpr (0 , op.getContext ())),
506- step);
535+ step, op. getIterOperands () );
507536 return std::make_pair (affineFor, affineFor.getInductionVar ());
508537 }
509538
@@ -528,7 +557,7 @@ class AffineLoopConversion : public mlir::OpRewritePattern<fir::DoLoopOp> {
528557 genericUpperBound.getResult (),
529558 mlir::AffineMap::get (0 , 1 ,
530559 1 + mlir::getAffineSymbolExpr (0 , op.getContext ())),
531- 1 );
560+ 1 , op. getIterOperands () );
532561 rewriter.setInsertionPointToStart (affineFor.getBody ());
533562 auto actualIndex = rewriter.create <affine::AffineApplyOp>(
534563 op.getLoc (), actualIndexMap,
0 commit comments