[flang-commits] [flang] [flang][Lower] Implement lowering for new expression kind used in explicit-shape-bounds-spec (PR #215403)

via flang-commits flang-commits at lists.llvm.org
Tue Sep 22 00:15:47 PDT 2026


================
@@ -1870,6 +1871,71 @@ static bool lowerToBoxValue(const Fortran::semantics::Symbol &sym,
   return false;
 }
 
+/// When every explicit bound on the requested side (lower or upper) of an
+/// array is a RankOneBoundElement, they all extract elements from the same
+/// rank-1 base expression -- that is how the front end builds them (see
+/// ArraySpecAnalyzer).  Evaluate that base exactly once and return the
+/// per-dimension element values, converted to \p idxTy, so a call-valued base
+/// such as `mb(n)` in `real :: a(mb(n))` is not re-evaluated for every
+/// dimension.  Returns an empty vector (so the caller lowers each bound
+/// independently) when the bounds are not rank-1 bound elements.
+static llvm::SmallVector<mlir::Value> lowerSharedRankOneBounds(
+    Fortran::lower::AbstractConverter &converter, mlir::Location loc,
+    const Fortran::lower::BoxAnalyzer &box, bool upper, mlir::Type idxTy,
+    Fortran::lower::SymMap &symMap, Fortran::lower::StatementContext &stmtCtx) {
+  const Fortran::evaluate::RankOneBoundElement *shared = nullptr;
+  for (const Fortran::semantics::ShapeSpec *spec : box.dynamicBound()) {
+    const Fortran::semantics::Bound &bound =
+        upper ? spec->ubound() : spec->lbound();
+    const auto &explicitBound = bound.GetExplicit();
+    if (!explicitBound)
+      return {};
+    if (const auto *robe = Fortran::evaluate::UnwrapExpr<
+            Fortran::evaluate::RankOneBoundElement>(*explicitBound)) {
+      if (!shared)
+        shared = robe;
+    } else {
+      return {};
----------------
MattPD wrote:

Confirmed: Scalar lower and upper bounds are now evaluated once when broadcast.

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


More information about the flang-commits mailing list