[Mlir-commits] [mlir] [mlir][vector] Patterns to convert to shape_cast, where possible (PR #138777)

Andrzej Warzyński llvmlistbot at llvm.org
Tue May 13 05:41:08 PDT 2025


banach-space wrote:

> I found https://github.com/llvm/llvm-project/commit/06dbb2856967a5497c6ddfad3d3fdfea20849f7e which removes patterns exactly like these, on the caoincalizers.

Thanks for finding and sharing that thread :) I wasn't aware of those earlier design discussions about restricting `vector.shape_cast`.

That’s a fairly old discussion (given MLIR’s age), and likely dates back to when there was an assumption we'd be using `llvm.intr.matrix` intrinsics. From the [vector.shape_cast documentation](https://mlir.llvm.org/docs/Dialects/Vector/#vectorshape_cast-vectorshapecastop):

> There is an exception to the folding expectation when targeting llvm.intr.matrix operations. We need a type conversion back and forth from a 2-D MLIR vector to a 1-D flattened LLVM vector.shape_cast lowering to LLVM is supported in that particular case, for now.

However, these matrix intrinsics are not widely used, and - as far as I know - the corresponding LLVM work has been on hold for quite some time (a few years?). From what I can tell, those requirements are now outdated.

In the last 2–3 years that I’ve been working in this space, the consistent takeaway has been:

> vector.shape_cast is the canonical form for reshapes that imply no data movement.

In general, the assumption is that `vector.shape_cast` encodes a reshape with no underlying value movement.

Regarding the example you mentioned:
```mlir
%0 = vector.shape_cast %arg0 : vector<2x3xf32> to vector<1x2x3xf32>
```
...and its lowering to:

```mlir
 %0 = ub.poison : vector<1x2x3xf32>
  %1 = vector.extract %arg0[0, 0] : f32 from vector<2x3xf32>
  %2 = vector.insert %1, %0 [0, 0, 0] : f32 into vector<1x2x3xf32>
  %3 = vector.extract %arg0[0, 1] : f32 from vector<2x3xf32>
  %4 = vector.insert %3, %2 [0, 0, 1] : f32 into vector<1x2x3xf32>
  %5 = vector.extract %arg0[0, 2] : f32 from vector<2x3xf32>
  %6 = vector.insert %5, %4 [0, 0, 2] : f32 into vector<1x2x3xf32>
  %7 = vector.extract %arg0[1, 0] : f32 from vector<2x3xf32>
  %8 = vector.insert %7, %6 [0, 1, 0] : f32 into vector<1x2x3xf32>
  %9 = vector.extract %arg0[1, 1] : f32 from vector<2x3xf32>
  %10 = vector.insert %9, %8 [0, 1, 1] : f32 into vector<1x2x3xf32>
  %11 = vector.extract %arg0[1, 2] : f32 from vector<2x3xf32>
  %12 = vector.insert %11, %10 [0, 1, 2] : f32 into vector<1x2x3xf32>
```

This lowering clearly involves data movement, and to me violates the design intent of `vector.shape_cast`. I wouldn’t use it as a guiding example - in fact, this may be a good time to revisit that lowering and consider disabling it or making it conditional.

So in principle: yes, I’m in favor of turning these patterns into canonicalizations. We should just be thoughtful about which constraints we want to enforce.

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


More information about the Mlir-commits mailing list