<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/144825>144825</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [mlir][hoisting] Currently linalg hoisting can not optimize memref.assume_alignment
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            mlir
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
            xiangzh1
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          xiangzh1
      </td>
    </tr>
</table>

<pre>
    Last month (2025-05-18)Kleiman update the AssumeAlignmentOp, let it has AnyMemRef result。
this make the following changes:

```
%2 = hal.interface.binding.subspan layout ... : memref<4096x4096xf16, #hal.descriptor_type<storage_buffer>>
 memref.assume_alignment %2, 64 : memref<4096x4096xf16, #hal.descriptor_type<storage_buffer>>
use %2
```
change to

```
%2 = hal.interface.binding.subspan layout ... : memref<4096x4096xf16, #hal.descriptor_type<storage_buffer>>
%assume_align = memref.assume_alignment %2, 64 : memref<4096x4096xf16, #hal.descriptor_type<storage_buffer>>
use %assume_align
```

**Problem**:
This will affect the linalg hoisting optimization,due to the memref.assume_alignment  inherited the interface
ViewLikeOpInterface which is excluded by linalg hoisting.

for example , in follow mlir, the
 "%1 = vector.transfer_read %assume_align_0[%c0, %c0] ..." and 
   "vector.transfer_write %3, %assume_align_0[%c0, %c0]"
read from and write to a same location. We can hoist them out of loop:

 ```
 %m0 = hal.interface.binding.subspan layout ...: memref<4096x4096xf16>
  %m1 = hal.interface.binding.subspan layout ...: memref<4096x4096xf16>
  %assume_align_0 = memref.assume_alignment %m0, 64 : memref<4096x4096xf16>
  %assume_align_1 = memref.assume_alignment %m1, 64 : memref<4096x4096xf16>
  scf.for %arg0 = %c256 to %c4096 step %c256 {
    %1 = vector.transfer_read %assume_align_0[%c0, %c0], %cst_0 {in_bounds = [true, true]} : memref<4096x4096xf16>, vector<16x16xf16>
    %2 = vector.transfer_read %m1[%arg0, %arg0], %cst_0 {in_bounds = [true, true]} : memref<4096x4096xf16>, vector<16x16xf16>
    %3 = vector.contract {indexing_maps = [affine_map<(d0, d1, d2) -> (d0, d2)>, affine_map<(d0, d1, d2) -> (d2, d1)>, affine_map<(d0, d1, d2) -> (d0, d1)>], iterator_types = ["parallel", "parallel", "reduction"], kind = #vector.kind<add>} %2, %2, %1 : vector<16x16xf16>, vector<16x16xf16> into vector<16x16xf16>
    vector.transfer_write %3, %assume_align_0[%c0, %c0] {in_bounds = [true, true]} : vector<16x16xf16>, memref<4096x4096xf16>
  }
```
but due to the transfer_read/write from/to an assume_alignment operation. The linalg hoisting stop do optimization for it.
(I am not much understand why the linalg hoisting do this,  I am a beginner in mlir)
But the assume_alignment just mark memref's alignment, The linalg hoisting should check its memref operand not it self.
so we expect the upper mlir can be optimized to:

```
   %m0 = hal.interface.binding.subspan layout ...: memref<4096x4096xf16>
    %m1 = hal.interface.binding.subspan layout ...: memref<4096x4096xf16>
    %assume_align_0 = memref.assume_alignment %m0, 64 : memref<4096x4096xf16>
    %assume_align_1 = memref.assume_alignment %m1, 64 : memref<4096x4096xf16>
    %0 = vector.transfer_read %assume_align[%c0, %c0], %cst {in_bounds = [true, true]} : memref<4096x4096xf16>, vector<16x16xf16> // out of loop
    %1 = scf.for %arg0 = %c256 to %c4096 step %c256 iter_args(%arg1 = %0) -> (vector<16x16xf16>) {
      %2 = vector.transfer_read %assume_align_1[%arg0, %arg0], %cst {in_bounds = [true, true]} : memref<4096x4096xf16>, vector<16x16xf16>
      %3 = vector.contract {indexing_maps = [#map, #map1, #map2], iterator_types = ["parallel", "parallel", "reduction"], kind = #vector.kind<add>} %2, %2, %arg1 : vector<16x16xf16>, vector<16x16xf16> into vector<16x16xf16>
      scf.yield %3 : vector<16x16xf16>
    }
    vector.transfer_write %1, %assume_align[%c0, %c0] {in_bounds = [true, true]} : vector<16x16xf16>, memref<4096x4096xf16> // out of loop
```

detailed example pls refer to  [example](https://godbolt.org/z/Tj19noof1)
(I don't not how to write hal.interface.binding for mlir-opt so, in the example I use memref.alloc() instead of them.)
</pre>

<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzMWF1v2zoS_TX0yyCCRFm29eAHx46BYu_iLhbF7qNBSSOLDUUKJNUk_fUXQ1mu7TpJWyRtASFWKHF45szHISWck3uNuGTZLeP8UQq9_9IkjHOWbSai942xy3F0UpjqafmXcB5ao30D7G7LbtdsseAxz27i7CZZjEP5vxTKVmjou0p4BN8grJzrW1wpudctav93N768BoUepIdGOFjpp39j-1-swaLrlWd3KVvEbMFZvPKNdNCK-8FebZQyD1LvoWyE3qM72MtXLA7XLD5c8YrxjANLN9AIFUnt0daixKiQupJ6H7m-cJ3QoMST6T1EUQQsXUGLrcWapetpnM8ew586mTG-BsZTslShK63svLE7_9QhS9fOGyv2uCv6ukbL0ju64tFUJAIHOzGSAASMDM6mb7xi73Awfk7EQBV48-dxxHh2Sk-A8rtoO13wkiZCStd_rCkUtsM_LKUHHylBH6RSIOoaSx_yVEkt1B4aI52nbDWdl638Irw0-lgCVU9BCe8_5zNI3aCVHqvw2jFCLF79T-LDX_Ie_-4-jKPw0MiyAekAH0vVV1hB8XSJJRr8qY0FfBRtp8j5NUh9KC5olbQ04htaBqgx8CwJofmMpTc28lZoV6PdWRTVJXW7ODSWrIyHWNBNtqHcYZyD0BWQVSC7l-YeyFOakh6mvm6X0MWrgKO2pg32BzPegAAnWgRlykB8BP9HKIUeqCD_WqC0NjUoY7ohnMHlk9DTSm38QzXyQnYOjSHYTN7e5jldrxVTG79eTc_YTl61nXy3bVfWESUjrWH3A2qKLs9mFEO6pSngPHbHB2x-O2QRvEFujvfOE2nzW6l3hel15QYs2a23PYaKoN9sw-abV_zi6wMclq6T2WNy5nDAzF_E3CYDTiJkLAW6_T1Y01OspdHeitIPi1f4KPV-14ruCEDUtdRIQyxdM76oggdVSIiKM57DDUvv4OsTGjsA-YG5fHzyE3Pjs7kDqdKjFaNWHJ1hnHfCCqVQhT5I5F8ZsVj1ZejtYRdFo_eSOl3I5fRAHQ2xdC2qipadb46KdvKbhGhdD8hzkSJZMC8G8Q0a7Y8k27PwX-ky882F7ha9hxOVPKsTxreDG9T3Gd9Sv9fwTTMyHcU1dP-PV4TZedNBZc4EGqgdSR-Eki8-gGhBGw9tXzbQ6wqt80FmmqerWl8RWOnIXwiTBRS4l1qjJZUd5DVn8eq2HzYL32D-1NN-W9j7kTA-d3B8TIavutKYXlVQNljeg_TuMHlgQFfBB-nBoarJNWfgAQEfu3HP0ncd2gAviGSBIym0-TBHdTwTR3gXeXwfgXxfiXxfkQzW4-_WuZdV7n11AxjfMr4921ldSPVPST416J2we8f4YpiYjBPj0-7-TPPJT_YM36HA55F8XY1_iRb_hBoznpIiDqeiVnTJ11v-ZynfIaBvL37DFvNJoqpG_p5b5JCnQYde1M3kim7-etW8XmoXB9cKvZAKq-Npr1MOLNZoqdYIz-FBCN-i8b5z1OyD6b2pCqN8ZOye8e0XxrcfPyW5NqZOBg0LAllR-Oc-KExjHsjuwNTV5h3klWTmxnQenDmcPkmCRogfgM7kY-tUypSh6HOQ2nmqUFOH41vEeD6plmmVp7mY4DKZZ3Eax3GaTJrlbBpXWZwukmSKWBSzYlpiXpaY5HGST0U2kUse8yyeJXnM-TxJonxa1FxMyyLDxWKelWwaYyukipT63BIHE-lcj8tkOl3wbKJEgcodvqMNsh6-odklvX9T9HvHprGSzruvFrz0Knx7CxOyDctuRwWnfFn31qL26ptje9BkIngU5eeUZdJbtbyIovRNX0Rl2CcRksPPTWfNJyw949vgmGN8e_Dt85L_EwAA__-BTBj0">