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

    <tr>
        <th>Summary</th>
        <td>
            [mlir] Using interfaces as keys in `llvm::DenseMap` leads to usage of invalid pointers
        </td>
    </tr>

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

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

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

<pre>
    The issue manifests in crashes when using an interface as they key for a `llvm::DenseMap` or `llvm::DenseSet`. Doing operations on the map will eventually lead to a crash. The current workaround (for `mlir::OpInterface`s) is to simply use `mlir::Operation*` instead, but it'd be a lot better code clarity wise to be able to use interfaces.

I believe this is likely to be the case for all kinds of interfaces, but I have only checked this and followed the call chain for op interfaces. 

The issue in short is, that `mlir::OpInterface`, being a subclass of `mlir::OpState`, uses the `llvm::DenseMapInfo` for subclasses of `mlir::OpState` which in the tombstone case, creates invalid pointers that are later dereferenced in the constructor of interfaces. 
The particular call chain is:
https://github.com/llvm/llvm-project/blob/2c14cdf831b677063a6518904b765c1f08d8557b/mlir/include/mlir/IR/OpDefinition.h#L1970-L1979
For the `llvm::DenseMapInfo` specialization used for any `mlir::OpInterface`. Note that `getEmptyKey` and `getTombstoneKey` of `llvm::DenseMapInfo<void*>` return invalid addresses used as sentinels. 
It then calls `T::getFromOpaquePointer`, which in the case of `mlir::OpInterface` goes to the implementation in `mlir::Op`:
https://github.com/llvm/llvm-project/blob/2c14cdf831b677063a6518904b765c1f08d8557b/mlir/include/mlir/IR/OpDefinition.h#L1697-L1700
Which simply calls the constructor of the actual concrete type using the pointer value. In the case of `mlir::OpInterface` the constructor called is here:
https://github.com/llvm/llvm-project/blob/2c14cdf831b677063a6518904b765c1f08d8557b/mlir/include/mlir/Support/InterfaceSupport.h#L91-L93
Leading to `t` being dereferenced in the implementation of `getInterfaceFor`.

I am guessing this could either be solved with a specialization of `llvm::DenseMapInfo` for `mlir::detail::Interface`, or probably even better if possible, an implementation of `getFromOpaquePointer` in `mlir::detail::Interface`. Haven't investigated however. 
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzNVtty4zYM_Rr5hRONLpZtPfgh3aynnqZNp8lOnykSstjQokpSzni_vgAp5-I4afu2M76SFHBwcACwMfK4fuiAKedGYHveqxacd0z1TFjuOnDsqYOejU71O8Z73PBgWy6Accd8B0f2iO_WWMZZssi0PuyT8hpfN9A7-JUPuMhw9_3ePXhcTNmNIdNmAMu9Mr1jpifDCGZgT0prBgfo_ci1PjINXDJv0FdAlzLCLkZr8QR7MvaRWzP2kiXFqo1O91rZ6PRu2J6w47pLihqjJmNO7Qe0PTo4f2CClBTXFIXqnUf_SfGFNaNnyifFUrIGmWDaePzh0TwTRiIkza3yR8SPRtEFHWp0-Elunkl0aZLdJNl1_NziOa0wXIwfoeFLq0dAaNECkSI4Ph7YRmIeVS-RrvaVvRO4Les42jE9Pi06EI8go1GO7LRGa_MUVsgiWhIdx4yTXTO8Rsdew3vRCZ51nbHIQXDoO-4_4zqAgiAg5sYGyXEB9tkj957703FkKcjrsqa2fWsoIwT4ZBA-M4kiVqIj3GTTm33jvOkjneROWMCDJPsD10qywQQSXAyNW2CaU3IlWGjx3Qtkb7ImULPejsITe-0F9oi3gVuvxIiyeE040ldO5HbeD-FfscHXTvlubFJh9vgnxB-_rgZr_gKByts02jT4VYh8LmS7KvNmsVxmi5IvqnxVZ_NmuahE3mYruaqqJR0NxBQb1Qs9SnhZ2P6BH3fDDbSqV6T3tEuK8javl9kVfdYR4Qbj-9eMuAGEQgq_h8KhNMoo1_74mUJS9pvx8CykHfiv-8Eff4EjGSXNxtWHU-amnZjxD-CUXw5GSSre8isdtuBH2z_nmEtpIegmoMR25rCLqB70c-a2niLuQ8oceXqIbhDJxpr93cD_HuH3qJVJuG-EFqr1vSpfR852BkIXovPUiGCPKCJ7aOXsSXLyAytmUS9RMcssiwj_DFxM7TVyeKFgaIkLavC0g5VIQjgOMM0c2p7KkWHiRkjZ9r-ze-6PUFDpOtZhGf8IXN6Pw4CtlFg9AZ-WIql1fnVblxHmLY6fwImhoGl8Tn31Ul86E1MkCpX77AYLmkrv7QTie7YbsSwi9ciTMKOWDJASTABOIWf0AZ084QK187f1_mk9Tg37TbokeK50_H0-MvAsEt7g4DyGO8BpwqoWBYEIcaDSMbqUfBDqpSJ9V1UfQUjZzzhCcfgvPfUMvBapHQ4ByTqcnQewKZvJdSnrsuYzr7yGdVL9FMxWN-xbIPBlFlB7wYuSm7xfvibR7cbFOwLfQRwmb-fRbLR6_b_FGoY2TupNNa-z1axbr4psURX5AuqyyvNsXkkUblbMmzqXq7IuZ5rjTcRRQElRTFQJgwVTFBjdTK2LrCiyeT7Ps3I1z1KQ2XyRS7GqMl7lZZnMM9gjqykhSY3dzew6gGrGncNNrfCS-bKJ41vteggMkn0-erxerL-DNXW-XM1CAOuA_h_oNYNV">