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

    <tr>
        <th>Summary</th>
        <td>
            Inconsistent result with --sparsification-and-bufferization and tensor.empty
        </td>
    </tr>

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

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

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

<pre>
    Consider the following MLIR program:
a.mlir:
```
module {
  func.func @tensor_i32(%arg0: tensor<1xi32>) -> i32 {
    %idx0 = index.constant 0
    %0 = tensor.extract %arg0[%idx0] : tensor<1xi32>
    return %0 : i32
  }
 func.func @func1() {
    %c1_i32 = arith.constant 1 : i32
    %c0_i32 = arith.constant 0 : i32
    %c0 = arith.constant 0 : index
    %5 = tensor.empty() : tensor<1xi32> // using empty
    // %5 = tensor.from_elements %c0_i32 : tensor<1xi32>
    
    %inserted_28 = tensor.insert %c1_i32 into %5[%c0] : tensor<1xi32>
    %31 = call @tensor_i32(%inserted_28) : (tensor<1xi32>) -> i32
    %308 = tensor.extract %5[%c0] : tensor<1xi32>
    // vector.print %31 : i32
 vector.print %308 : i32
    return
  }
}
```

It will output two different results when applying two different optimization pass sequences:
```pass sequence1```: ```--sparsification-and-bufferization --tensor-bufferize --func-bufferize --convert-func-to-llvm --convert-index-to-llvm --convert-vector-to-llvm --finalize-memref-to-llvm --convert-arith-to-llvm --reconcile-unrealized-casts```
```pass sequence2```: ```--tensor-bufferize --func-bufferize --convert-func-to-llvm --convert-index-to-llvm --convert-vector-to-llvm --finalize-memref-to-llvm --convert-arith-to-llvm --reconcile-unrealized-casts```

The ```pass sequence1``` outputs the executable that outputs 1, while the latter outputs 0.
The difference between ```pass sequence1``` and ```pass sequence2``` is that there is an additional ```--sparsification-and-bufferization``` at the begining of the ```pass sequence1```.

I futher analyze the output of these two sequences:
pass1: ```--sparsification-and-bufferization --tensor-bufferize```
pass2: ```--tensor-bufferize```
The result of ```pass1``` is:
```
module {
  func.func @tensor_i32(%arg0: memref<1xi32>) -> i32 {
    %idx0 = index.constant 0
    %0 = memref.load %arg0[%idx0] : memref<1xi32>
    return %0 : i32
  }
 func.func @func1() {
    %c1_i32 = arith.constant 1 : i32
    %c0 = arith.constant 0 : index
    %alloc = memref.alloc() {alignment = 64 : i64} : memref<1xi32>
    memref.store %c1_i32, %alloc[%c0] : memref<1xi32>
    %0 = call @tensor_i32(%alloc) : (memref<1xi32>) -> i32
    %1 = memref.load %alloc[%c0] : memref<1xi32>
    vector.print %1 : i32
    return
  }
}
```
The result of ```pass2``` is:
```
module {
  func.func @tensor_i32(%arg0: tensor<1xi32>) -> i32 {
    %0 = bufferization.to_memref %arg0 : memref<1xi32>
    %idx0 = index.constant 0
    %1 = memref.load %0[%idx0] : memref<1xi32>
 return %1 : i32
  }
  func.func @func1() {
    %c1_i32 = arith.constant 1 : i32
    %c0_i32 = arith.constant 0 : i32
    %c0 = arith.constant 0 : index
    %alloc = memref.alloc() {alignment = 64 : i64} : memref<1xi32>
    %alloc_0 = memref.alloc() {alignment = 64 : i64} : memref<1xi32>
    memref.copy %alloc, %alloc_0 : memref<1xi32> to memref<1xi32>
    memref.store %c1_i32, %alloc_0[%c0] : memref<1xi32>
 %0 = bufferization.to_tensor %alloc_0 : memref<1xi32>
    %1 = call @tensor_i32(%0) : (tensor<1xi32>) -> i32
    %2 = memref.load %alloc[%c0] : memref<1xi32>
    vector.print %2 : i32
    return
 }
}
```

It seems that ```--sparsification-and-bufferization --tensor-bufferize``` treats the operand and the result of ```tensor.insert``` as same tensor(memref), 
when the operand of ```tensor.insert``` is created by ```tensor.empty```.

If I replace the ```tensor.empty``` with ```tensor.from_element```, or just wrap the ```tensor.empty``` with a function. The modified MLIR program will output the same result.
The modified program:
```
module {
  func.func @gen_tensor_i32() -> tensor<1xi32> {
    %c0_i32 = arith.constant 0 : i32
    %5 = tensor.empty() : tensor<1xi32>
    return %5 : tensor<1xi32>
  }
  func.func @tensor_i32(%arg0: tensor<1xi32>) -> i32 {
    %idx0 = index.constant 0
    %0 = tensor.extract %arg0[%idx0] : tensor<1xi32>
    return %0 : i32
  }
  func.func @func1() {
 %c1_i32 = arith.constant 1 : i32
    %c0_i32 = arith.constant 0 : i32
 %c0 = arith.constant 0 : index
    %5 = call @gen_tensor_i32() : () -> tensor<1xi32>
    // %5 = tensor.empty() : tensor<1xi32> // using empty
    // %5 = tensor.from_elements %c0_i32 : tensor<1xi32>
    
 %inserted_28 = tensor.insert %c1_i32 into %5[%c0] : tensor<1xi32>
 %31 = call @tensor_i32(%inserted_28) : (tensor<1xi32>) -> i32
    %308 = tensor.extract %5[%c0] : tensor<1xi32>
    // vector.print %31 : i32
 vector.print %308 : i32
    return
  }
}
```

I wonder if there is some thing wrong with ```--sparsification-and-bufferization``` and ```tensor.empty```.
This result inconsistency may not be a problem because ```tensor.empty``` should only contains the shpae information.

git version: 2163ae761808ca0e5478357384f6ddbacce279eb
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsWUtv2z4S_zT0ZWBDoiw_Dj6kSQME2L0sejcoaWSxoEgtScVxP_2ClGVLtvxqG6Bb_IFEtsjhcDjzmwfHzBi-kYgrEn8h8cuI1bZQevUkldyVqjZhHC_pKFHZbvWspOEZarAFQq6EUFsuN_Dvf739ByqtNpqVJHoiwQsJntikFFwfXsks2P_511JltUAg8y_NO0Bey3TiHkCmgUVplF7ziBK6IDRmehOQ6AmacRI9hx9uLvpK6BLGJPoKPKJdbgCExjz7CIBEL8Blhh-TVEljmbQQ9KgakobzBD-sZqmFds_4y54PiV9gWIIDL4221rJl-eREaifJ_GX_tXdM9xn6Ey7PhE_DtT9T9AJMc1scxQ9PuTf0wSX6M2n29Fdonb561HFPSWVld63YQzoBQl8JfYXaOHg05B1ufu6Uaa5VuUaBJUprege6qvS-waVBbTFb00WXdTPcUSqXVnkBGvum91iX0DgKPdeUCTEE0s7urWYIXVyFbJ99sLgAxcfk9Op9x9QqPak0l_YgexcFZwR-9xOcNJA-Q_HxS9-rm-ebhS0XAlRtq9qC3SrIeJ6jRmlBo6mFNbAtUAKrKrFzEOnTqMrykv9glisJFTMGDP63RpmiOY8nvfnwKJDTfvsyHpuKacNznnqmYyazcVK7_dptxuNGp4dhhPHY-WdvIFXyHbVtJqwaC_Fedoa93wyMN7ruTORcMsF_4LjEUmM-sMT7ZWdcY6pkygWOa6nRL87GKTPWnNpgUDH0kmL-llP757cC4RYw9rA0PofhB6a1ZYlAsAWzh7mQ0GfYFtyPIwhmLerDbDA5bteiNkVI0G4R5W0JmMwuEB3NBNw0ItkCNbo3JoFlGXdoZeIRbHc29uwgwQ2Xzu1U7t9vCTzpeTfktZMJmGRi96NR0N7VG34GvT-f-6xjH_66Y56Y3nGlN1B9ssQZrglETuTe8cOuBX5z9dLA_jOql4bzRCiWXS5dzrf_Y0qXR0oRJoRKu6f2A0dRmOAb6aoITzObNmxmUzK_qYY9Q2OVxuNBXCxo9z1NxFeYHYxzqV7Yy32oFK7Co8c3HDT6g_KdFgADtnkw_V9xK_qJbvXYpaCxSS_GTKxaN4pqnecO297nnoOWesA3j455Zp6jY_6_Xio-0ZNb7uvgUyNFqqrd0fc6cWJ9AUJg1a8FoHVwr4tfxnrjMDdlHQDypVAW_NSFh35GGKM3wtj9lxiDWO6LsN9UsIDVyPalp6pQu0LQ_dvhwNm7vnaqOAOGldjGvUPioEsPFC--v151t7mDLzeQOvkwg2R3Rt3c4odLwhzeQGMlWIr9gnJwLWy5Lc5ouvf_o0XoMygN32tjYatZdTd35mOiBzy4tFSqjOccs16vqn9NLbBRa2OITol_WHva4nosfW1Qrk_8Zu8XA_2T07j9YBx-rF0zVAfG10kvJZ-_t3F3T5L91Az7kz27NmQPwm8fsi8j8Wbb7g_sBX5mI_CfLuDdCRS2SmaogefHHoZRLm8VDglbrdyzlwoe6mV0myjXctS3gps2u3LpvIYbizLdQcl2IJWFBIG54J4ILCHBlNXmZpYxhapFBkqKHaRKWsZlk9dNUTEELnOly6bi6mplwy28ozbuKNET0HAWMZzPwkWwSFmA8XS-iOJ5tJjmsyxLWJoinS8xGWWrKFtGSzbCVTgP49ksDqPFqFglNJnHs2CxQEbjWZDSRTrNglkwi0OWh5iP-IoGdBrE4TSIo0W8mNCEMpzGMbI8CREpmQZYMi4mQryXE6U3I25MjaslDWbLkWAJCuN_GqJU4hb8JKGUxC8jvXJrxkm9MWQaCG6sOXKx3ApcvR0V3vZ-G5vfUUj5yqij_FGtxaqwtvIXSA_wDbdFnUxSVRL66rbef4wrrb5jagl99QIbQl_9gf4XAAD__-ZywhQ">