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

    <tr>
        <th>Summary</th>
        <td>
            Tensor Dialect canonicalizer `FoldTensorCastProducerOp` can produce invalid IR
        </td>
    </tr>

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

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

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

<pre>
    
Reproducer: 

```mlir
// RUN: mlir-opt -canonicalize
func.func @materialize_in_destination_tensor_cast(%arg0: tensor<4xf32>, %arg1: index) -> tensor<?xf32> {
  %0 = bufferization.alloc_tensor(%arg1) : tensor<?xf32>
  %1 = tensor.cast %arg0 : tensor<4xf32> to tensor<?xf32>
  %2 = bufferization.materialize_in_destination %1 in %0 : (tensor<?xf32>, tensor<?xf32>) -> tensor<?xf32>
  return %2 : tensor<?xf32>
}
```

`FoldTensorCastProducerOp` defined in `lib/Dialect/Tensor/IR/TensorOps.cpp` assumes that any operand of an op that implements `DestinationStyleOpInterface` can absorb a `tensor.cast` operation that is erasing information from the type. However, that assumption is not encoded anywhere in the spec of `DestinationStyleOpInterface. For example, `bufferization.materialize_in_destination` requires that the shapes of its DPS input and DPS output operands match, and therefore the canonicalizer will produce IR that fails verification :

```
within split at test/Dialect/Bufferization/canonicalize.mlir:392 offset :6:8: error: 'bufferization.materialize_in_destination' op failed to verify that all of {source, dest} have same shape
  %2 = bufferization.materialize_in_destination %1 in %0 : (tensor<?xf32>, tensor<?xf32>) -> tensor<?xf32>
       ^
within split at test/Dialect/Bufferization/canonicalize.mlir:392 offset :6:8: note: see current operation: %1 = "bufferization.materialize_in_destination"(%arg0, %0) : (tensor<4xf32>, tensor<?xf32>) -> tensor<?xf32>
```

</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzMVt9vozgQ_mvMy6jIGAjNAw9pU3R9ua66e8-VMUPwydicbfpj__qTDdnkqly30umkjSKQmfHMN9-MP-DOyYNGrEl5Q8p9wmc_GFuLwUrnzTSgbbnHpDXdW03ontDdI07WdLNAS_IdLM_W64Yu_1FJuz5iDWENPP7xe3AOz6_M5OFKcG20FFzJ77h49rMWabgAKejIPVoZrU9SP3XovNTcS6OfPGpn7JPgzhN2TVjJ7YGG4IuB5LfFa58zkt8RdguLPQt2qTt8JWwLVyS_O3mTvFn9gVQ3CxYI-yiQfA_t3Pdo5feYPOVKGbFC-JE9C0H_geAU8yxeFuMtPmmAv4KjcBE9ePOTgOwCwH8nboEg9bG0HRB2fSkBu72Y9wPijpgs-tnqI7QP-CDV_t3EvBujxqjuW9x9y53_ss7bw0Q2FDrspcYulrKhSraENXvJFQpPWPNt7U1z__hj9TC5VExxM3duHtGBH7gHrt_ATGi57sD0wDWYabHIcVI4ovYu5NifWPzq3xQ-TPfao-25wBBTcA28dca2wIP7WYuDOWaIHVhCO0DLndQHkLo3dlxsvTUj-AHBv02Ywm_mBZ_RxmZEqAH3FD2lA208oBamwy4U8TKgxcBH2O8mFKGaj3Gn0BgL-MpDofGgbOhnJykUZfGvWdojkTHvwCd0IbP0DvZfvoLU0xxI7uLKzD4sV74djNyLIWQODj5U0BuLMdS5OFh4kUrBKjlw_7hk7LlUDp7Ryl6Kdb7z3UUxWpYv0g9Sg5uU9BAgY9CPs8G5Oa-esOYcRBoFLd_lWwam7x36kG1D8t11mHO01ixiyKpPk8iqMG2hDuzCWY-1vK3dViq2sLpxZrYiNijsJdUeBv6M4Pi4Mv4r60H8kfLu_--ANh7D3SGCmK1F7U_nbqlt1V_C2OdbxM7eMMvLhB61_pys4r9S9W5Wk67Ou22-5QnWWZWVlFVZVSVDzVpaCFGw6zLP--ue51hUGaV9WVRdkWGWyJpRVtCSbhhlm6xKSy6wYjlFzlhebAtSUBy5VKlSz2Nq7CGRzs1YbzO2KRPFW1QufgowpvEFojHwUO4TW4c9V-18cKSgSjrvTlG89ArrRW5hbem7c_wTWQ8qejzlUj9zJTu4f0xmq-rB-8mF4x0_Jg7SD3ObCjMS1gQA6-1qsubPZZIibEdYE8v6OwAA__8cZ9RJ">