[flang-commits] [flang] [flang][acc] Implement cache directive lowering (PR #174897)

Valentin Clement バレンタイン クレメン via flang-commits flang-commits at lists.llvm.org
Thu Jan 8 10:19:22 PST 2026


================
@@ -4837,12 +4837,180 @@ genACC(Fortran::lower::AbstractConverter &converter,
       atomicConstruct.u);
 }
 
+/// Generate acc.bounds for cache directive. Handles:
+/// - Single element: arr(i) or arr(5)
+/// - Full range: arr(lower:upper)
+/// - Missing upper: arr(lower:) - uses array's upper bound
+/// - Missing lower: arr(:upper) - uses array's lower bound
+static void
+genCacheBounds(Fortran::lower::AbstractConverter &converter,
+               Fortran::semantics::SemanticsContext &semanticsContext,
+               Fortran::lower::StatementContext &stmtCtx,
+               const Fortran::parser::AccObject &accObject,
+               std::stringstream &asFortran,
+               llvm::SmallVectorImpl<mlir::Value> &bounds) {
+  fir::FirOpBuilder &builder = converter.getFirOpBuilder();
+  mlir::Location loc = converter.getCurrentLocation();
+  mlir::Type idxTy = builder.getIndexType();
+  mlir::Type boundTy = builder.getType<mlir::acc::DataBoundsType>();
+
+  Fortran::evaluate::ExpressionAnalyzer ea{semanticsContext};
+  Fortran::semantics::Symbol &symbol = getSymbolFromAccObject(accObject);
+
+  std::optional<Fortran::evaluate::DataRef> dataRef;
+  Fortran::semantics::MaybeExpr designator = Fortran::common::visit(
+      [&](auto &&s) { return ea.Analyze(s); }, accObject.u);
+  if (designator)
+    dataRef = Fortran::evaluate::ExtractDataRef(*designator);
+
+  if (!dataRef)
+    return;
+
+  auto *arrayRef = std::get_if<Fortran::evaluate::ArrayRef>(&dataRef->u);
+  if (!arrayRef)
+    return;
+
+  // Helper to generate index value from expression.
+  // Optimize for compile-time constants to generate index type directly.
+  auto genIndex =
+      [&](const Fortran::semantics::MaybeExpr &expr) -> mlir::Value {
+    if (auto constVal = Fortran::evaluate::ToInt64(*expr))
+      return builder.createIntegerConstant(loc, idxTy, *constVal);
+    return builder.createConvert(
+        loc, idxTy, fir::getBase(converter.genExprValue(loc, *expr, stmtCtx)));
+  };
+
+  const auto &subscripts = arrayRef->subscript();
+  int dimension = 0;
+  mlir::Value one = builder.createIntegerConstant(loc, idxTy, 1);
+  fir::ExtendedValue dataExv = converter.getSymbolExtendedValue(symbol);
+
+  for (const auto &subscript : subscripts) {
+    if (dimension != 0)
+      asFortran << ',';
+
+    mlir::Value lbound, extent;
+    mlir::Value arrayLb =
+        fir::factory::readLowerBound(builder, loc, dataExv, dimension, one);
+    mlir::Value arrayExtent =
+        fir::factory::readExtent(builder, loc, dataExv, dimension);
+
+    const auto *triplet = std::get_if<Fortran::evaluate::Triplet>(&subscript.u);
+
+    if (triplet) {
+      asFortran << ':';
+
+      // OpenACC spec requires at least one of lower or upper bound to be
+      // specified: arr(lower:upper), arr(lower:), or arr(:upper).
+      // arr(:) with both bounds missing is not allowed.
+      Fortran::semantics::MaybeExpr lowerExpr =
+          Fortran::evaluate::AsGenericExpr(triplet->lower());
+      Fortran::semantics::MaybeExpr upperExpr =
+          Fortran::evaluate::AsGenericExpr(triplet->upper());
+
+      if (!lowerExpr && !upperExpr) {
+        llvm::report_fatal_error("OpenACC cache directive requires at least "
+                                 "one bound to be specified for array section");
+      }
----------------
clementval wrote:

no braces

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


More information about the flang-commits mailing list