Skip to content

Conversation

@razvanlupusoru
Copy link
Contributor

Add utilities in OpenACCUtilsTiling.h/.cpp to support tiling transformations on acc.loop operations:

  • uncollapseLoops: Expand collapsed loops with multiple IVs into nested loop structures when tile count exceeds collapse count
  • tileACCLoops: Transform loop nests into tile and element loops based on provided tile sizes, with automatic resolution of unknown tile sizes (tile(*) represented as -1)

These utilities prepare for the ACCLoopTiling pass which handles the OpenACC loop tile directive.

Add utilities in OpenACCUtilsTiling.h/.cpp to support tiling
transformations on acc.loop operations:

- uncollapseLoops: Expand collapsed loops with multiple IVs into
  nested loop structures when tile count exceeds collapse count
- tileACCLoops: Transform loop nests into tile and element loops
  based on provided tile sizes, with automatic resolution of
  unknown tile sizes (tile(*) represented as -1)

These utilities prepare for the ACCLoopTiling pass which handles
the OpenACC loop tile directive.
@llvmbot
Copy link
Member

llvmbot commented Dec 9, 2025

@llvm/pr-subscribers-mlir

@llvm/pr-subscribers-mlir-openacc

Author: Razvan Lupusoru (razvanlupusoru)

Changes

Add utilities in OpenACCUtilsTiling.h/.cpp to support tiling transformations on acc.loop operations:

  • uncollapseLoops: Expand collapsed loops with multiple IVs into nested loop structures when tile count exceeds collapse count
  • tileACCLoops: Transform loop nests into tile and element loops based on provided tile sizes, with automatic resolution of unknown tile sizes (tile(*) represented as -1)

These utilities prepare for the ACCLoopTiling pass which handles the OpenACC loop tile directive.


Patch is 31.65 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/171490.diff

5 Files Affected:

  • (added) mlir/include/mlir/Dialect/OpenACC/OpenACCUtilsTiling.h (+83)
  • (modified) mlir/lib/Dialect/OpenACC/Utils/CMakeLists.txt (+3)
  • (added) mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsTiling.cpp (+313)
  • (modified) mlir/unittests/Dialect/OpenACC/CMakeLists.txt (+1)
  • (added) mlir/unittests/Dialect/OpenACC/OpenACCUtilsTilingTest.cpp (+349)
diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCUtilsTiling.h b/mlir/include/mlir/Dialect/OpenACC/OpenACCUtilsTiling.h
new file mode 100644
index 0000000000000..3152526cc0582
--- /dev/null
+++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCUtilsTiling.h
@@ -0,0 +1,83 @@
+//===- OpenACCUtilsTiling.h - OpenACC Loop Tiling Utilities -----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains utility functions for tiling OpenACC loops.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_DIALECT_OPENACC_OPENACCUTILSTILING_H_
+#define MLIR_DIALECT_OPENACC_OPENACCUTILSTILING_H_
+
+#include "mlir/Dialect/OpenACC/OpenACC.h"
+#include "mlir/IR/PatternMatch.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace mlir {
+namespace acc {
+
+/// Uncollapse tile loops with multiple IVs and collapseCount < tileCount.
+/// This is used to prepare loops for tiling when the collapse count is less
+/// than the tile count.
+///
+/// \param origLoop The original loop operation to uncollapse.
+/// \param tileCount The number of tile dimensions.
+/// \param collapseCount The collapse count from the original loop.
+/// \param rewriter The rewriter to use for modifications.
+/// \return A vector of uncollapsed loop operations.
+llvm::SmallVector<mlir::acc::LoopOp>
+uncollapseLoops(mlir::acc::LoopOp origLoop, unsigned tileCount,
+                unsigned collapseCount, mlir::RewriterBase &rewriter);
+
+/// Tile ACC loops according to the given tile sizes.
+///
+/// Tiling a 2-level nested loop will create two 'tile' loops containing two
+/// 'element' loops. The transformation looks like:
+///
+/// Before Tiling:
+/// \code
+/// #pragma acc loop tile(tile_size1, tile_size2)
+///  for (i = lb1; i < ub1; i += step1) { // original loop
+///    for (j = lb2; j < ub2; j += step2) {
+///      a[i,j] = i + j;
+///    }
+///  }
+/// \endcode
+///
+/// After Tiling:
+/// \code
+///  for (i = lb1; i < ub1; i += (step1 * tile_size1)) { // tile loop 1
+///    for (j = lb2; j < ub2; j += (step2 * tile_size2)) { // tile loop 2
+///      for (ii = i; ii < min(ub1, (step1 * tile_size1) + i); ii += step1) {
+///      // element loop 1
+///        for (jj = j; jj < min(ub2, (step2 * tile_size2) + j); jj += step2)
+///        { // element loop 2
+///          a[ii,jj] = i + j;
+///        }
+///      }
+///    }
+///  }
+/// \endcode
+///
+/// Unknown tile sizes (represented as -1 in OpenACC for `tile(*)`) are
+/// resolved to the provided default tile size.
+///
+/// \param tileLoops The loops to tile (outermost first).
+/// \param tileSizes The tile sizes for each dimension. Values of -1 are
+///        treated as unknown and resolved to defaultTileSize.
+/// \param defaultTileSize The default tile size to use for unknown (*) tiles.
+/// \param rewriter The rewriter to use for modifications.
+/// \return The outermost loop after tiling.
+mlir::acc::LoopOp tileACCLoops(llvm::SmallVector<mlir::acc::LoopOp> &tileLoops,
+                               const llvm::SmallVector<mlir::Value> &tileSizes,
+                               int32_t defaultTileSize,
+                               mlir::RewriterBase &rewriter);
+
+} // namespace acc
+} // namespace mlir
+
+#endif // MLIR_DIALECT_OPENACC_OPENACCUTILSTILING_H_
diff --git a/mlir/lib/Dialect/OpenACC/Utils/CMakeLists.txt b/mlir/lib/Dialect/OpenACC/Utils/CMakeLists.txt
index 68e124625921f..c3de4f7e3e282 100644
--- a/mlir/lib/Dialect/OpenACC/Utils/CMakeLists.txt
+++ b/mlir/lib/Dialect/OpenACC/Utils/CMakeLists.txt
@@ -1,4 +1,5 @@
 add_mlir_dialect_library(MLIROpenACCUtils
+  OpenACCUtilsTiling.cpp
   OpenACCUtils.cpp
 
   ADDITIONAL_HEADER_DIRS
@@ -14,7 +15,9 @@ add_mlir_dialect_library(MLIROpenACCUtils
   MLIROpenACCTypeInterfacesIncGen
 
   LINK_LIBS PUBLIC
+  MLIRArithDialect
   MLIROpenACCDialect
   MLIRIR
   MLIRSupport
+  MLIRTransformUtils
 )
diff --git a/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsTiling.cpp b/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsTiling.cpp
new file mode 100644
index 0000000000000..f939ec1c58cfd
--- /dev/null
+++ b/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsTiling.cpp
@@ -0,0 +1,313 @@
+//===- OpenACCUtilsTiling.cpp - OpenACC Loop Tiling Utilities -------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains utility functions for tiling OpenACC loops.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Dialect/OpenACC/OpenACCUtilsTiling.h"
+
+#include "mlir/Dialect/Arith/IR/Arith.h"
+#include "mlir/Dialect/OpenACC/OpenACC.h"
+#include "mlir/Dialect/Utils/StaticValueUtils.h"
+#include "mlir/Transforms/RegionUtils.h"
+
+// Resolve unknown tile sizes (represented as -1 for tile(*)) to the default.
+static mlir::Value resolveUnknownTileSize(mlir::Value tileSize,
+                                          int32_t defaultTileSize,
+                                          mlir::RewriterBase &rewriter,
+                                          mlir::Location loc) {
+  auto constVal = mlir::getConstantIntValue(tileSize);
+  if (constVal && *constVal < 0) {
+    return mlir::arith::ConstantOp::create(
+        rewriter, loc, rewriter.getI32Type(),
+        rewriter.getI32IntegerAttr(defaultTileSize));
+  }
+  return tileSize;
+}
+
+// Remove vector/worker attributes from loop
+static void removeWorkerVectorFromLoop(mlir::acc::LoopOp loop) {
+  if (loop.hasVector() || loop.getVectorValue()) {
+    loop.removeVectorAttr();
+    loop.removeVectorOperandsDeviceTypeAttr();
+  } else if (loop.hasWorker() || loop.getWorkerValue()) {
+    loop.removeWorkerAttr();
+    loop.removeWorkerNumOperandsDeviceTypeAttr();
+  }
+}
+
+// Create a new ACC loop with new steps, lb, ub from original loop
+static mlir::acc::LoopOp
+createACCLoopFromOriginal(mlir::acc::LoopOp origLoop,
+                          mlir::RewriterBase &rewriter, mlir::ValueRange lb,
+                          mlir::ValueRange ub, mlir::ValueRange step,
+                          mlir::DenseBoolArrayAttr inclusiveUBAttr,
+                          mlir::acc::CombinedConstructsTypeAttr combinedAttr,
+                          mlir::Location loc, bool preserveCollapse) {
+  mlir::ArrayAttr collapseAttr = mlir::ArrayAttr{};
+  mlir::ArrayAttr collapseDeviceTypeAttr = mlir::ArrayAttr{};
+  if (preserveCollapse) {
+    collapseAttr = origLoop.getCollapseAttr();
+    collapseDeviceTypeAttr = origLoop.getCollapseDeviceTypeAttr();
+  }
+  auto newLoop = mlir::acc::LoopOp::create(
+      rewriter, loc, origLoop->getResultTypes(), lb, ub, step, inclusiveUBAttr,
+      collapseAttr, collapseDeviceTypeAttr, origLoop.getGangOperands(),
+      origLoop.getGangOperandsArgTypeAttr(),
+      origLoop.getGangOperandsSegmentsAttr(),
+      origLoop.getGangOperandsDeviceTypeAttr(), origLoop.getWorkerNumOperands(),
+      origLoop.getWorkerNumOperandsDeviceTypeAttr(),
+      origLoop.getVectorOperands(), origLoop.getVectorOperandsDeviceTypeAttr(),
+      origLoop.getSeqAttr(), origLoop.getIndependentAttr(),
+      origLoop.getAuto_Attr(), origLoop.getGangAttr(), origLoop.getWorkerAttr(),
+      origLoop.getVectorAttr(), mlir::ValueRange{}, mlir::DenseI32ArrayAttr{},
+      mlir::ArrayAttr{}, origLoop.getCacheOperands(),
+      origLoop.getPrivateOperands(), origLoop.getFirstprivateOperands(),
+      origLoop.getReductionOperands(), combinedAttr);
+  return newLoop;
+}
+
+// Create inner loop inside input loop
+static mlir::acc::LoopOp
+createInnerLoop(mlir::acc::LoopOp inputLoop, mlir::RewriterBase &rewriter,
+                mlir::ValueRange lb, mlir::ValueRange ub, mlir::ValueRange step,
+                mlir::DenseBoolArrayAttr inclusiveUBAttr, mlir::Location loc) {
+  mlir::acc::LoopOp elementLoop = createACCLoopFromOriginal(
+      inputLoop, rewriter, lb, ub, step, inclusiveUBAttr,
+      mlir::acc::CombinedConstructsTypeAttr{}, loc, /*preserveCollapse*/ false);
+
+  // Remove gang/worker attributes from inner loops
+  rewriter.startOpModification(elementLoop);
+  if (inputLoop.hasGang() ||
+      inputLoop.getGangValue(mlir::acc::GangArgType::Num) ||
+      inputLoop.getGangValue(mlir::acc::GangArgType::Dim) ||
+      inputLoop.getGangValue(mlir::acc::GangArgType::Static)) {
+    elementLoop.removeGangAttr();
+    elementLoop.removeGangOperandsArgTypeAttr();
+    elementLoop.removeGangOperandsSegmentsAttr();
+    elementLoop.removeGangOperandsDeviceTypeAttr();
+  }
+  if (inputLoop.hasVector() || inputLoop.getVectorValue()) {
+    elementLoop.removeWorkerAttr();
+    elementLoop.removeWorkerNumOperandsDeviceTypeAttr();
+  }
+  rewriter.finalizeOpModification(elementLoop);
+
+  // Create empty block in elementLoop and add IV argument
+  mlir::Block *blk = rewriter.createBlock(&elementLoop.getRegion(),
+                                          elementLoop.getRegion().begin());
+  rewriter.setInsertionPointToEnd(blk);
+  mlir::acc::YieldOp::create(rewriter, loc);
+  elementLoop.getBody().addArgument(
+      inputLoop.getBody().getArgument(0).getType(), loc);
+
+  return elementLoop;
+}
+
+// Move ops from source to target Loop and replace uses of IVs
+static void moveOpsAndReplaceIVs(mlir::acc::LoopOp sourceLoop,
+                                 mlir::acc::LoopOp targetLoop,
+                                 llvm::ArrayRef<mlir::Value> newIVs,
+                                 llvm::ArrayRef<mlir::Value> origIVs,
+                                 size_t nOps, mlir::RewriterBase &rewriter) {
+  // Move ops from source to target loop [begin, begin + nOps - 1)
+  mlir::Block::iterator begin = sourceLoop.getBody().begin();
+  targetLoop.getBody().getOperations().splice(
+      targetLoop.getBody().getOperations().begin(),
+      sourceLoop.getBody().getOperations(), begin, std::next(begin, nOps - 1));
+
+  // Replace uses of origIV with newIV
+  for (auto [i, newIV] : llvm::enumerate(newIVs))
+    mlir::replaceAllUsesInRegionWith(origIVs[i], newIV, targetLoop.getRegion());
+}
+
+mlir::acc::LoopOp
+mlir::acc::tileACCLoops(llvm::SmallVector<mlir::acc::LoopOp> &tileLoops,
+                        const llvm::SmallVector<mlir::Value> &tileSizes,
+                        int32_t defaultTileSize, mlir::RewriterBase &rewriter) {
+  // Tile collapsed and/or nested loops
+  mlir::acc::LoopOp outerLoop = tileLoops[0];
+  const mlir::Location loc = outerLoop.getLoc();
+
+  // Resolve unknown tile sizes (tile(*) represented as -1)
+  llvm::SmallVector<mlir::Value> resolvedTileSizes;
+  rewriter.setInsertionPoint(outerLoop);
+  for (mlir::Value tileSize : tileSizes) {
+    resolvedTileSizes.push_back(
+        resolveUnknownTileSize(tileSize, defaultTileSize, rewriter, loc));
+  }
+
+  mlir::acc::LoopOp innerLoop = tileLoops[tileLoops.size() - 1];
+  llvm::SmallVector<mlir::Value, 3> origIVs;
+  llvm::SmallVector<mlir::Value, 3> origSteps;
+  llvm::SmallVector<mlir::Value, 3> origUBs;
+  llvm::SmallVector<mlir::Value, 3> newSteps;
+  llvm::SmallVector<mlir::Value, 3> newUBs;
+  llvm::SmallVector<mlir::Value, 3> newIVs;
+  size_t nOps = innerLoop.getBody().getOperations().size();
+
+  // Extract original inclusiveUBs
+  llvm::SmallVector<bool> inclusiveUBs;
+  for (auto tileLoop : tileLoops) {
+    for (auto [j, step] : llvm::enumerate(tileLoop.getStep())) {
+      // inclusiveUBs are present on the IR from Fortran frontend for DO loops
+      // but might not be present from other frontends (python)
+      // So check if it exists
+      if (tileLoop.getInclusiveUpperboundAttr())
+        inclusiveUBs.push_back(
+            tileLoop.getInclusiveUpperboundAttr().asArrayRef()[j]);
+      else
+        inclusiveUBs.push_back(false);
+    }
+  }
+
+  // Extract original ivs, UBs, steps, and calculate new steps
+  rewriter.setInsertionPoint(outerLoop);
+  for (auto [i, tileLoop] : llvm::enumerate(tileLoops)) {
+    for (auto arg : tileLoop.getBody().getArguments())
+      origIVs.push_back(arg);
+    for (auto ub : tileLoop.getUpperbound())
+      origUBs.push_back(ub);
+
+    llvm::SmallVector<mlir::Value, 3> currentLoopSteps;
+    for (auto [j, step] : llvm::enumerate(tileLoop.getStep())) {
+      origSteps.push_back(step);
+      if (i + j >= resolvedTileSizes.size()) {
+        currentLoopSteps.push_back(step);
+      } else {
+        mlir::Value tileSize = resolvedTileSizes[i + j];
+        auto newLoopStep =
+            mlir::arith::MulIOp::create(rewriter, loc, step, tileSize);
+        currentLoopSteps.push_back(newLoopStep);
+        newSteps.push_back(newLoopStep);
+      }
+    }
+
+    rewriter.startOpModification(tileLoop);
+    tileLoop.getStepMutable().clear();
+    tileLoop.getStepMutable().append(currentLoopSteps);
+    rewriter.finalizeOpModification(tileLoop);
+  }
+
+  // Calculate new upper bounds for element loops
+  for (size_t i = 0; i < newSteps.size(); i++) {
+    rewriter.setInsertionPoint(innerLoop.getBody().getTerminator());
+    // UpperBound: min(origUB, origIV+(originalStep*tile_size))
+    auto stepped =
+        mlir::arith::AddIOp::create(rewriter, loc, origIVs[i], newSteps[i]);
+    mlir::Value newUB = stepped;
+    if (inclusiveUBs[i]) {
+      // Handle InclusiveUB
+      // UpperBound: min(origUB, origIV+(originalStep*tile_size - 1))
+      auto c1 = mlir::arith::ConstantOp::create(
+          rewriter, loc, newSteps[i].getType(),
+          rewriter.getIntegerAttr(newSteps[i].getType(), 1));
+      newUB = mlir::arith::SubIOp::create(rewriter, loc, stepped, c1);
+    }
+    newUBs.push_back(
+        mlir::arith::MinSIOp::create(rewriter, loc, origUBs[i], newUB));
+  }
+
+  // Create and insert nested elementLoopOps before terminator of outer loopOp
+  mlir::acc::LoopOp currentLoop = innerLoop;
+  for (size_t i = 0; i < resolvedTileSizes.size(); i++) {
+    rewriter.setInsertionPoint(currentLoop.getBody().getTerminator());
+    mlir::DenseBoolArrayAttr inclusiveUBAttr = mlir::DenseBoolArrayAttr{};
+    if (inclusiveUBs[i])
+      inclusiveUBAttr = rewriter.getDenseBoolArrayAttr({true});
+
+    mlir::acc::LoopOp elementLoop =
+        createInnerLoop(innerLoop, rewriter, mlir::ValueRange{origIVs[i]},
+                        mlir::ValueRange{newUBs[i]},
+                        mlir::ValueRange{origSteps[i]}, inclusiveUBAttr, loc);
+
+    // Remove vector/worker attributes from inner element loops except
+    // outermost element loop
+    if (i > 0) {
+      rewriter.startOpModification(elementLoop);
+      removeWorkerVectorFromLoop(elementLoop);
+      rewriter.finalizeOpModification(elementLoop);
+    }
+    newIVs.push_back(elementLoop.getBody().getArgument(0));
+    currentLoop = elementLoop;
+  }
+
+  // Remove vector/worker attributes from outer tile loops
+  for (auto tileLoop : tileLoops) {
+    rewriter.startOpModification(tileLoop);
+    removeWorkerVectorFromLoop(tileLoop);
+    rewriter.finalizeOpModification(tileLoop);
+  }
+
+  // Move ops from inner tile loop to inner element loop and replace IV uses
+  moveOpsAndReplaceIVs(innerLoop, currentLoop, newIVs, origIVs, nOps, rewriter);
+
+  return outerLoop;
+}
+
+llvm::SmallVector<mlir::acc::LoopOp>
+mlir::acc::uncollapseLoops(mlir::acc::LoopOp origLoop, unsigned tileCount,
+                           unsigned collapseCount,
+                           mlir::RewriterBase &rewriter) {
+  llvm::SmallVector<mlir::acc::LoopOp, 3> newLoops;
+  llvm::SmallVector<mlir::Value, 3> newIVs;
+  mlir::Location loc = origLoop.getLoc();
+  llvm::SmallVector<bool> newInclusiveUBs;
+  llvm::SmallVector<mlir::Value, 3> lbs, ubs, steps;
+  for (unsigned i = 0; i < collapseCount; i++) {
+    // inclusiveUpperbound attribute might not be set, default to false
+    bool inclusiveUB = false;
+    if (origLoop.getInclusiveUpperboundAttr())
+      inclusiveUB = origLoop.getInclusiveUpperboundAttr().asArrayRef()[i];
+    newInclusiveUBs.push_back(inclusiveUB);
+    lbs.push_back(origLoop.getLowerbound()[i]);
+    ubs.push_back(origLoop.getUpperbound()[i]);
+    steps.push_back(origLoop.getStep()[i]);
+  }
+  mlir::acc::LoopOp outerLoop = createACCLoopFromOriginal(
+      origLoop, rewriter, lbs, ubs, steps,
+      rewriter.getDenseBoolArrayAttr(newInclusiveUBs),
+      origLoop.getCombinedAttr(), loc, /*preserveCollapse*/ true);
+  mlir::Block *blk = rewriter.createBlock(&outerLoop.getRegion(),
+                                          outerLoop.getRegion().begin());
+  rewriter.setInsertionPointToEnd(blk);
+  mlir::acc::YieldOp::create(rewriter, loc);
+  for (unsigned i = 0; i < collapseCount; i++) {
+    outerLoop.getBody().addArgument(origLoop.getBody().getArgument(i).getType(),
+                                    loc);
+    newIVs.push_back(outerLoop.getBody().getArgument(i));
+  }
+  newLoops.push_back(outerLoop);
+
+  mlir::acc::LoopOp currentLoopOp = outerLoop;
+  for (unsigned i = collapseCount; i < tileCount; i++) {
+    rewriter.setInsertionPoint(currentLoopOp.getBody().getTerminator());
+    bool inclusiveUB = false;
+    if (origLoop.getInclusiveUpperboundAttr())
+      inclusiveUB = origLoop.getInclusiveUpperboundAttr().asArrayRef()[i];
+    mlir::DenseBoolArrayAttr inclusiveUBAttr =
+        rewriter.getDenseBoolArrayAttr({inclusiveUB});
+    mlir::acc::LoopOp innerLoop = createInnerLoop(
+        origLoop, rewriter, mlir::ValueRange{origLoop.getLowerbound()[i]},
+        mlir::ValueRange{origLoop.getUpperbound()[i]},
+        mlir::ValueRange{origLoop.getStep()[i]}, inclusiveUBAttr, loc);
+    newIVs.push_back(innerLoop.getBody().getArgument(0));
+    newLoops.push_back(innerLoop);
+    currentLoopOp = innerLoop;
+  }
+  // Move ops from origLoop to innermost loop and replace uses of IVs
+  size_t nOps = origLoop.getBody().getOperations().size();
+  llvm::SmallVector<mlir::Value, 3> origIVs;
+  for (auto arg : origLoop.getBody().getArguments())
+    origIVs.push_back(arg);
+  moveOpsAndReplaceIVs(origLoop, currentLoopOp, newIVs, origIVs, nOps,
+                       rewriter);
+
+  return newLoops;
+}
diff --git a/mlir/unittests/Dialect/OpenACC/CMakeLists.txt b/mlir/unittests/Dialect/OpenACC/CMakeLists.txt
index c8c2bb96b0539..060c8b8d2679d 100644
--- a/mlir/unittests/Dialect/OpenACC/CMakeLists.txt
+++ b/mlir/unittests/Dialect/OpenACC/CMakeLists.txt
@@ -2,6 +2,7 @@ add_mlir_unittest(MLIROpenACCTests
   OpenACCOpsTest.cpp
   OpenACCOpsInterfacesTest.cpp
   OpenACCUtilsTest.cpp
+  OpenACCUtilsTilingTest.cpp
 )
 mlir_target_link_libraries(MLIROpenACCTests
   PRIVATE
diff --git a/mlir/unittests/Dialect/OpenACC/OpenACCUtilsTilingTest.cpp b/mlir/unittests/Dialect/OpenACC/OpenACCUtilsTilingTest.cpp
new file mode 100644
index 0000000000000..287af9fafd5b7
--- /dev/null
+++ b/mlir/unittests/Dialect/OpenACC/OpenACCUtilsTilingTest.cpp
@@ -0,0 +1,349 @@
+//===- OpenACCUtilsTilingTest.cpp - Unit tests for loop tiling utilities --===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Dialect/OpenACC/OpenACCUtilsTiling.h"
+#include "mlir/Dialect/Arith/IR/Arith.h"
+#include "mlir/Dialect/Func/IR/FuncOps.h"
+#include "mlir/Dialect/MemRef/IR/MemRef.h"
+#include "mlir/Dialect/OpenACC/OpenACC.h"
+#include "mlir/IR/BuiltinOps.h"
+#include "mlir/IR/BuiltinTypes.h"
+#include "mlir/IR/MLIRContext.h"
+#include "mlir/IR/OwningOpRef.h"
+#include "gtest/gtest.h"
+
+using namespace mlir;
+using namespace mlir::acc;
+
+//===----------------------------------------------------------------------===//
+// Test Fixture
+//===----------------------------------------------------------------------===//
+
+class OpenACCUtilsTilingTest : public ::testing::Test {
+protected:
+  OpenACCUtilsTilingTest() : b(&context), loc(UnknownLoc::get(&context)) {
+    context.loadDialect<acc::OpenACCDialect, arith::ArithDialect,
+                        memref::MemRefDialect, func::FuncDialect>(...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Dec 9, 2025

@llvm/pr-subscribers-openacc

Author: Razvan Lupusoru (razvanlupusoru)

Changes

Add utilities in OpenACCUtilsTiling.h/.cpp to support tiling transformations on acc.loop operations:

  • uncollapseLoops: Expand collapsed loops with multiple IVs into nested loop structures when tile count exceeds collapse count
  • tileACCLoops: Transform loop nests into tile and element loops based on provided tile sizes, with automatic resolution of unknown tile sizes (tile(*) represented as -1)

These utilities prepare for the ACCLoopTiling pass which handles the OpenACC loop tile directive.


Patch is 31.65 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/171490.diff

5 Files Affected:

  • (added) mlir/include/mlir/Dialect/OpenACC/OpenACCUtilsTiling.h (+83)
  • (modified) mlir/lib/Dialect/OpenACC/Utils/CMakeLists.txt (+3)
  • (added) mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsTiling.cpp (+313)
  • (modified) mlir/unittests/Dialect/OpenACC/CMakeLists.txt (+1)
  • (added) mlir/unittests/Dialect/OpenACC/OpenACCUtilsTilingTest.cpp (+349)
diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCUtilsTiling.h b/mlir/include/mlir/Dialect/OpenACC/OpenACCUtilsTiling.h
new file mode 100644
index 0000000000000..3152526cc0582
--- /dev/null
+++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCUtilsTiling.h
@@ -0,0 +1,83 @@
+//===- OpenACCUtilsTiling.h - OpenACC Loop Tiling Utilities -----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains utility functions for tiling OpenACC loops.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_DIALECT_OPENACC_OPENACCUTILSTILING_H_
+#define MLIR_DIALECT_OPENACC_OPENACCUTILSTILING_H_
+
+#include "mlir/Dialect/OpenACC/OpenACC.h"
+#include "mlir/IR/PatternMatch.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace mlir {
+namespace acc {
+
+/// Uncollapse tile loops with multiple IVs and collapseCount < tileCount.
+/// This is used to prepare loops for tiling when the collapse count is less
+/// than the tile count.
+///
+/// \param origLoop The original loop operation to uncollapse.
+/// \param tileCount The number of tile dimensions.
+/// \param collapseCount The collapse count from the original loop.
+/// \param rewriter The rewriter to use for modifications.
+/// \return A vector of uncollapsed loop operations.
+llvm::SmallVector<mlir::acc::LoopOp>
+uncollapseLoops(mlir::acc::LoopOp origLoop, unsigned tileCount,
+                unsigned collapseCount, mlir::RewriterBase &rewriter);
+
+/// Tile ACC loops according to the given tile sizes.
+///
+/// Tiling a 2-level nested loop will create two 'tile' loops containing two
+/// 'element' loops. The transformation looks like:
+///
+/// Before Tiling:
+/// \code
+/// #pragma acc loop tile(tile_size1, tile_size2)
+///  for (i = lb1; i < ub1; i += step1) { // original loop
+///    for (j = lb2; j < ub2; j += step2) {
+///      a[i,j] = i + j;
+///    }
+///  }
+/// \endcode
+///
+/// After Tiling:
+/// \code
+///  for (i = lb1; i < ub1; i += (step1 * tile_size1)) { // tile loop 1
+///    for (j = lb2; j < ub2; j += (step2 * tile_size2)) { // tile loop 2
+///      for (ii = i; ii < min(ub1, (step1 * tile_size1) + i); ii += step1) {
+///      // element loop 1
+///        for (jj = j; jj < min(ub2, (step2 * tile_size2) + j); jj += step2)
+///        { // element loop 2
+///          a[ii,jj] = i + j;
+///        }
+///      }
+///    }
+///  }
+/// \endcode
+///
+/// Unknown tile sizes (represented as -1 in OpenACC for `tile(*)`) are
+/// resolved to the provided default tile size.
+///
+/// \param tileLoops The loops to tile (outermost first).
+/// \param tileSizes The tile sizes for each dimension. Values of -1 are
+///        treated as unknown and resolved to defaultTileSize.
+/// \param defaultTileSize The default tile size to use for unknown (*) tiles.
+/// \param rewriter The rewriter to use for modifications.
+/// \return The outermost loop after tiling.
+mlir::acc::LoopOp tileACCLoops(llvm::SmallVector<mlir::acc::LoopOp> &tileLoops,
+                               const llvm::SmallVector<mlir::Value> &tileSizes,
+                               int32_t defaultTileSize,
+                               mlir::RewriterBase &rewriter);
+
+} // namespace acc
+} // namespace mlir
+
+#endif // MLIR_DIALECT_OPENACC_OPENACCUTILSTILING_H_
diff --git a/mlir/lib/Dialect/OpenACC/Utils/CMakeLists.txt b/mlir/lib/Dialect/OpenACC/Utils/CMakeLists.txt
index 68e124625921f..c3de4f7e3e282 100644
--- a/mlir/lib/Dialect/OpenACC/Utils/CMakeLists.txt
+++ b/mlir/lib/Dialect/OpenACC/Utils/CMakeLists.txt
@@ -1,4 +1,5 @@
 add_mlir_dialect_library(MLIROpenACCUtils
+  OpenACCUtilsTiling.cpp
   OpenACCUtils.cpp
 
   ADDITIONAL_HEADER_DIRS
@@ -14,7 +15,9 @@ add_mlir_dialect_library(MLIROpenACCUtils
   MLIROpenACCTypeInterfacesIncGen
 
   LINK_LIBS PUBLIC
+  MLIRArithDialect
   MLIROpenACCDialect
   MLIRIR
   MLIRSupport
+  MLIRTransformUtils
 )
diff --git a/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsTiling.cpp b/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsTiling.cpp
new file mode 100644
index 0000000000000..f939ec1c58cfd
--- /dev/null
+++ b/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsTiling.cpp
@@ -0,0 +1,313 @@
+//===- OpenACCUtilsTiling.cpp - OpenACC Loop Tiling Utilities -------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains utility functions for tiling OpenACC loops.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Dialect/OpenACC/OpenACCUtilsTiling.h"
+
+#include "mlir/Dialect/Arith/IR/Arith.h"
+#include "mlir/Dialect/OpenACC/OpenACC.h"
+#include "mlir/Dialect/Utils/StaticValueUtils.h"
+#include "mlir/Transforms/RegionUtils.h"
+
+// Resolve unknown tile sizes (represented as -1 for tile(*)) to the default.
+static mlir::Value resolveUnknownTileSize(mlir::Value tileSize,
+                                          int32_t defaultTileSize,
+                                          mlir::RewriterBase &rewriter,
+                                          mlir::Location loc) {
+  auto constVal = mlir::getConstantIntValue(tileSize);
+  if (constVal && *constVal < 0) {
+    return mlir::arith::ConstantOp::create(
+        rewriter, loc, rewriter.getI32Type(),
+        rewriter.getI32IntegerAttr(defaultTileSize));
+  }
+  return tileSize;
+}
+
+// Remove vector/worker attributes from loop
+static void removeWorkerVectorFromLoop(mlir::acc::LoopOp loop) {
+  if (loop.hasVector() || loop.getVectorValue()) {
+    loop.removeVectorAttr();
+    loop.removeVectorOperandsDeviceTypeAttr();
+  } else if (loop.hasWorker() || loop.getWorkerValue()) {
+    loop.removeWorkerAttr();
+    loop.removeWorkerNumOperandsDeviceTypeAttr();
+  }
+}
+
+// Create a new ACC loop with new steps, lb, ub from original loop
+static mlir::acc::LoopOp
+createACCLoopFromOriginal(mlir::acc::LoopOp origLoop,
+                          mlir::RewriterBase &rewriter, mlir::ValueRange lb,
+                          mlir::ValueRange ub, mlir::ValueRange step,
+                          mlir::DenseBoolArrayAttr inclusiveUBAttr,
+                          mlir::acc::CombinedConstructsTypeAttr combinedAttr,
+                          mlir::Location loc, bool preserveCollapse) {
+  mlir::ArrayAttr collapseAttr = mlir::ArrayAttr{};
+  mlir::ArrayAttr collapseDeviceTypeAttr = mlir::ArrayAttr{};
+  if (preserveCollapse) {
+    collapseAttr = origLoop.getCollapseAttr();
+    collapseDeviceTypeAttr = origLoop.getCollapseDeviceTypeAttr();
+  }
+  auto newLoop = mlir::acc::LoopOp::create(
+      rewriter, loc, origLoop->getResultTypes(), lb, ub, step, inclusiveUBAttr,
+      collapseAttr, collapseDeviceTypeAttr, origLoop.getGangOperands(),
+      origLoop.getGangOperandsArgTypeAttr(),
+      origLoop.getGangOperandsSegmentsAttr(),
+      origLoop.getGangOperandsDeviceTypeAttr(), origLoop.getWorkerNumOperands(),
+      origLoop.getWorkerNumOperandsDeviceTypeAttr(),
+      origLoop.getVectorOperands(), origLoop.getVectorOperandsDeviceTypeAttr(),
+      origLoop.getSeqAttr(), origLoop.getIndependentAttr(),
+      origLoop.getAuto_Attr(), origLoop.getGangAttr(), origLoop.getWorkerAttr(),
+      origLoop.getVectorAttr(), mlir::ValueRange{}, mlir::DenseI32ArrayAttr{},
+      mlir::ArrayAttr{}, origLoop.getCacheOperands(),
+      origLoop.getPrivateOperands(), origLoop.getFirstprivateOperands(),
+      origLoop.getReductionOperands(), combinedAttr);
+  return newLoop;
+}
+
+// Create inner loop inside input loop
+static mlir::acc::LoopOp
+createInnerLoop(mlir::acc::LoopOp inputLoop, mlir::RewriterBase &rewriter,
+                mlir::ValueRange lb, mlir::ValueRange ub, mlir::ValueRange step,
+                mlir::DenseBoolArrayAttr inclusiveUBAttr, mlir::Location loc) {
+  mlir::acc::LoopOp elementLoop = createACCLoopFromOriginal(
+      inputLoop, rewriter, lb, ub, step, inclusiveUBAttr,
+      mlir::acc::CombinedConstructsTypeAttr{}, loc, /*preserveCollapse*/ false);
+
+  // Remove gang/worker attributes from inner loops
+  rewriter.startOpModification(elementLoop);
+  if (inputLoop.hasGang() ||
+      inputLoop.getGangValue(mlir::acc::GangArgType::Num) ||
+      inputLoop.getGangValue(mlir::acc::GangArgType::Dim) ||
+      inputLoop.getGangValue(mlir::acc::GangArgType::Static)) {
+    elementLoop.removeGangAttr();
+    elementLoop.removeGangOperandsArgTypeAttr();
+    elementLoop.removeGangOperandsSegmentsAttr();
+    elementLoop.removeGangOperandsDeviceTypeAttr();
+  }
+  if (inputLoop.hasVector() || inputLoop.getVectorValue()) {
+    elementLoop.removeWorkerAttr();
+    elementLoop.removeWorkerNumOperandsDeviceTypeAttr();
+  }
+  rewriter.finalizeOpModification(elementLoop);
+
+  // Create empty block in elementLoop and add IV argument
+  mlir::Block *blk = rewriter.createBlock(&elementLoop.getRegion(),
+                                          elementLoop.getRegion().begin());
+  rewriter.setInsertionPointToEnd(blk);
+  mlir::acc::YieldOp::create(rewriter, loc);
+  elementLoop.getBody().addArgument(
+      inputLoop.getBody().getArgument(0).getType(), loc);
+
+  return elementLoop;
+}
+
+// Move ops from source to target Loop and replace uses of IVs
+static void moveOpsAndReplaceIVs(mlir::acc::LoopOp sourceLoop,
+                                 mlir::acc::LoopOp targetLoop,
+                                 llvm::ArrayRef<mlir::Value> newIVs,
+                                 llvm::ArrayRef<mlir::Value> origIVs,
+                                 size_t nOps, mlir::RewriterBase &rewriter) {
+  // Move ops from source to target loop [begin, begin + nOps - 1)
+  mlir::Block::iterator begin = sourceLoop.getBody().begin();
+  targetLoop.getBody().getOperations().splice(
+      targetLoop.getBody().getOperations().begin(),
+      sourceLoop.getBody().getOperations(), begin, std::next(begin, nOps - 1));
+
+  // Replace uses of origIV with newIV
+  for (auto [i, newIV] : llvm::enumerate(newIVs))
+    mlir::replaceAllUsesInRegionWith(origIVs[i], newIV, targetLoop.getRegion());
+}
+
+mlir::acc::LoopOp
+mlir::acc::tileACCLoops(llvm::SmallVector<mlir::acc::LoopOp> &tileLoops,
+                        const llvm::SmallVector<mlir::Value> &tileSizes,
+                        int32_t defaultTileSize, mlir::RewriterBase &rewriter) {
+  // Tile collapsed and/or nested loops
+  mlir::acc::LoopOp outerLoop = tileLoops[0];
+  const mlir::Location loc = outerLoop.getLoc();
+
+  // Resolve unknown tile sizes (tile(*) represented as -1)
+  llvm::SmallVector<mlir::Value> resolvedTileSizes;
+  rewriter.setInsertionPoint(outerLoop);
+  for (mlir::Value tileSize : tileSizes) {
+    resolvedTileSizes.push_back(
+        resolveUnknownTileSize(tileSize, defaultTileSize, rewriter, loc));
+  }
+
+  mlir::acc::LoopOp innerLoop = tileLoops[tileLoops.size() - 1];
+  llvm::SmallVector<mlir::Value, 3> origIVs;
+  llvm::SmallVector<mlir::Value, 3> origSteps;
+  llvm::SmallVector<mlir::Value, 3> origUBs;
+  llvm::SmallVector<mlir::Value, 3> newSteps;
+  llvm::SmallVector<mlir::Value, 3> newUBs;
+  llvm::SmallVector<mlir::Value, 3> newIVs;
+  size_t nOps = innerLoop.getBody().getOperations().size();
+
+  // Extract original inclusiveUBs
+  llvm::SmallVector<bool> inclusiveUBs;
+  for (auto tileLoop : tileLoops) {
+    for (auto [j, step] : llvm::enumerate(tileLoop.getStep())) {
+      // inclusiveUBs are present on the IR from Fortran frontend for DO loops
+      // but might not be present from other frontends (python)
+      // So check if it exists
+      if (tileLoop.getInclusiveUpperboundAttr())
+        inclusiveUBs.push_back(
+            tileLoop.getInclusiveUpperboundAttr().asArrayRef()[j]);
+      else
+        inclusiveUBs.push_back(false);
+    }
+  }
+
+  // Extract original ivs, UBs, steps, and calculate new steps
+  rewriter.setInsertionPoint(outerLoop);
+  for (auto [i, tileLoop] : llvm::enumerate(tileLoops)) {
+    for (auto arg : tileLoop.getBody().getArguments())
+      origIVs.push_back(arg);
+    for (auto ub : tileLoop.getUpperbound())
+      origUBs.push_back(ub);
+
+    llvm::SmallVector<mlir::Value, 3> currentLoopSteps;
+    for (auto [j, step] : llvm::enumerate(tileLoop.getStep())) {
+      origSteps.push_back(step);
+      if (i + j >= resolvedTileSizes.size()) {
+        currentLoopSteps.push_back(step);
+      } else {
+        mlir::Value tileSize = resolvedTileSizes[i + j];
+        auto newLoopStep =
+            mlir::arith::MulIOp::create(rewriter, loc, step, tileSize);
+        currentLoopSteps.push_back(newLoopStep);
+        newSteps.push_back(newLoopStep);
+      }
+    }
+
+    rewriter.startOpModification(tileLoop);
+    tileLoop.getStepMutable().clear();
+    tileLoop.getStepMutable().append(currentLoopSteps);
+    rewriter.finalizeOpModification(tileLoop);
+  }
+
+  // Calculate new upper bounds for element loops
+  for (size_t i = 0; i < newSteps.size(); i++) {
+    rewriter.setInsertionPoint(innerLoop.getBody().getTerminator());
+    // UpperBound: min(origUB, origIV+(originalStep*tile_size))
+    auto stepped =
+        mlir::arith::AddIOp::create(rewriter, loc, origIVs[i], newSteps[i]);
+    mlir::Value newUB = stepped;
+    if (inclusiveUBs[i]) {
+      // Handle InclusiveUB
+      // UpperBound: min(origUB, origIV+(originalStep*tile_size - 1))
+      auto c1 = mlir::arith::ConstantOp::create(
+          rewriter, loc, newSteps[i].getType(),
+          rewriter.getIntegerAttr(newSteps[i].getType(), 1));
+      newUB = mlir::arith::SubIOp::create(rewriter, loc, stepped, c1);
+    }
+    newUBs.push_back(
+        mlir::arith::MinSIOp::create(rewriter, loc, origUBs[i], newUB));
+  }
+
+  // Create and insert nested elementLoopOps before terminator of outer loopOp
+  mlir::acc::LoopOp currentLoop = innerLoop;
+  for (size_t i = 0; i < resolvedTileSizes.size(); i++) {
+    rewriter.setInsertionPoint(currentLoop.getBody().getTerminator());
+    mlir::DenseBoolArrayAttr inclusiveUBAttr = mlir::DenseBoolArrayAttr{};
+    if (inclusiveUBs[i])
+      inclusiveUBAttr = rewriter.getDenseBoolArrayAttr({true});
+
+    mlir::acc::LoopOp elementLoop =
+        createInnerLoop(innerLoop, rewriter, mlir::ValueRange{origIVs[i]},
+                        mlir::ValueRange{newUBs[i]},
+                        mlir::ValueRange{origSteps[i]}, inclusiveUBAttr, loc);
+
+    // Remove vector/worker attributes from inner element loops except
+    // outermost element loop
+    if (i > 0) {
+      rewriter.startOpModification(elementLoop);
+      removeWorkerVectorFromLoop(elementLoop);
+      rewriter.finalizeOpModification(elementLoop);
+    }
+    newIVs.push_back(elementLoop.getBody().getArgument(0));
+    currentLoop = elementLoop;
+  }
+
+  // Remove vector/worker attributes from outer tile loops
+  for (auto tileLoop : tileLoops) {
+    rewriter.startOpModification(tileLoop);
+    removeWorkerVectorFromLoop(tileLoop);
+    rewriter.finalizeOpModification(tileLoop);
+  }
+
+  // Move ops from inner tile loop to inner element loop and replace IV uses
+  moveOpsAndReplaceIVs(innerLoop, currentLoop, newIVs, origIVs, nOps, rewriter);
+
+  return outerLoop;
+}
+
+llvm::SmallVector<mlir::acc::LoopOp>
+mlir::acc::uncollapseLoops(mlir::acc::LoopOp origLoop, unsigned tileCount,
+                           unsigned collapseCount,
+                           mlir::RewriterBase &rewriter) {
+  llvm::SmallVector<mlir::acc::LoopOp, 3> newLoops;
+  llvm::SmallVector<mlir::Value, 3> newIVs;
+  mlir::Location loc = origLoop.getLoc();
+  llvm::SmallVector<bool> newInclusiveUBs;
+  llvm::SmallVector<mlir::Value, 3> lbs, ubs, steps;
+  for (unsigned i = 0; i < collapseCount; i++) {
+    // inclusiveUpperbound attribute might not be set, default to false
+    bool inclusiveUB = false;
+    if (origLoop.getInclusiveUpperboundAttr())
+      inclusiveUB = origLoop.getInclusiveUpperboundAttr().asArrayRef()[i];
+    newInclusiveUBs.push_back(inclusiveUB);
+    lbs.push_back(origLoop.getLowerbound()[i]);
+    ubs.push_back(origLoop.getUpperbound()[i]);
+    steps.push_back(origLoop.getStep()[i]);
+  }
+  mlir::acc::LoopOp outerLoop = createACCLoopFromOriginal(
+      origLoop, rewriter, lbs, ubs, steps,
+      rewriter.getDenseBoolArrayAttr(newInclusiveUBs),
+      origLoop.getCombinedAttr(), loc, /*preserveCollapse*/ true);
+  mlir::Block *blk = rewriter.createBlock(&outerLoop.getRegion(),
+                                          outerLoop.getRegion().begin());
+  rewriter.setInsertionPointToEnd(blk);
+  mlir::acc::YieldOp::create(rewriter, loc);
+  for (unsigned i = 0; i < collapseCount; i++) {
+    outerLoop.getBody().addArgument(origLoop.getBody().getArgument(i).getType(),
+                                    loc);
+    newIVs.push_back(outerLoop.getBody().getArgument(i));
+  }
+  newLoops.push_back(outerLoop);
+
+  mlir::acc::LoopOp currentLoopOp = outerLoop;
+  for (unsigned i = collapseCount; i < tileCount; i++) {
+    rewriter.setInsertionPoint(currentLoopOp.getBody().getTerminator());
+    bool inclusiveUB = false;
+    if (origLoop.getInclusiveUpperboundAttr())
+      inclusiveUB = origLoop.getInclusiveUpperboundAttr().asArrayRef()[i];
+    mlir::DenseBoolArrayAttr inclusiveUBAttr =
+        rewriter.getDenseBoolArrayAttr({inclusiveUB});
+    mlir::acc::LoopOp innerLoop = createInnerLoop(
+        origLoop, rewriter, mlir::ValueRange{origLoop.getLowerbound()[i]},
+        mlir::ValueRange{origLoop.getUpperbound()[i]},
+        mlir::ValueRange{origLoop.getStep()[i]}, inclusiveUBAttr, loc);
+    newIVs.push_back(innerLoop.getBody().getArgument(0));
+    newLoops.push_back(innerLoop);
+    currentLoopOp = innerLoop;
+  }
+  // Move ops from origLoop to innermost loop and replace uses of IVs
+  size_t nOps = origLoop.getBody().getOperations().size();
+  llvm::SmallVector<mlir::Value, 3> origIVs;
+  for (auto arg : origLoop.getBody().getArguments())
+    origIVs.push_back(arg);
+  moveOpsAndReplaceIVs(origLoop, currentLoopOp, newIVs, origIVs, nOps,
+                       rewriter);
+
+  return newLoops;
+}
diff --git a/mlir/unittests/Dialect/OpenACC/CMakeLists.txt b/mlir/unittests/Dialect/OpenACC/CMakeLists.txt
index c8c2bb96b0539..060c8b8d2679d 100644
--- a/mlir/unittests/Dialect/OpenACC/CMakeLists.txt
+++ b/mlir/unittests/Dialect/OpenACC/CMakeLists.txt
@@ -2,6 +2,7 @@ add_mlir_unittest(MLIROpenACCTests
   OpenACCOpsTest.cpp
   OpenACCOpsInterfacesTest.cpp
   OpenACCUtilsTest.cpp
+  OpenACCUtilsTilingTest.cpp
 )
 mlir_target_link_libraries(MLIROpenACCTests
   PRIVATE
diff --git a/mlir/unittests/Dialect/OpenACC/OpenACCUtilsTilingTest.cpp b/mlir/unittests/Dialect/OpenACC/OpenACCUtilsTilingTest.cpp
new file mode 100644
index 0000000000000..287af9fafd5b7
--- /dev/null
+++ b/mlir/unittests/Dialect/OpenACC/OpenACCUtilsTilingTest.cpp
@@ -0,0 +1,349 @@
+//===- OpenACCUtilsTilingTest.cpp - Unit tests for loop tiling utilities --===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Dialect/OpenACC/OpenACCUtilsTiling.h"
+#include "mlir/Dialect/Arith/IR/Arith.h"
+#include "mlir/Dialect/Func/IR/FuncOps.h"
+#include "mlir/Dialect/MemRef/IR/MemRef.h"
+#include "mlir/Dialect/OpenACC/OpenACC.h"
+#include "mlir/IR/BuiltinOps.h"
+#include "mlir/IR/BuiltinTypes.h"
+#include "mlir/IR/MLIRContext.h"
+#include "mlir/IR/OwningOpRef.h"
+#include "gtest/gtest.h"
+
+using namespace mlir;
+using namespace mlir::acc;
+
+//===----------------------------------------------------------------------===//
+// Test Fixture
+//===----------------------------------------------------------------------===//
+
+class OpenACCUtilsTilingTest : public ::testing::Test {
+protected:
+  OpenACCUtilsTilingTest() : b(&context), loc(UnknownLoc::get(&context)) {
+    context.loadDialect<acc::OpenACCDialect, arith::ArithDialect,
+                        memref::MemRefDialect, func::FuncDialect>(...
[truncated]

@github-actions
Copy link

github-actions bot commented Dec 9, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

Copy link
Contributor

@VijayKandiah VijayKandiah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you!

@razvanlupusoru razvanlupusoru merged commit 21147e7 into llvm:main Dec 10, 2025
10 checks passed
@llvm-ci
Copy link
Collaborator

llvm-ci commented Dec 10, 2025

LLVM Buildbot has detected a new failure on builder amdgpu-offload-ubuntu-22-cmake-build-only running on rocm-docker-ubu-22 while building mlir at step 4 "annotate".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/203/builds/31383

Here is the relevant piece of the build log for the reference
Step 4 (annotate) failure: '../llvm-zorg/zorg/buildbot/builders/annotated/amdgpu-offload-cmake.py --jobs=32' (failure)
...
[5639/8231] Linking CXX shared library lib/libMLIRVectorTransformOps.so.22.0git
[5640/8231] Creating library symlink lib/libMLIRVectorTransformOps.so
[5641/8231] Building CXX object tools/mlir/test/lib/Transforms/CMakeFiles/MLIRTestTransforms.dir/TestMakeIsolatedFromAbove.cpp.o
[5642/8231] Linking CXX shared library lib/libMLIRSPIRVTransforms.so.22.0git
[5643/8231] Building CXX object tools/mlir/test/lib/Transforms/CMakeFiles/MLIRTestTransforms.dir/TestInliningCallback.cpp.o
[5644/8231] Creating library symlink lib/libMLIRVectorToLLVMPass.so
[5645/8231] Linking CXX shared library lib/libMLIRTestRewrite.so.22.0git
[5646/8231] Building CXX object tools/mlir/test/lib/Transforms/CMakeFiles/MLIRTestTransforms.dir/TestCompositePass.cpp.o
[5647/8231] Building CXX object tools/mlir/test/lib/Transforms/CMakeFiles/MLIRTestTransforms.dir/TestControlFlowSink.cpp.o
[5648/8231] Building CXX object tools/mlir/lib/Dialect/OpenACC/Utils/CMakeFiles/obj.MLIROpenACCUtils.dir/OpenACCUtilsTiling.cpp.o
FAILED: tools/mlir/lib/Dialect/OpenACC/Utils/CMakeFiles/obj.MLIROpenACCUtils.dir/OpenACCUtilsTiling.cpp.o 
ccache /usr/bin/c++ -DGTEST_HAS_RTTI=0 -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_GLIBCXX_USE_CXX11_ABI=1 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/botworker/bbot/amdgpu-offload-ubuntu-22-cmake-build-only/build/tools/mlir/lib/Dialect/OpenACC/Utils -I/home/botworker/bbot/amdgpu-offload-ubuntu-22-cmake-build-only/llvm-project/mlir/lib/Dialect/OpenACC/Utils -I/home/botworker/bbot/amdgpu-offload-ubuntu-22-cmake-build-only/build/tools/mlir/include -I/home/botworker/bbot/amdgpu-offload-ubuntu-22-cmake-build-only/llvm-project/mlir/include -I/home/botworker/bbot/amdgpu-offload-ubuntu-22-cmake-build-only/build/include -I/home/botworker/bbot/amdgpu-offload-ubuntu-22-cmake-build-only/llvm-project/llvm/include -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wimplicit-fallthrough -Wno-uninitialized -Wno-nonnull -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-array-bounds -Wno-stringop-overread -Wno-noexcept-type -Wdelete-non-virtual-dtor -Wsuggest-override -Wno-comment -Wno-misleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -Wundef -Wno-unused-but-set-parameter -Wno-deprecated-copy -O3 -DNDEBUG  -fno-exceptions -funwind-tables -fno-rtti -UNDEBUG -std=c++17 -MD -MT tools/mlir/lib/Dialect/OpenACC/Utils/CMakeFiles/obj.MLIROpenACCUtils.dir/OpenACCUtilsTiling.cpp.o -MF tools/mlir/lib/Dialect/OpenACC/Utils/CMakeFiles/obj.MLIROpenACCUtils.dir/OpenACCUtilsTiling.cpp.o.d -o tools/mlir/lib/Dialect/OpenACC/Utils/CMakeFiles/obj.MLIROpenACCUtils.dir/OpenACCUtilsTiling.cpp.o -c /home/botworker/bbot/amdgpu-offload-ubuntu-22-cmake-build-only/llvm-project/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsTiling.cpp
/home/botworker/bbot/amdgpu-offload-ubuntu-22-cmake-build-only/llvm-project/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsTiling.cpp: In function ‘llvm::SmallVector<mlir::acc::LoopOp> mlir::acc::uncollapseLoops(mlir::acc::LoopOp, unsigned int, unsigned int, mlir::RewriterBase&)’:
/home/botworker/bbot/amdgpu-offload-ubuntu-22-cmake-build-only/llvm-project/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsTiling.cpp:310:10: error: could not convert ‘newLoops’ from ‘SmallVector<[...],3>’ to ‘SmallVector<[...],6>’
  310 |   return newLoops;
      |          ^~~~~~~~
      |          |
      |          SmallVector<[...],3>
[5649/8231] Creating library symlink lib/libMLIRSPIRVTransforms.so
[5650/8231] Building CXX object tools/clang/lib/Basic/CMakeFiles/obj.clangBasic.dir/OperatorPrecedence.cpp.o
[5651/8231] Building CXX object tools/mlir/test/lib/Transforms/CMakeFiles/MLIRTestTransforms.dir/TestInlining.cpp.o
[5652/8231] Building CXX object tools/mlir/test/lib/Transforms/CMakeFiles/MLIRTestTransforms.dir/TestCommutativityUtils.cpp.o
[5653/8231] Linking CXX executable bin/mlir-pdll-lsp-server
[5654/8231] Building CXX object tools/mlir/test/lib/Transforms/CMakeFiles/MLIRTestTransforms.dir/TestDialectConversion.cpp.o
[5655/8231] Creating library symlink lib/libMLIRTestRewrite.so
[5656/8231] Building CXX object tools/clang/lib/Basic/CMakeFiles/obj.clangBasic.dir/OpenMPKinds.cpp.o
[5657/8231] Building CXX object tools/mlir/test/lib/Transforms/CMakeFiles/MLIRTestTransforms.dir/TestTransformsOps.cpp.o
[5658/8231] Building CXX object tools/clang/lib/Basic/CMakeFiles/obj.clangBasic.dir/OpenCLOptions.cpp.o
[5659/8231] Building CXX object tools/clang/lib/Basic/CMakeFiles/obj.clangBasic.dir/ParsedAttrInfo.cpp.o
[5660/8231] Building CXX object tools/clang/lib/Basic/CMakeFiles/obj.clangBasic.dir/ProfileList.cpp.o
[5661/8231] Linking CXX shared library lib/libMLIRArmSMETestPasses.so.22.0git
[5662/8231] Linking CXX shared library lib/liblldCommon.so.22.0git
[5663/8231] Linking CXX executable bin/tblgen-to-irdl
[5664/8231] Linking CXX executable bin/mlir-minimal-opt
[5665/8231] Linking CXX executable bin/mlir-minimal-opt-canonicalize
[5666/8231] Linking CXX shared library lib/libMLIRXeGPUTestPasses.so.22.0git
[5667/8231] Linking CXX shared library lib/libMLIRXeGPUTransformOps.so.22.0git
[5668/8231] Linking CXX shared library lib/libMLIRVectorToSPIRV.so.22.0git
[5669/8231] Linking CXX shared library lib/libMLIRLinalgTransforms.so.22.0git
[5670/8231] Linking CXX shared library lib/libMLIRArithToSPIRV.so.22.0git
[5671/8231] Linking CXX shared library lib/libLLVMPasses.so.22.0git
[5672/8231] Building CXX object lib/CodeGen/AsmPrinter/CMakeFiles/LLVMAsmPrinter.dir/AsmPrinter.cpp.o
[5673/8231] Building AMDGPUGenCallingConv.inc...
[5674/8231] Building CXX object lib/LTO/CMakeFiles/LLVMLTO.dir/LTO.cpp.o
[5675/8231] Building AMDGPUGenAsmWriter.inc...
[5676/8231] Building AMDGPUGenInstrInfo.inc...
[5677/8231] Building AMDGPUGenGlobalISel.inc...
[5678/8231] Building AMDGPUGenDAGISel.inc...
[5679/8231] Building AMDGPUGenAsmMatcher.inc...
Step 7 (build cmake config) failure: build cmake config (failure)
...
[5639/8231] Linking CXX shared library lib/libMLIRVectorTransformOps.so.22.0git
[5640/8231] Creating library symlink lib/libMLIRVectorTransformOps.so
[5641/8231] Building CXX object tools/mlir/test/lib/Transforms/CMakeFiles/MLIRTestTransforms.dir/TestMakeIsolatedFromAbove.cpp.o
[5642/8231] Linking CXX shared library lib/libMLIRSPIRVTransforms.so.22.0git
[5643/8231] Building CXX object tools/mlir/test/lib/Transforms/CMakeFiles/MLIRTestTransforms.dir/TestInliningCallback.cpp.o
[5644/8231] Creating library symlink lib/libMLIRVectorToLLVMPass.so
[5645/8231] Linking CXX shared library lib/libMLIRTestRewrite.so.22.0git
[5646/8231] Building CXX object tools/mlir/test/lib/Transforms/CMakeFiles/MLIRTestTransforms.dir/TestCompositePass.cpp.o
[5647/8231] Building CXX object tools/mlir/test/lib/Transforms/CMakeFiles/MLIRTestTransforms.dir/TestControlFlowSink.cpp.o
[5648/8231] Building CXX object tools/mlir/lib/Dialect/OpenACC/Utils/CMakeFiles/obj.MLIROpenACCUtils.dir/OpenACCUtilsTiling.cpp.o
FAILED: tools/mlir/lib/Dialect/OpenACC/Utils/CMakeFiles/obj.MLIROpenACCUtils.dir/OpenACCUtilsTiling.cpp.o 
ccache /usr/bin/c++ -DGTEST_HAS_RTTI=0 -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_GLIBCXX_USE_CXX11_ABI=1 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/botworker/bbot/amdgpu-offload-ubuntu-22-cmake-build-only/build/tools/mlir/lib/Dialect/OpenACC/Utils -I/home/botworker/bbot/amdgpu-offload-ubuntu-22-cmake-build-only/llvm-project/mlir/lib/Dialect/OpenACC/Utils -I/home/botworker/bbot/amdgpu-offload-ubuntu-22-cmake-build-only/build/tools/mlir/include -I/home/botworker/bbot/amdgpu-offload-ubuntu-22-cmake-build-only/llvm-project/mlir/include -I/home/botworker/bbot/amdgpu-offload-ubuntu-22-cmake-build-only/build/include -I/home/botworker/bbot/amdgpu-offload-ubuntu-22-cmake-build-only/llvm-project/llvm/include -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wimplicit-fallthrough -Wno-uninitialized -Wno-nonnull -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-array-bounds -Wno-stringop-overread -Wno-noexcept-type -Wdelete-non-virtual-dtor -Wsuggest-override -Wno-comment -Wno-misleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -Wundef -Wno-unused-but-set-parameter -Wno-deprecated-copy -O3 -DNDEBUG  -fno-exceptions -funwind-tables -fno-rtti -UNDEBUG -std=c++17 -MD -MT tools/mlir/lib/Dialect/OpenACC/Utils/CMakeFiles/obj.MLIROpenACCUtils.dir/OpenACCUtilsTiling.cpp.o -MF tools/mlir/lib/Dialect/OpenACC/Utils/CMakeFiles/obj.MLIROpenACCUtils.dir/OpenACCUtilsTiling.cpp.o.d -o tools/mlir/lib/Dialect/OpenACC/Utils/CMakeFiles/obj.MLIROpenACCUtils.dir/OpenACCUtilsTiling.cpp.o -c /home/botworker/bbot/amdgpu-offload-ubuntu-22-cmake-build-only/llvm-project/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsTiling.cpp
/home/botworker/bbot/amdgpu-offload-ubuntu-22-cmake-build-only/llvm-project/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsTiling.cpp: In function ‘llvm::SmallVector<mlir::acc::LoopOp> mlir::acc::uncollapseLoops(mlir::acc::LoopOp, unsigned int, unsigned int, mlir::RewriterBase&)’:
/home/botworker/bbot/amdgpu-offload-ubuntu-22-cmake-build-only/llvm-project/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsTiling.cpp:310:10: error: could not convert ‘newLoops’ from ‘SmallVector<[...],3>’ to ‘SmallVector<[...],6>’
  310 |   return newLoops;
      |          ^~~~~~~~
      |          |
      |          SmallVector<[...],3>
[5649/8231] Creating library symlink lib/libMLIRSPIRVTransforms.so
[5650/8231] Building CXX object tools/clang/lib/Basic/CMakeFiles/obj.clangBasic.dir/OperatorPrecedence.cpp.o
[5651/8231] Building CXX object tools/mlir/test/lib/Transforms/CMakeFiles/MLIRTestTransforms.dir/TestInlining.cpp.o
[5652/8231] Building CXX object tools/mlir/test/lib/Transforms/CMakeFiles/MLIRTestTransforms.dir/TestCommutativityUtils.cpp.o
[5653/8231] Linking CXX executable bin/mlir-pdll-lsp-server
[5654/8231] Building CXX object tools/mlir/test/lib/Transforms/CMakeFiles/MLIRTestTransforms.dir/TestDialectConversion.cpp.o
[5655/8231] Creating library symlink lib/libMLIRTestRewrite.so
[5656/8231] Building CXX object tools/clang/lib/Basic/CMakeFiles/obj.clangBasic.dir/OpenMPKinds.cpp.o
[5657/8231] Building CXX object tools/mlir/test/lib/Transforms/CMakeFiles/MLIRTestTransforms.dir/TestTransformsOps.cpp.o
[5658/8231] Building CXX object tools/clang/lib/Basic/CMakeFiles/obj.clangBasic.dir/OpenCLOptions.cpp.o
[5659/8231] Building CXX object tools/clang/lib/Basic/CMakeFiles/obj.clangBasic.dir/ParsedAttrInfo.cpp.o
[5660/8231] Building CXX object tools/clang/lib/Basic/CMakeFiles/obj.clangBasic.dir/ProfileList.cpp.o
[5661/8231] Linking CXX shared library lib/libMLIRArmSMETestPasses.so.22.0git
[5662/8231] Linking CXX shared library lib/liblldCommon.so.22.0git
[5663/8231] Linking CXX executable bin/tblgen-to-irdl
[5664/8231] Linking CXX executable bin/mlir-minimal-opt
[5665/8231] Linking CXX executable bin/mlir-minimal-opt-canonicalize
[5666/8231] Linking CXX shared library lib/libMLIRXeGPUTestPasses.so.22.0git
[5667/8231] Linking CXX shared library lib/libMLIRXeGPUTransformOps.so.22.0git
[5668/8231] Linking CXX shared library lib/libMLIRVectorToSPIRV.so.22.0git
[5669/8231] Linking CXX shared library lib/libMLIRLinalgTransforms.so.22.0git
[5670/8231] Linking CXX shared library lib/libMLIRArithToSPIRV.so.22.0git
[5671/8231] Linking CXX shared library lib/libLLVMPasses.so.22.0git
[5672/8231] Building CXX object lib/CodeGen/AsmPrinter/CMakeFiles/LLVMAsmPrinter.dir/AsmPrinter.cpp.o
[5673/8231] Building AMDGPUGenCallingConv.inc...
[5674/8231] Building CXX object lib/LTO/CMakeFiles/LLVMLTO.dir/LTO.cpp.o
[5675/8231] Building AMDGPUGenAsmWriter.inc...
[5676/8231] Building AMDGPUGenInstrInfo.inc...
[5677/8231] Building AMDGPUGenGlobalISel.inc...
[5678/8231] Building AMDGPUGenDAGISel.inc...
[5679/8231] Building AMDGPUGenAsmMatcher.inc...

@llvm-ci
Copy link
Collaborator

llvm-ci commented Dec 10, 2025

LLVM Buildbot has detected a new failure on builder amdgpu-offload-rhel-9-cmake-build-only running on rocm-docker-rhel-9 while building mlir at step 4 "annotate".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/205/builds/30173

Here is the relevant piece of the build log for the reference
Step 4 (annotate) failure: '../llvm-zorg/zorg/buildbot/builders/annotated/amdgpu-offload-cmake.py --jobs=32' (failure)
...
[5581/8231] Building CXX object tools/mlir/test/lib/IR/CMakeFiles/MLIRTestIR.dir/TestSlicing.cpp.o
[5582/8231] Building CXX object tools/mlir/test/lib/IR/CMakeFiles/MLIRTestIR.dir/TestRegions.cpp.o
[5583/8231] Building CXX object tools/mlir/test/lib/IR/CMakeFiles/MLIRTestIR.dir/TestSymbolUses.cpp.o
[5584/8231] Building CXX object tools/mlir/test/lib/IR/CMakeFiles/MLIRTestIR.dir/TestVisitors.cpp.o
[5585/8231] Building CXX object tools/mlir/test/lib/IR/CMakeFiles/MLIRTestIR.dir/TestTypes.cpp.o
[5586/8231] Building CXX object tools/mlir/test/lib/IR/CMakeFiles/MLIRTestIR.dir/TestUseListOrders.cpp.o
[5587/8231] Building CXX object tools/mlir/test/lib/Rewrite/CMakeFiles/MLIRTestRewrite.dir/TestPDLByteCode.cpp.o
[5588/8231] Creating library symlink lib/libMLIRTosaTestPasses.so
[5589/8231] Building CXX object tools/mlir/test/lib/Reducer/CMakeFiles/MLIRTestReducer.dir/MLIRTestReducer.cpp.o
[5590/8231] Building CXX object tools/mlir/lib/Dialect/OpenACC/Utils/CMakeFiles/obj.MLIROpenACCUtils.dir/OpenACCUtilsTiling.cpp.o
FAILED: tools/mlir/lib/Dialect/OpenACC/Utils/CMakeFiles/obj.MLIROpenACCUtils.dir/OpenACCUtilsTiling.cpp.o 
ccache /usr/bin/c++ -DGTEST_HAS_RTTI=0 -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_GLIBCXX_USE_CXX11_ABI=1 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/botworker/bbot/amdgpu-offload-rhel-9-cmake-build-only/build/tools/mlir/lib/Dialect/OpenACC/Utils -I/home/botworker/bbot/amdgpu-offload-rhel-9-cmake-build-only/llvm-project/mlir/lib/Dialect/OpenACC/Utils -I/home/botworker/bbot/amdgpu-offload-rhel-9-cmake-build-only/build/tools/mlir/include -I/home/botworker/bbot/amdgpu-offload-rhel-9-cmake-build-only/llvm-project/mlir/include -I/home/botworker/bbot/amdgpu-offload-rhel-9-cmake-build-only/build/include -I/home/botworker/bbot/amdgpu-offload-rhel-9-cmake-build-only/llvm-project/llvm/include -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wimplicit-fallthrough -Wno-uninitialized -Wno-nonnull -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-array-bounds -Wno-stringop-overread -Wno-noexcept-type -Wdelete-non-virtual-dtor -Wsuggest-override -Wno-comment -Wno-misleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -Wundef -Wno-unused-but-set-parameter -Wno-deprecated-copy -O3 -DNDEBUG -std=c++17  -fno-exceptions -funwind-tables -fno-rtti -UNDEBUG -MD -MT tools/mlir/lib/Dialect/OpenACC/Utils/CMakeFiles/obj.MLIROpenACCUtils.dir/OpenACCUtilsTiling.cpp.o -MF tools/mlir/lib/Dialect/OpenACC/Utils/CMakeFiles/obj.MLIROpenACCUtils.dir/OpenACCUtilsTiling.cpp.o.d -o tools/mlir/lib/Dialect/OpenACC/Utils/CMakeFiles/obj.MLIROpenACCUtils.dir/OpenACCUtilsTiling.cpp.o -c /home/botworker/bbot/amdgpu-offload-rhel-9-cmake-build-only/llvm-project/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsTiling.cpp
/home/botworker/bbot/amdgpu-offload-rhel-9-cmake-build-only/llvm-project/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsTiling.cpp: In function ‘llvm::SmallVector<mlir::acc::LoopOp> mlir::acc::uncollapseLoops(mlir::acc::LoopOp, unsigned int, unsigned int, mlir::RewriterBase&)’:
/home/botworker/bbot/amdgpu-offload-rhel-9-cmake-build-only/llvm-project/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsTiling.cpp:310:10: error: could not convert ‘newLoops’ from ‘SmallVector<[...],3>’ to ‘SmallVector<[...],6>’
  310 |   return newLoops;
      |          ^~~~~~~~
      |          |
      |          SmallVector<[...],3>
[5591/8231] Building CXX object tools/mlir/test/lib/IR/CMakeFiles/MLIRTestIR.dir/TestVisitorsGeneric.cpp.o
[5592/8231] Building CXX object tools/mlir/tools/mlir-pdll-lsp-server/CMakeFiles/mlir-pdll-lsp-server.dir/mlir-pdll-lsp-server.cpp.o
[5593/8231] Building CXX object tools/mlir/tools/tblgen-to-irdl/CMakeFiles/tblgen-to-irdl.dir/OpDefinitionsGen.cpp.o
[5594/8231] Linking CXX shared library lib/libMLIRSCFToSPIRV.so.22.0git
[5595/8231] Linking CXX shared library lib/libMLIRLinalgTransformOps.so.22.0git
[5596/8231] Linking CXX shared library lib/libMLIRTensorToSPIRV.so.22.0git
[5597/8231] Building TestDialectConversionPDLLPatterns.h.inc...
[5598/8231] Linking CXX shared library lib/libMLIRTestVectorToSPIRV.so.22.0git
[5599/8231] Building TestPDLLPatterns.h.inc...
[5600/8231] Linking CXX executable bin/mlir-text-parser-fuzzer
[5601/8231] Linking CXX executable bin/mlir-bytecode-parser-fuzzer
[5602/8231] Linking CXX shared library lib/libMLIRTestRewrite.so.22.0git
[5603/8231] Linking CXX shared library lib/libMLIRTestReducer.so.22.0git
[5604/8231] Linking CXX shared library lib/libMLIRXeGPUTestPasses.so.22.0git
[5605/8231] Linking CXX shared library lib/libMLIRTestTransformDialect.so.22.0git
[5606/8231] Linking CXX shared library lib/libMLIRVectorTestPasses.so.22.0git
[5607/8231] Linking CXX shared library lib/libMLIRCAPISparseTensor.so.22.0git
[5608/8231] Linking CXX shared library lib/libMLIRTilingInterfaceTestPasses.so.22.0git
[5609/8231] Linking CXX shared library lib/libMLIRCAPITarget.so.22.0git
[5610/8231] Building CXX object lib/CodeGen/AsmPrinter/CMakeFiles/LLVMAsmPrinter.dir/AsmPrinter.cpp.o
[5611/8231] Linking CXX shared library lib/libMLIRTestDialect.so.22.0git
[5612/8231] Building AMDGPUGenCallingConv.inc...
[5613/8231] Building AMDGPUGenAsmWriter.inc...
[5614/8231] Building CXX object lib/LTO/CMakeFiles/LLVMLTO.dir/LTO.cpp.o
[5615/8231] Building AMDGPUGenGlobalISel.inc...
[5616/8231] Building AMDGPUGenInstrInfo.inc...
[5617/8231] Building AMDGPUGenDAGISel.inc...
[5618/8231] Building CXX object tools/flang/lib/Support/CMakeFiles/FortranSupport.dir/OpenMP-utils.cpp.o
[5619/8231] Building AMDGPUGenRegisterInfo.inc...
[5620/8231] Building AMDGPUGenAsmMatcher.inc...
[5621/8231] Building AMDGPUGenRegisterBank.inc...
Step 7 (build cmake config) failure: build cmake config (failure)
...
[5581/8231] Building CXX object tools/mlir/test/lib/IR/CMakeFiles/MLIRTestIR.dir/TestSlicing.cpp.o
[5582/8231] Building CXX object tools/mlir/test/lib/IR/CMakeFiles/MLIRTestIR.dir/TestRegions.cpp.o
[5583/8231] Building CXX object tools/mlir/test/lib/IR/CMakeFiles/MLIRTestIR.dir/TestSymbolUses.cpp.o
[5584/8231] Building CXX object tools/mlir/test/lib/IR/CMakeFiles/MLIRTestIR.dir/TestVisitors.cpp.o
[5585/8231] Building CXX object tools/mlir/test/lib/IR/CMakeFiles/MLIRTestIR.dir/TestTypes.cpp.o
[5586/8231] Building CXX object tools/mlir/test/lib/IR/CMakeFiles/MLIRTestIR.dir/TestUseListOrders.cpp.o
[5587/8231] Building CXX object tools/mlir/test/lib/Rewrite/CMakeFiles/MLIRTestRewrite.dir/TestPDLByteCode.cpp.o
[5588/8231] Creating library symlink lib/libMLIRTosaTestPasses.so
[5589/8231] Building CXX object tools/mlir/test/lib/Reducer/CMakeFiles/MLIRTestReducer.dir/MLIRTestReducer.cpp.o
[5590/8231] Building CXX object tools/mlir/lib/Dialect/OpenACC/Utils/CMakeFiles/obj.MLIROpenACCUtils.dir/OpenACCUtilsTiling.cpp.o
FAILED: tools/mlir/lib/Dialect/OpenACC/Utils/CMakeFiles/obj.MLIROpenACCUtils.dir/OpenACCUtilsTiling.cpp.o 
ccache /usr/bin/c++ -DGTEST_HAS_RTTI=0 -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_GLIBCXX_USE_CXX11_ABI=1 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/botworker/bbot/amdgpu-offload-rhel-9-cmake-build-only/build/tools/mlir/lib/Dialect/OpenACC/Utils -I/home/botworker/bbot/amdgpu-offload-rhel-9-cmake-build-only/llvm-project/mlir/lib/Dialect/OpenACC/Utils -I/home/botworker/bbot/amdgpu-offload-rhel-9-cmake-build-only/build/tools/mlir/include -I/home/botworker/bbot/amdgpu-offload-rhel-9-cmake-build-only/llvm-project/mlir/include -I/home/botworker/bbot/amdgpu-offload-rhel-9-cmake-build-only/build/include -I/home/botworker/bbot/amdgpu-offload-rhel-9-cmake-build-only/llvm-project/llvm/include -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wimplicit-fallthrough -Wno-uninitialized -Wno-nonnull -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-array-bounds -Wno-stringop-overread -Wno-noexcept-type -Wdelete-non-virtual-dtor -Wsuggest-override -Wno-comment -Wno-misleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -Wundef -Wno-unused-but-set-parameter -Wno-deprecated-copy -O3 -DNDEBUG -std=c++17  -fno-exceptions -funwind-tables -fno-rtti -UNDEBUG -MD -MT tools/mlir/lib/Dialect/OpenACC/Utils/CMakeFiles/obj.MLIROpenACCUtils.dir/OpenACCUtilsTiling.cpp.o -MF tools/mlir/lib/Dialect/OpenACC/Utils/CMakeFiles/obj.MLIROpenACCUtils.dir/OpenACCUtilsTiling.cpp.o.d -o tools/mlir/lib/Dialect/OpenACC/Utils/CMakeFiles/obj.MLIROpenACCUtils.dir/OpenACCUtilsTiling.cpp.o -c /home/botworker/bbot/amdgpu-offload-rhel-9-cmake-build-only/llvm-project/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsTiling.cpp
/home/botworker/bbot/amdgpu-offload-rhel-9-cmake-build-only/llvm-project/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsTiling.cpp: In function ‘llvm::SmallVector<mlir::acc::LoopOp> mlir::acc::uncollapseLoops(mlir::acc::LoopOp, unsigned int, unsigned int, mlir::RewriterBase&)’:
/home/botworker/bbot/amdgpu-offload-rhel-9-cmake-build-only/llvm-project/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsTiling.cpp:310:10: error: could not convert ‘newLoops’ from ‘SmallVector<[...],3>’ to ‘SmallVector<[...],6>’
  310 |   return newLoops;
      |          ^~~~~~~~
      |          |
      |          SmallVector<[...],3>
[5591/8231] Building CXX object tools/mlir/test/lib/IR/CMakeFiles/MLIRTestIR.dir/TestVisitorsGeneric.cpp.o
[5592/8231] Building CXX object tools/mlir/tools/mlir-pdll-lsp-server/CMakeFiles/mlir-pdll-lsp-server.dir/mlir-pdll-lsp-server.cpp.o
[5593/8231] Building CXX object tools/mlir/tools/tblgen-to-irdl/CMakeFiles/tblgen-to-irdl.dir/OpDefinitionsGen.cpp.o
[5594/8231] Linking CXX shared library lib/libMLIRSCFToSPIRV.so.22.0git
[5595/8231] Linking CXX shared library lib/libMLIRLinalgTransformOps.so.22.0git
[5596/8231] Linking CXX shared library lib/libMLIRTensorToSPIRV.so.22.0git
[5597/8231] Building TestDialectConversionPDLLPatterns.h.inc...
[5598/8231] Linking CXX shared library lib/libMLIRTestVectorToSPIRV.so.22.0git
[5599/8231] Building TestPDLLPatterns.h.inc...
[5600/8231] Linking CXX executable bin/mlir-text-parser-fuzzer
[5601/8231] Linking CXX executable bin/mlir-bytecode-parser-fuzzer
[5602/8231] Linking CXX shared library lib/libMLIRTestRewrite.so.22.0git
[5603/8231] Linking CXX shared library lib/libMLIRTestReducer.so.22.0git
[5604/8231] Linking CXX shared library lib/libMLIRXeGPUTestPasses.so.22.0git
[5605/8231] Linking CXX shared library lib/libMLIRTestTransformDialect.so.22.0git
[5606/8231] Linking CXX shared library lib/libMLIRVectorTestPasses.so.22.0git
[5607/8231] Linking CXX shared library lib/libMLIRCAPISparseTensor.so.22.0git
[5608/8231] Linking CXX shared library lib/libMLIRTilingInterfaceTestPasses.so.22.0git
[5609/8231] Linking CXX shared library lib/libMLIRCAPITarget.so.22.0git
[5610/8231] Building CXX object lib/CodeGen/AsmPrinter/CMakeFiles/LLVMAsmPrinter.dir/AsmPrinter.cpp.o
[5611/8231] Linking CXX shared library lib/libMLIRTestDialect.so.22.0git
[5612/8231] Building AMDGPUGenCallingConv.inc...
[5613/8231] Building AMDGPUGenAsmWriter.inc...
[5614/8231] Building CXX object lib/LTO/CMakeFiles/LLVMLTO.dir/LTO.cpp.o
[5615/8231] Building AMDGPUGenGlobalISel.inc...
[5616/8231] Building AMDGPUGenInstrInfo.inc...
[5617/8231] Building AMDGPUGenDAGISel.inc...
[5618/8231] Building CXX object tools/flang/lib/Support/CMakeFiles/FortranSupport.dir/OpenMP-utils.cpp.o
[5619/8231] Building AMDGPUGenRegisterInfo.inc...
[5620/8231] Building AMDGPUGenAsmMatcher.inc...
[5621/8231] Building AMDGPUGenRegisterBank.inc...

@razvanlupusoru
Copy link
Contributor Author

The buildbot failures should get resolved with: #171546

@llvm-ci
Copy link
Collaborator

llvm-ci commented Dec 10, 2025

LLVM Buildbot has detected a new failure on builder mlir-s390x-linux running on systemz-1 while building mlir at step 5 "build-unified-tree".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/117/builds/15627

Here is the relevant piece of the build log for the reference
Step 5 (build-unified-tree) failure: build (failure)
...
63.448 [1082/4/4045] Linking CXX static library lib/libMLIRBufferizationDialect.a
63.466 [1081/4/4046] Linking CXX static library lib/libMLIRFuncShardingExtensions.a
63.481 [1080/4/4047] Linking CXX static library lib/libMLIRFuncAllExtensions.a
63.528 [1079/4/4048] Linking CXX static library lib/libMLIRNVGPUDialect.a
63.544 [1078/4/4049] Linking CXX static library lib/libMLIRTensorInferTypeOpInterfaceImpl.a
63.560 [1077/4/4050] Linking CXX static library lib/libMLIRTensorShardingExtensions.a
63.585 [1076/4/4051] Linking CXX static library lib/libMLIRTensorAllExtensions.a
63.586 [1075/4/4052] Linking CXX static library lib/libMLIRShapeDialect.a
63.600 [1074/4/4053] Linking CXX static library lib/libMLIRTensorUtils.a
63.668 [1073/4/4054] Building CXX object tools/mlir/lib/Dialect/OpenACC/Utils/CMakeFiles/obj.MLIROpenACCUtils.dir/OpenACCUtilsTiling.cpp.o
FAILED: tools/mlir/lib/Dialect/OpenACC/Utils/CMakeFiles/obj.MLIROpenACCUtils.dir/OpenACCUtilsTiling.cpp.o 
CCACHE_CPP2=yes CCACHE_HASHDIR=yes CCACHE_SLOPPINESS=pch_defines,time_macros /usr/bin/ccache /usr/bin/c++ -DGTEST_HAS_RTTI=0 -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_GLIBCXX_USE_CXX11_ABI=1 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/uweigand/sandbox/buildbot/mlir-s390x-linux/build/tools/mlir/lib/Dialect/OpenACC/Utils -I/home/uweigand/sandbox/buildbot/mlir-s390x-linux/llvm-project/mlir/lib/Dialect/OpenACC/Utils -I/home/uweigand/sandbox/buildbot/mlir-s390x-linux/build/tools/mlir/include -I/home/uweigand/sandbox/buildbot/mlir-s390x-linux/llvm-project/mlir/include -I/home/uweigand/sandbox/buildbot/mlir-s390x-linux/build/include -I/home/uweigand/sandbox/buildbot/mlir-s390x-linux/llvm-project/llvm/include -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wimplicit-fallthrough -Wno-uninitialized -Wno-nonnull -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-array-bounds -Wno-stringop-overread -Wno-noexcept-type -Wdelete-non-virtual-dtor -Wsuggest-override -Wno-comment -Wno-misleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -Wundef -Wno-unused-but-set-parameter -Wno-deprecated-copy -O3 -DNDEBUG  -fno-exceptions -funwind-tables -fno-rtti -UNDEBUG -std=c++17 -MD -MT tools/mlir/lib/Dialect/OpenACC/Utils/CMakeFiles/obj.MLIROpenACCUtils.dir/OpenACCUtilsTiling.cpp.o -MF tools/mlir/lib/Dialect/OpenACC/Utils/CMakeFiles/obj.MLIROpenACCUtils.dir/OpenACCUtilsTiling.cpp.o.d -o tools/mlir/lib/Dialect/OpenACC/Utils/CMakeFiles/obj.MLIROpenACCUtils.dir/OpenACCUtilsTiling.cpp.o -c /home/uweigand/sandbox/buildbot/mlir-s390x-linux/llvm-project/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsTiling.cpp
/home/uweigand/sandbox/buildbot/mlir-s390x-linux/llvm-project/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsTiling.cpp: In function ‘llvm::SmallVector<mlir::acc::LoopOp> mlir::acc::uncollapseLoops(mlir::acc::LoopOp, unsigned int, unsigned int, mlir::RewriterBase&)’:
/home/uweigand/sandbox/buildbot/mlir-s390x-linux/llvm-project/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsTiling.cpp:310:10: error: could not convert ‘newLoops’ from ‘SmallVector<[...],3>’ to ‘SmallVector<[...],6>’
  310 |   return newLoops;
      |          ^~~~~~~~
      |          |
      |          SmallVector<[...],3>
63.729 [1073/3/4055] Linking CXX static library lib/libMLIRVectorDialect.a
63.783 [1073/2/4056] Linking CXX static library lib/libMLIRTosaDialect.a
63.788 [1073/1/4057] Linking CXX static library lib/libMLIRNVVMDialect.a
ninja: build stopped: subcommand failed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants