[Mlir-commits] [flang] [mlir] [openmp] [MLIR][OpenMP] Add scan reduction lowering to llvm (PR #167031)

Sergio Afonso llvmlistbot at llvm.org
Tue Nov 25 07:21:57 PST 2025


================
@@ -2320,12 +2326,52 @@ genParallelOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
 
 static mlir::omp::ScanOp
 genScanOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
-          semantics::SemanticsContext &semaCtx, mlir::Location loc,
-          const ConstructQueue &queue, ConstructQueue::const_iterator item) {
+          semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
+          mlir::Location loc, const ConstructQueue &queue,
+          ConstructQueue::const_iterator item) {
   mlir::omp::ScanOperands clauseOps;
   genScanClauses(converter, semaCtx, item->clauses, loc, clauseOps);
-  return mlir::omp::ScanOp::create(converter.getFirOpBuilder(),
-                                   converter.getCurrentLocation(), clauseOps);
+  mlir::omp::ScanOp scanOp = mlir::omp::ScanOp::create(
+      converter.getFirOpBuilder(), converter.getCurrentLocation(), clauseOps);
+
+  /// Scan redution is not implemented with nested workshare loops, linear
+  /// clause, tiling
+  mlir::omp::LoopNestOp loopNestOp =
+      scanOp->getParentOfType<mlir::omp::LoopNestOp>();
+  mlir::omp::WsloopOp wsLoopOp = scanOp->getParentOfType<mlir::omp::WsloopOp>();
----------------
skatrak wrote:

I'm not sure that this is exactly what we want to get here. As per the spec, `scan` can be attached to a `simd`, worksharing-loop or composite combining them. That means that what we probably want is something like:
```suggestion
  llvm::SmallVector<mlir::omp::LoopWrapperInterface> loopWrappers;
  loopNestOp.gatherWrappers(loopWrappers);
  mlir::Operation *loopWrapperOp = loopWrappers.front()->getOperation();
  // if (llvm::isa<mlir::omp::SimdOp>(loopWrapperOp)) TODO(loc, "unsupported simd?");
  // if (loopWrappers.size() > 1) TODO(loc, "unsupported composite?");
  auto wsloopOp = llvm::cast<mlir::omp::WsloopOp>(loopWrapperOp);
```
Also, without that change or something similar, we would base checks below on the wrong loop wrapper in a case like this:
```mlir
omp.wsloop ... {
  omp.loop_nest ... {
    ...
    omp.simd ... {
      omp.loop_nest ... {
        // scan here: wsLoopOp would be the one wrapping the parent loop, rather than this one.
        omp.yield
      }
    }
    ...
    omp.yield
  }
}
```

https://github.com/llvm/llvm-project/pull/167031


More information about the Mlir-commits mailing list