[Mlir-commits] [llvm] [mlir] [MLIR][OpenMP] add interchange operation in the OpenMP mlir dialect (PR #186381)

Ferran Toda llvmlistbot at llvm.org
Mon Mar 23 07:59:21 PDT 2026


================
@@ -3965,6 +3967,98 @@ std::pair<unsigned, unsigned> FuseOp::getGenerateesODSOperandIndexAndLength() {
   return getODSOperandIndexAndLength(odsIndex_generatees);
 }
 
+//===----------------------------------------------------------------------===//
+// InterchangeOp
+//===----------------------------------------------------------------------===//
+
+static void printLoopTransformClis(OpAsmPrinter &p, InterchangeOp op,
+                                   OperandRange generatees,
+                                   OperandRange applyees) {
+  if (!generatees.empty())
+    p << '(' << llvm::interleaved(generatees) << ')';
+
+  if (!applyees.empty())
+    p << " <- (" << llvm::interleaved(applyees) << ')';
+}
+
+LogicalResult InterchangeOp::verify() {
+  if (getApplyees().size() < 2)
+    return emitOpError() << "must apply to at least two loops";
+
+  if (!getPermutation().has_value())
+    return emitOpError() << "must have permutation attribute";
+
+  auto permutation = getPermutation().value();
+  if (permutation.size() != getApplyees().size())
+    return emitOpError() << "expecting the same number of permutation "
+                            "attributes and applyees";
+
+  llvm::SmallVector<bool> found(permutation.size(), false);
+  for (auto &val : permutation) {
+    int perm = llvm::dyn_cast<IntegerAttr>(val).getInt();
+    if (perm <= 0)
+      return emitOpError()
+             << "permutation attribute must be a positive integer";
+    if ((unsigned)perm - 1 < permutation.size())
+      found[perm - 1] = true;
+  }
+  for (bool b : found) {
+    if (!b)
+      return emitOpError()
+             << "every integer from 1 must appear in the permutation attribute";
+  }
+
+  if (!getGeneratees().empty() &&
+      getApplyees().size() != getGeneratees().size())
+    return emitOpError()
+           << "expecting the same number of generatees and applyees";
+
+  DenseSet<Value> parentIVs;
+
+  Value parent = getApplyees().front();
+  for (auto &&applyee : llvm::drop_begin(getApplyees())) {
+    auto [parentCreate, parentGen, parentCons] = decodeCli(parent);
+    auto [create, gen, cons] = decodeCli(applyee);
+
+    if (!parentGen)
+      return emitOpError() << "applyee CLI has no generator";
+
+    auto parentLoop = dyn_cast_or_null<CanonicalLoopOp>(parentGen->getOwner());
+    if (!parentGen)
+      return emitOpError()
+             << "currently only supports omp.canonical_loop as applyee";
+
+    parentIVs.insert(parentLoop.getInductionVar());
+
+    if (!gen)
+      return emitOpError() << "applyee CLI has no generator";
+    auto loop = dyn_cast_or_null<CanonicalLoopOp>(gen->getOwner());
+    if (!loop)
+      return emitOpError()
+             << "currently only supports omp.canonical_loop as applyee";
----------------
NouTimbaler wrote:

Removed this check and added the test for chaining multiple interchanges

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


More information about the Mlir-commits mailing list