)]}'
{
  "commit": "a652cacbb287a3a3bc3d17b2be21fced37753fc0",
  "tree": "303d083858ed1a91113b8a9c1f557dec9280a1bb",
  "parents": [
    "c04b8e5ef033f9f89a11f8a44843cbd0dc3ea440"
  ],
  "author": {
    "name": "Jianhui Li",
    "email": "jian.hui.li@intel.com",
    "time": "Wed Oct 14 11:20:00 2026 -0700"
  },
  "committer": {
    "name": "GitHub",
    "email": "noreply@github.com",
    "time": "Wed Oct 14 18:20:00 2026 +0000"
  },
  "message": "[mlir][Vector]  Promote buffers accessed via dynamic subviews (#217793)\n\n**Motivation**\n\nAn op on dynamically-shaped tensors is padded to static tile sizes\nbefore vectorization: its operands are padded up to a fixed size, and\nthe real region is extracted back from the result. After bufferization\nthose padded tensors become fixed-size buffers, and the IR around them\nreaches each buffer through dynamic-shaped views — the buffer\u0027s shape is\nstatic, but the part that really holds data is not.\n\nThe pattern looks like this: a fixed-size staging buffer holding one\ntile, a dynamic subview covering the part with real data, a reshape\nlifting that tile to the rank of the original tensor it came from, and a\nmemref.copy that stores the tile back into it or loads a tile out.\n\n```mlir\n%buf \u003d memref.alloca() : memref\u003c128x64xf16\u003e      // padded staging buffer\nvector.transfer_write %v, %buf[%c0, %c0] {in_bounds \u003d [true, true]}\n    : vector\u003c128x64xf16\u003e, memref\u003c128x64xf16\u003e\n%sv  \u003d memref.subview %buf[0, 0] [%n, 64]  [1, 1]   // %n rows of the padded buffer, %n may \u003c128 for the edge tile \n    : memref\u003c128x64xf16\u003e to memref\u003c?x64xf16, strided\u003c[64, 1]\u003e\u003e\n             ...                                     // ops on the dynamic subview like repadding + elewise/reduction\n%ex  \u003d memref.expand_shape %sv [[0, 1, 2], [3]]\n    : memref\u003c?x64xf16, strided\u003c[64, 1]\u003e\u003e into memref\u003c1x1x?x64xf16, strided\u003c[?, ?, 64, 1]\u003e\u003e\n%dst \u003d memref.subview %out[%i, %j, %k, 0]  [1, 1, %n, 64] [1, 1, 1, 1]   // the tile\u0027s window in %out: %k is where it starts, %n how long it is\nmemref.copy %ex, %dst\n```\n\n#211880 taught Mem2Reg to promote a staticall vector SSA value, but only\nfor whole-buffer,in-bounds, unmasked\nvector.transfer_read/transfer_write, plus fully-static memref.subview\nsub-slices.\n\nThis PR extends the vector Mem2Reg models so dynamic subviews and masked\ntransfers promote as well. Any partial access is reconstructed with an\narith.select during promotion instead of bailing out. The chain above\nthen promotes to vector values, and the allocation goes away.\n\nThis PR closes a gap in the lowering pipeline for linalg IR on\ndynamically-shaped tensors: tile-and-fuse → padding → vectorize →\nbufferization → mem2reg. The current Mem2Reg handles only whole-buffer\ntransfers and static-shaped subviews, so the staging buffers remain in\nthe final IR. Now they promote to vector values instead: the padding\nintroduced at the linalg level becomes a vector.create_mask and an\narith.select on a fixed-size vector, and the pipeline finishes in pure\nvector IR.\n\nThe expand_shape and collapse_shape will be supported in a separate PR. \n\n**What this PR adds**\n\n**Dynamic-shaped subviews.** A vector\u0027s shape has to be static, so a\ndynamic subview cannot have a vector of its own shape. It uses the whole\nbuffer\u0027s vector instead, and reads or writes through it are masked to\nthe runtime size with vector.create_mask and arith.select. The subview\nhas to start at the buffer\u0027s origin, so the live region on each\ndimension is just [0, size).\n\n**Masked transfers.** A masked transfer touches only some lanes, so\nrather than reject it, promotion rebuilds the result with an\narith.select.\n\n**Restrictions**\n- a transfer that does not start at the buffer\u0027s origin, or whose\npermutation map is not the identity\n - a subview whose offsets are not constants\n - a dynamic subview that does not start at the buffer\u0027s origin\n - a rank-reducing or non-unit-stride subview\n- subviewing or reshaping a scalable buffer — it still promotes through\nwhole-buffer transfers, just not through these\n\n**Tests**\n- mem2reg.mlir covers whole-buffer, static-subview, masked cases. \n- mem2reg-dynamic-subview.mlir covers dynamic views: plain, nested on a\nstatic subview, and merged across a branch by a block argument.\n \n assisted-by-claude\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) \u003cnoreply@anthropic.com\u003e",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "70e356ae5a254b2171e0f1d4fc27008dba3c158b",
      "old_mode": 33188,
      "old_path": "mlir/include/mlir/Dialect/MemRef/Transforms/MemorySlotOpInterfaceImpl.h",
      "new_id": "cb94ccf1a3541beb5cf6f046e1659c0a83219973",
      "new_mode": 33188,
      "new_path": "mlir/include/mlir/Dialect/MemRef/Transforms/MemorySlotOpInterfaceImpl.h"
    },
    {
      "type": "modify",
      "old_id": "b64cdfc0a48c813c57f1c2fb875241b2ee48cf36",
      "old_mode": 33188,
      "old_path": "mlir/lib/Dialect/MemRef/Transforms/MemorySlotOpInterfaceImpl.cpp",
      "new_id": "c562c67433f470c866e2f86ebcb2cc7371100c2e",
      "new_mode": 33188,
      "new_path": "mlir/lib/Dialect/MemRef/Transforms/MemorySlotOpInterfaceImpl.cpp"
    },
    {
      "type": "modify",
      "old_id": "e261dfd7c1d66aaafa29a93fec802d6200291449",
      "old_mode": 33188,
      "old_path": "mlir/lib/Dialect/Vector/Transforms/MemorySlotOpInterfaceImpl.cpp",
      "new_id": "c8c17f2039b02551be2891cdc44a37d96d5f6b01",
      "new_mode": 33188,
      "new_path": "mlir/lib/Dialect/Vector/Transforms/MemorySlotOpInterfaceImpl.cpp"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "e650f7e3fb09a77a63ce928ba87070b64066a23e",
      "new_mode": 33188,
      "new_path": "mlir/test/Dialect/Vector/mem2reg-dynamic-subview.mlir"
    },
    {
      "type": "modify",
      "old_id": "a7cdc569a81a0f3dc4047b78a88d5df28b9cf032",
      "old_mode": 33188,
      "old_path": "mlir/test/Dialect/Vector/mem2reg.mlir",
      "new_id": "62a35c90d324e367d345b9c7e178658e500d644d",
      "new_mode": 33188,
      "new_path": "mlir/test/Dialect/Vector/mem2reg.mlir"
    }
  ]
}
