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

    <tr>
        <th>Summary</th>
        <td>
            [mlir][func] Duplicate function elimination pass can create invalid IR
        </td>
    </tr>

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

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

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

<pre>
    In the duplicate function elimination logic [here](https://github.com/llvm/llvm-project/blob/main/mlir/lib/Dialect/Func/Transforms/DuplicateFunctionElimination.cpp), there are a couple bugs:

1. It is not checked whether a function has a body or not, so in the below `some_external_func2` will be replaced with `some_external_func`:

```mlir
func.func private @some_external_func(i32, i32) -> i32
func.func private @some_external_func2(i32, i32) -> i32

func.func @some_caller(%arg0: i32, %arg1: i32) -> (i32, i32) {
  %0 = func.call @some_external_func(%arg0, %arg1) : (i32, i32) -> i32
  %1 = func.call @some_external_func2(%arg0, %arg1) : (i32, i32) -> i32
  return %0, %1 : i32, i32
}
```

2. The logic assumes that the only users of the `func.func` symbol are  `func::CallOp` ops, but it doesn't check this. There could be other users (e.g. `func.constant`, ops not in upstream, or even just a discardable `SymbolRefAttr` in any op). These symbols will still refer to the removed function symbol at the end of the pass.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJykVEuPozgQ_jXmUhoE5hE4cOhuJlKfVpqd-8iYInjW2Mg26c2_X5VJOr09s4_WSAlGRfl7lF0lvFcng9ix6pFVfSK2MFvXydkpH-w6oxtEwGSw46V7NhBmhHFbtZIiIEybkUFZA6jVooyI79qelARWPc7okFU9480cwupZ8cD4kfHjSYV5G1JpF8aPWp9vy6fV2e8oA-PHQduB8eMilKFFK0c5imK9EnpPOm5GMn786oTxk3WLp683bcertM93ZalcV8Zbxp_IhkMQ9Adpt1UjDNspSsx6ll2feQrPAZQHYwPIGeUfOMLLjLQbxN39LDwIoBKBdZRMFN6C2us1oLYvwOrM2wW_4Z8BnRH6G23nrM7gRWkNA4LDVQtJFCrMP89ndfZOI0XiLxYphigxpQesTp3pnFj5MyzeqIKT1Li08IkVn-P7R1D4f8C8B7uBSKE1OsYbxivhTmQLrjh7JH-NXCF_IGKHxx0daEsGrOjjmaSE_Y-eb3xviAirePiR4O9OIkv-f1j4r9E4DJsz0dN1ew5vynMv7aF_dwfelpyn8HXGazcK77cFPYRZhHgnrdEX2Dw6D3aKEVZnr6dEt9JflsHq2CO3b3T1iocnofVvK6XY1ZOgYQugAowWvWH8cG0VCLPyUYND6jE90h23sXd2YsYbTE_pK7O0xgdhAhnhT4QeG08Z2FYfHIolhh3gGQ1833wAAaPyUrhRDDpa-D2q_oLTQwiONCoDwlzAUudHNR6v1vzeeD7Q0-GEDoKNpXC42DOO9wa_1WKvHZrxVrRVeJ8mY1eMbdGKBLv8kNcNP-SHKpm7sm3quhnaRo5lmY2yKcfDUPOqrCSfsGkT1fGMl1nFD3nN67xKp2ySYztWouZyyqaBlRkuQumU5mNq3SlR3m_YtUXZFIkWA2ofJzfn-5DkNMNdF8dpnGhlppUP_g4QVNBx2scNVc-qx3i2VQ_9vw92MgtSGJAOKUmZs9BqhOcvyeZ09-EhH63Q0N7dnDv-VwAAAP__kU0MUg">