[flang-commits] [flang] Allow do concurrent inside cuf kernel directive (PR #127693)

Valentin Clement バレンタイン クレメン via flang-commits flang-commits at lists.llvm.org
Tue Feb 18 16:57:44 PST 2025


================
@@ -3074,50 +3074,135 @@ class FirConverter : public Fortran::lower::AbstractConverter {
     llvm::SmallVector<mlir::Value> ivValues;
     Fortran::lower::pft::Evaluation *loopEval =
         &getEval().getFirstNestedEvaluation();
-    for (unsigned i = 0; i < nestedLoops; ++i) {
-      const Fortran::parser::LoopControl *loopControl;
-      mlir::Location crtLoc = loc;
-      if (i == 0) {
-        loopControl = &*outerDoConstruct->GetLoopControl();
-        crtLoc =
-            genLocation(Fortran::parser::FindSourceLocation(outerDoConstruct));
-      } else {
-        auto *doCons = loopEval->getIf<Fortran::parser::DoConstruct>();
-        assert(doCons && "expect do construct");
-        loopControl = &*doCons->GetLoopControl();
-        crtLoc = genLocation(Fortran::parser::FindSourceLocation(*doCons));
+    bool isDoConcurrent = outerDoConstruct->IsDoConcurrent();
+    if (isDoConcurrent) {
+      // Handle DO CONCURRENT
+      locs.push_back(
+          genLocation(Fortran::parser::FindSourceLocation(outerDoConstruct)));
+      const Fortran::parser::LoopControl *loopControl =
+          &*outerDoConstruct->GetLoopControl();
+      const auto &concurrent =
+          std::get<Fortran::parser::LoopControl::Concurrent>(loopControl->u);
+
+      if (!std::get<std::list<Fortran::parser::LocalitySpec>>(concurrent.t)
+               .empty())
+        TODO(loc, "DO CONCURRENT with locality spec");
+
+      const auto &concurrentHeader =
+          std::get<Fortran::parser::ConcurrentHeader>(concurrent.t);
+      const auto &controls =
+          std::get<std::list<Fortran::parser::ConcurrentControl>>(
+              concurrentHeader.t);
+
+      for (const auto &control : controls) {
+        auto lb = fir::getBase(genExprValue(
+            *Fortran::semantics::GetExpr(std::get<1>(control.t)), stmtCtx));
+        auto ub = fir::getBase(genExprValue(
+            *Fortran::semantics::GetExpr(std::get<2>(control.t)), stmtCtx));
+        mlir::Value step;
+
+        if (const auto &expr =
+                std::get<std::optional<Fortran::parser::ScalarIntExpr>>(
+                    control.t)) {
+          step = fir::getBase(
+              genExprValue(*Fortran::semantics::GetExpr(*expr), stmtCtx));
+        } else {
+          step = builder->create<mlir::arith::ConstantIndexOp>(
+              loc, 1); // Use index type directly
+        }
+
+        // Ensure lb, ub, and step are of index type using fir.convert
+        auto indexType = builder->getIndexType();
+        if (lb.getType() != indexType) {
+          lb = builder->create<fir::ConvertOp>(loc, indexType, lb);
+        }
+        if (ub.getType() != indexType) {
+          ub = builder->create<fir::ConvertOp>(loc, indexType, ub);
+        }
+        if (step.getType() != indexType) {
+          step = builder->create<fir::ConvertOp>(loc, indexType, step);
+        }
----------------
clementval wrote:

You can simplify this an always add the convert op. It will get removed if the from and to type are identical. 

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


More information about the flang-commits mailing list