@@ -2326,12 +2326,40 @@ genParallelOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
23262326
23272327static mlir::omp::ScanOp
23282328genScanOp (lower::AbstractConverter &converter, lower::SymMap &symTable,
2329- semantics::SemanticsContext &semaCtx, mlir::Location loc,
2330- const ConstructQueue &queue, ConstructQueue::const_iterator item) {
2329+ semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
2330+ mlir::Location loc, const ConstructQueue &queue,
2331+ ConstructQueue::const_iterator item) {
23312332 mlir::omp::ScanOperands clauseOps;
23322333 genScanClauses (converter, semaCtx, item->clauses , loc, clauseOps);
2333- return mlir::omp::ScanOp::create (converter.getFirOpBuilder (),
2334- converter.getCurrentLocation (), clauseOps);
2334+ mlir::omp::ScanOp scanOp = mlir::omp::ScanOp::create (
2335+ converter.getFirOpBuilder (), converter.getCurrentLocation (), clauseOps);
2336+ // All loop indices should be loaded after the scan construct as otherwise,
2337+ // it would result in using the index variable across scan directive.
2338+ // (`Intra-iteration dependences from a statement in the structured
2339+ // block sequence that precede a scan directive to a statement in the
2340+ // structured block sequence that follows a scan directive must not exist,
2341+ // except for dependences for the list items specified in an inclusive or
2342+ // exclusive clause.`).
2343+ // TODO: Nested loops are not handled.
2344+ mlir::omp::LoopNestOp loopNestOp =
2345+ scanOp->getParentOfType <mlir::omp::LoopNestOp>();
2346+ assert (loopNestOp.getNumLoops () == 1 &&
2347+ " Scan directive inside nested do loops is not handled yet." );
2348+ mlir::Region ®ion = loopNestOp->getRegion (0 );
2349+ mlir::Value indexVal = fir::getBase (region.getArgument (0 ));
2350+ lower::pft::Evaluation *doConstructEval = eval.parentConstruct ;
2351+ fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder ();
2352+ lower::pft::Evaluation *doLoop = &doConstructEval->getFirstNestedEvaluation ();
2353+ auto *doStmt = doLoop->getIf <parser::NonLabelDoStmt>();
2354+ assert (doStmt && " Expected do loop to be in the nested evaluation" );
2355+ const auto &loopControl =
2356+ std::get<std::optional<parser::LoopControl>>(doStmt->t );
2357+ const parser::LoopControl::Bounds *bounds =
2358+ std::get_if<parser::LoopControl::Bounds>(&loopControl->u );
2359+ mlir::Operation *storeOp =
2360+ setLoopVar (converter, loc, indexVal, bounds->name .thing .symbol );
2361+ firOpBuilder.setInsertionPointAfter (storeOp);
2362+ return scanOp;
23352363}
23362364
23372365static mlir::omp::SectionsOp
@@ -3416,7 +3444,7 @@ static void genOMPDispatch(lower::AbstractConverter &converter,
34163444 loc, queue, item);
34173445 break ;
34183446 case llvm::omp::Directive::OMPD_scan:
3419- newOp = genScanOp (converter, symTable, semaCtx, loc, queue, item);
3447+ newOp = genScanOp (converter, symTable, semaCtx, eval, loc, queue, item);
34203448 break ;
34213449 case llvm::omp::Directive::OMPD_section:
34223450 llvm_unreachable (" genOMPDispatch: OMPD_section" );
0 commit comments