[Mlir-commits] [clang] [llvm] [mlir] [openmp] [LoopTiling][Clang][MLIR] Canonical Intra-tile Loops (PR #191114)

Michael Kruse llvmlistbot at llvm.org
Tue May 26 08:59:34 PDT 2026


================
@@ -14983,35 +14994,113 @@ StmtResult SemaOpenMP::ActOnOpenMPTileDirective(ArrayRef<OMPClause *> Clauses,
       FloorIndVars[I] = FloorCntDecl;
     }
 
-    // Iteration variable for the tile (i.e. inner) loop.
+    // Logical iteration variable for the tile loop. Retains the meaning of
+    // the original logical iteration number (floor_iv + tile_cnt) so that
+    // LoopHelper.Updates can derive the original loop variable unchanged.
     {
-      std::string TileCntName =
+      std::string TileIVName =
           (Twine(".tile_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
 
-      // Reuse the iteration variable created by checkOpenMPLoop. It is also
-      // used by the expressions to derive the original iteration variable's
-      // value from the logical iteration number.
-      auto *TileCntDecl = cast<VarDecl>(IterVarRef->getDecl());
-      TileCntDecl->setDeclName(
-          &SemaRef.PP.getIdentifierTable().get(TileCntName));
-      TileIndVars[I] = TileCntDecl;
+      auto *TileIVDecl = cast<VarDecl>(IterVarRef->getDecl());
+      TileIVDecl->setDeclName(&SemaRef.PP.getIdentifierTable().get(TileIVName));
+      TileIndVars[I] = TileIVDecl;
+    }
+
+    // Loop counter for the rectangular tile loop [0, TileSize).
+    if (IntraTileMustBeCanonical) {
+      std::string TileCntName =
+          (Twine(".tile.cnt.") + llvm::utostr(I) + ".iv." + OrigVarName).str();
+      VarDecl *TileCntDecl =
+          buildVarDecl(SemaRef, {}, CntTy, TileCntName, nullptr, OrigCntVar);
+      TileCntVars[I] = TileCntDecl;
     }
 
     addLoopPreInits(Context, LoopHelper, LoopStmts[I], OriginalInits[I],
                     PreInits);
+
+    // Declare the logical tile IV in PreInits so it is in scope for the
+    // entire loop nest (it will be assigned in each tile loop body).
+    if (IntraTileMustBeCanonical) {
+      Decl *TileIVDeclPtr = TileIndVars[I];
+      PreInits.push_back(new (Context) DeclStmt(
+          DeclGroupRef::Create(Context, &TileIVDeclPtr, 1), {}, {}));
+    }
   }
 
   // Once the original iteration values are set, append the innermost body.
   Stmt *Inner = Body;
 
+  // Build a combined validity predicate that guards the innermost body.
+  // For each tiled dimension, check that the logical iteration number
+  // (.tile.iv) is within the original trip count. This is required because the
+  // tile loop now has rectangular (constant) bounds and may overshoot on the
+  // remainder tile. The predicate is: .tile.iv.0 < N0 && .tile.iv.1 < N1 ...
+  //
+  // Optimization: if every dimension's trip count is a compile-time constant
+  // that is evenly divisible by the corresponding tile size (also a constant),
+  // then the remainder tile is empty and the predicate is trivially true.
+  //
+  // The min-bounded path clamps the tile loop's upper bound directly so no
+  // predicate is needed.
+  if (IntraTileMustBeCanonical) {
+    bool PredicateNeeded = false;
+    for (unsigned I = 0; I < NumLoops; ++I) {
+      Expr *TSExpr = SizesClause->getSizesRefs()[I];
+      Expr *NExpr = LoopHelpers[I].NumIterations;
+      bool TSConst =
----------------
Meinersbur wrote:

```suggestion
      bool TSIsConst =
```
Since the variable does not contain the constant itself.

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


More information about the Mlir-commits mailing list