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

    <tr>
        <th>Summary</th>
        <td>
            `linalg.index` shouldn't be marked as `Pure`.
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

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

    <tr>
      <th>Reporter</th>
      <td>
          erick-xanadu
      </td>
    </tr>
</table>

<pre>
    Currently `linalg.index` is marked as `Pure` which leads to different `linalg.index` operations to be eliminated via CSE. This will mean that `linalg.index` operations with the same operands yet on different enclosing scopes will be transformed leading to bad iteration indices.

Consider the following example:

```mlir
 linalg.map outs(%alloc_4 : memref<2x3x2xf64>)
      () {
        %3 = linalg.index 0 : index
        %4 = linalg.index 1 : index
        %5 = linalg.index 2 : index

 // ... snip ...

        linalg.generic {indexing_maps = [#map1], iterator_types = ["parallel", "parallel"]} outs(%alloc_12 : memref<3x2xf64>) {
        ^bb0(%out: f64):
 %9 = linalg.index 1 : index
          %10 = linalg.index 0 : index
 %11 = arith.cmpi ult, %10, %c1 : index
          %12 = scf.if %11 -> (f64) {
            %13 = memref.load %expand_shape_9[%10, %9] : memref<1x2xf64>
            scf.yield %13 : f64
          } else {
```


After applying CSE the constants inside linalg.generic get eliminated:

```mlir
  linalg.map outs(%alloc_4 : memref<2x3x2xf64>)
    () {
      %3 = linalg.index 0 : index
 %4 = linalg.index 1 : index
      %5 = linalg.index 2 : index
// ... snip ...
      linalg.generic {indexing_maps = [affine_map<(d0, d1) -> (d0, d1)>], iterator_types = ["parallel", "parallel"]} outs(%alloc_12 : memref<3x2xf64>) {
      ^bb0(%out: f64):
        %9 = arith.cmpi ult, %3, %c1 : index
        %10 = scf.if %9 -> (f64) {
          %11 = memref.load %expand_shape_9[%3, %4] : memref<1x2xf64>
          scf.yield %11 : f64
```

Later after lowering to loops:

```

 scf.for %arg1 = %c0 to %c2 step %c1 {
      scf.for %arg2 = %c0 to %c3 step %c1 {
        scf.for %arg3 = %c0 to %c2 step %c1 {

// ...snip...

          scf.for %arg4 = %c0 to %c3 step %c1 {
 scf.for %arg5 = %c0 to %c2 step %c1 {
              %6 = arith.cmpi ult, %arg1, %c1 : index
              %7 = scf.if %6 -> (f64) {
 %8 = memref.load %expand_shape_9[%arg1, %arg2] : memref<1x2xf64>
```


But the last line should be `memref.load %expanded_shape_9[%arg4, %arg5]`

</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzEVk1vqzgX_jXOxioCG0hZsGiTdvUuXunOvjL4EDzX2Mg2N8m_H9nQJuSjJdJIgyKCjs_n4_Mcm1krdgqgRNkryrYrNrhWmxKMqH8_HZhifFhVmh_LzWAMKCePGOWxFIrJXSQUhwPKYyws7pj5DRwz69f_Pxjw8n0r6hZLYNxipzEXTQPeyy0fugfDnNAqqFaAQYpOKOaA4z-C4c2vtwj_1QqL90JK3AFT2LXsJ1974VrsWsCWdTAuKG7xERzW6iwjULXUVqgdtrXuYYpSAXaGKdto0wEPlXgVnyDjWLgpDBaKixpshOItil_G90YrKziYEL3RUuq9t4UD63oJiL6cK6M8Hn-dFGYU4amqjvVYD84i8oxIxqTU9UeKEX3BHXQGGkQ35EAP5NDkKaJviBSTfXiCVYHR-vVc6uUZxYhu8Tl2OA5-Rxwv1dNr9eQb9exanVyqT0aIvCPyjqMowlaJ3n_M1qdn8rUD5dvTlxRcCbX76FhvQzzfxoR2rE9QtkVkM-2RNh_u6Hf1S4f0zDApQSJCvN6FJNui9fYK9oTMcZ-hfgPj7K2q4tGBHpw39dqk-Np8D1TxAK4B2SResnFeMQmKzAjXRnXXCzxINxabJfH0Uf8QjAQftm4i0UxOnxB98401FnNd96fp2GAjWpHUjHspHHqm-IdtWQ8fRdiLUzIFyrZziJMTxFcxfFJHAZJ_RRsBvqxivcUgLZwS_WLbjILh_dI4MJj1vTx6tm5-vQX-1lpZx5SzWARWXzbjDtzZwFpA7n-D3be5vZTZD1F6KaHvMfkhBrOmEQq8CNENIs88tAdPfLGfvXcm87D812RfQPUTMYr7tKQ_svI0AE6cLBZQ8jQPFhDyM430AT7O2ZjM2XiTcf9jgWuBcVLvwUxnq9S6t_c4NDsZfMxGGx-Rmd1Ynkcv9m78B8HWQf-J6ByVuTG5NqbfGF-a06WxL4nieXLnwLuMkS5OcW6XPYbLWcfk9zvV473gCJkcrS86Nr_fsYhkz0v79CwJv4U_dus3g_91cGHSS2adH1SAbasHyf0d0I_uW8nAdTrpKZ3MD5bPUCteUl7Qgq2gTPJnus5IQbJVW-Z5lRb5Os6rCmKaJHGV8iZN4pRlNOV5shIliQmNsyQmSfycZlFaVwnNacw4JTWpGEpj6JiQkZR_ukib3UpYO0CZkzxNV5JVIG05zkEFexwWx7G3MqW3eaqGnUVpLIV19uTFCSehvHG9HoFRiKydR-fW1T9aDUaWrXMjkUO374RrhyqqdYfIu48y_T31Rv8NtUPkPeRmEXkPuf8TAAD__yoIes4">