<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/62376>62376</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[MLIR] Custom `malloc`/`free` functions with signatures differing from libc and private symbol visibility cause llvmir dialect module -> llvm IR conversion to fail
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
J-MR-T
</td>
</tr>
</table>
<pre>
Commit: 1f1fea6c380e
Steps to reproduce:
1. Take this file:
```mlir
module {
llvm.func @free(i64) -> i64 attributes {sym_visibility = "private"}
llvm.func @foo() -> i64 attributes {sym_visibility = "private"} {
%0 = llvm.mlir.constant(0 : i64) : i64
%1 = llvm.call @free(%0) : (i64) -> i64
llvm.return %0 : i64
}
}
```
2. And run it through e.g. `mlir-translate`: mlir-translate --mlir-to-llvmir test.mlir
This results in this assertion failure: `/path/to/llvm-project/llvm/lib/IR/Instructions.cpp:652: void llvm::CallInst::init(llvm::FunctionType*, llvm::Value*, llvm::ArrayRef<llvm::Value*>, llvm::ArrayRef<llvm::OperandBundleDefT<llvm::Value*> >, const llvm::Twine&): Assertion ``(i >= FTy->getNumParams() || FTy->getParamType(i) == Args[i]->getType()) && "Calling a function with a bad signature!"' failed.`
Backtrace:
```
Stack dump:
0. Program arguments: mlir-translate --mlir-to-llvmir mlirCallTest.mlir
#0 0x0000564fc03fafee llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/usr/local/bin/mlir-translate+0xc73fee)
#1 0x0000564fc03f8a7b llvm::sys::RunSignalHandlers() (/usr/local/bin/mlir-translate+0xc71a7b)
#2 0x0000564fc03f8bb5 SignalHandler(int) Signals.cpp:0:0
#3 0x00007f059c569f50 (/usr/lib/libc.so.6+0x38f50)
#4 0x00007f059c5b88ec (/usr/lib/libc.so.6+0x878ec)
#5 0x00007f059c569ea8 raise (/usr/lib/libc.so.6+0x38ea8)
#6 0x00007f059c55353d abort (/usr/lib/libc.so.6+0x2253d)
#7 0x00007f059c55345c (/usr/lib/libc.so.6+0x2245c)
#8 0x00007f059c5629f6 (/usr/lib/libc.so.6+0x319f6)
#9 0x0000564fc02dd2e8 llvm::CallInst::init(llvm::FunctionType*, llvm::Value*, llvm::ArrayRef<llvm::Value*>, llvm::ArrayRef<llvm::OperandBundleDefT<llvm::Value*>>, llvm::Twine const&) (/usr/local/bin/mlir-translate+0xb562e8)
#10 0x0000564fbfb827a4 llvm::IRBuilderBase::CreateCall(llvm::FunctionType*, llvm::Value*, llvm::ArrayRef<llvm::Value*>, llvm::Twine const&, llvm::MDNode*) (/usr/local/bin/mlir-translate+0x3fb7a4)
#11 0x0000564fbfb9af55 convertOperationImpl(mlir::Operation&, llvm::IRBuilderBase&, mlir::LLVM::ModuleTranslation&) LLVMToLLVMIRTranslation.cpp:0:0
#12 0x0000564fbfd38b1b mlir::LLVM::ModuleTranslation::convertOperation(mlir::Operation&, llvm::IRBuilderBase&) (/usr/local/bin/mlir-translate+0x5b1b1b)
#13 0x0000564fbfd417b4 mlir::LLVM::ModuleTranslation::convertBlock(mlir::Block&, bool, llvm::IRBuilderBase&) (/usr/local/bin/mlir-translate+0x5ba7b4)
#14 0x0000564fbfd43f6f mlir::LLVM::ModuleTranslation::convertOneFunction(mlir::LLVM::LLVMFuncOp) (/usr/local/bin/mlir-translate+0x5bcf6f)
#15 0x0000564fbfd4481b mlir::LLVM::ModuleTranslation::convertFunctions() (/usr/local/bin/mlir-translate+0x5bd81b)
#16 0x0000564fbfd4830e mlir::translateModuleToLLVMIR(mlir::Operation*, llvm::LLVMContext&, llvm::StringRef) (/usr/local/bin/mlir-translate+0x5c130e)
#17 0x0000564fbf85f32b std::_Function_handler<mlir::LogicalResult (mlir::Operation*, llvm::raw_ostream&), mlir::registerToLLVMIRTranslation()::'lambda'(mlir::Operation*, llvm::raw_ostream&)>::_M_invoke(std::_Any_data const&, mlir::Operation*&&, llvm::raw_ostream&) ConvertToLLVMIR.cpp:0:0
#18 0x0000564fbfae903b std::_Function_handler<mlir::LogicalResult (std::shared_ptr<llvm::SourceMgr> const&, llvm::raw_ostream&, mlir::MLIRContext*), mlir::TranslateFromMLIRRegistration::TranslateFromMLIRRegistration(llvm::StringRef, llvm::StringRef, std::function<mlir::LogicalResult (mlir::Operation*, llvm::raw_ostream&)> const&, std::function<void (mlir::DialectRegistry&)> const&)::'lambda'(std::shared_ptr<llvm::SourceMgr> const&, llvm::raw_ostream&, mlir::MLIRContext*)>::_M_invoke(std::_Any_data const&, std::shared_ptr<llvm::SourceMgr> const&, llvm::raw_ostream&, mlir::MLIRContext*&&) Translation.cpp:0:0
#19 0x0000564fbfae4d78 mlir::mlirTranslateMain(int, char**, llvm::StringRef)::'lambda'(std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>>, llvm::raw_ostream&)::operator()(std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>>, llvm::raw_ostream&) const MlirTranslateMain.cpp:0:0
#20 0x0000564fbfae4ff9 mlir::LogicalResult llvm::function_ref<mlir::LogicalResult (std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>>, llvm::raw_ostream&)>::callback_fn<mlir::mlirTranslateMain(int, char**, llvm::StringRef)::'lambda'(std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>>, llvm::raw_ostream&)>(long, std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>>, llvm::raw_ostream&) MlirTranslateMain.cpp:0:0
#21 0x0000564fbfaf10ab mlir::splitAndProcessBuffer(std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>>, llvm::function_ref<mlir::LogicalResult (std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>>, llvm::raw_ostream&)>, llvm::raw_ostream&, bool, bool) (/usr/local/bin/mlir-translate+0x36a0ab)
#22 0x0000564fbfae5c13 mlir::mlirTranslateMain(int, char**, llvm::StringRef) (/usr/local/bin/mlir-translate+0x35ec13)
#23 0x0000564fbf83acc9 main (/usr/local/bin/mlir-translate+0xb3cc9)
#24 0x00007f059c554790 (/usr/lib/libc.so.6+0x23790)
#25 0x00007f059c55484a __libc_start_main (/usr/lib/libc.so.6+0x2384a)
#26 0x0000564fbf8500e5 _start (/usr/local/bin/mlir-translate+0xc90e5)
```
I understand this signature for free doesn't make any sense at first glance. I encountered this in a compiler for a (more or less toy) language which only has `i64` as a type, and all functions have a signature of the form `i64* -> i64`. Using normal LLVM IR, this works flawlessly, but the conversion from the llvmir dialect to llvm IR seems to be tripped up by `free` as a name for a function with this signature (even though it has private symbol visibility, but as far as I can tell, that get's lost in translation to LLVM IR anyway).
In examples where the translation works, I can see that declarations for `malloc` and `free` (with their 'correct' signatures) seem to get inserted regardless of my source mlir module (and I can't find a way to disable these declarations), which seems to be the root cause of this issue:
If I change the input file to this:
```mlir
module {
llvm.func @freee(i64) -> i64 attributes {sym_visibility = "private"}
llvm.func @foo() -> i64 attributes {sym_visibility = "private"} {
%0 = llvm.mlir.constant(0 : i64) : i64
%1 = llvm.call @freee(%0) : (i64) -> i64
llvm.return %0 : i64
}
}
```
this is the result of the llvmir translation:
```llvm
; ModuleID = 'LLVMDialectModule'
source_filename = "LLVMDialectModule"
declare ptr @malloc(i64)
declare void @free(ptr)
declare i64 @freee(i64)
define i64 @foo() {
%1 = call i64 @freee(i64 0)
ret i64 0
}
!llvm.module.flags = !{!0}
!0 = !{i32 2, !"Debug Info Version", i32 3}
```
Note the declarations for free and malloc, and that they seem to get inserted before declarations in the translated module.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsWktz47gR_jXwpcsqChRfBx9kaVVxarw75XH2qgLJpoQYBBQAtEf_PgWQEklJXj92M5tspWpGlkigH19_3WgQZMbwjUS8IdEtiZZXrLFbpW_-fn3_cP14latyf7NQdc0tCecwraYVsrgI0wBJsCTBvP38ZnFnwCrQuNOqbAokYXdrOoFH9oRgt9xAxUV_h8RB-68WXLeXalU2AoEkt-1vACGe60nVyALILKg0IqEpj2eEZnBNwp-AxzNg1mqeNxaNm2n29fqZG55zwe0eSLgEQulO82dmkVBKkuVl4UoRmv4-wUPLAQiNAj_M63FeTgoljWXSEpq6W3PofDl8Hc6d9nMLJsQAACf4MOscj16In6vRNloejBmpOULRfznEpP1JJzCXJehGArdgt1o1my3gZDOBLm7XVjNphEMgDpz48UW4vm4vqGtnDNdg0dhJH_H289GRQ6NphDXAZUsWZgxqy5WEinHRaPTuxgGhqx2zW0JXVhG6cnKvd1r9Ewvb_XR_eE7o6u7BfUhjdVM4SWZS7HYknMcRdcKeFS89SI6T4XzBhHCD219cchem_vaqkV7I436HhM4JXQzm_spEc351rjXbP2BFwsWFoeFP7xj9yw41k-VtI0uBS6weX5MFnTxPsYHUxxcukdCY0Mz5PD-i2gWaptxPDZewetw7Em3Q_tzUX5lmtelSgiQLkiwGA_zdFomUt1xcOhFzvTEkuuUkWnYju0FOvRvmDIld4ji0udwAg6oDFl643QKDnJXgihKzLuh06nKLJp4FWE6O5Gw_b1nxZDUrLtSVQ21ixROUTb07jggmJMi-arXRrAamN02N0pr3sNf9dIY_jlkMhIYBBN-DIAiieFYVQVixCnEQBrM37ZevmkvrjXr0Zg8pptnLWhmrkdUeqAVwVyscbCmhq8ZoR21VMEHoKueS0NVJEtLb4HuRhJWrE1lv3PTEuJQl-SXjHhr5zSEv_sYc3_Qx_h_TP2VJPtJPT_XneQQjTY5Hra_t5UOqBv7_UVDYCUqqIMqKKM4qV9aG1vnEFzwvJkZNYm9QmFa-YPZiZmMxeZpi8aaYNEmxGImJTq1BloJm3OA7bEKWjoTFY2FRGIUlsFxp-6YwSqOwHAlLToXNorcdpHQWjR1MTxykWRW_7do0q-KRmGwUflqWFNO_TOE9E-crbluH27r7sfTJo5hiTw2XvcPakld5ShM2Gyi8e7htuChR3zKDHaQamUUH7I-F8tT34b375c-qbBV8EJKwyhM2G0EyHUOSsSqKnN5n1NaHzrl5V--c_75Q90F1d86MG2PY3u3nffny633nhG9RHzvzDpIycCMelfu8exjcPa9izng6Mr4M03yav1Obv3zq56d9_GAconyaT_NRHMKxK7Npks8-4cqtUMXTyI3uinchV0r84a6wJB9TanbiSljF1WeiIvGQZiOH-vnumxvyy-4TZhdVXI3Mjk7MnqWfItPB5k8t-VFepifEiE_MSsMAB2Yd53dWdanzGpNPipIbvFDS4vfzMvPNai43rmJ92ItiGgY48iIZeZFGVUhzMLZsVa0PoK23XRcTLgbIqw0vmHjw-xp4p2enLWA2LkQaN9xY1BdKTddk-2GEJoLVeckITT6t2C1t3sv7NZfP6sn1qr3rc7lfl8yyUbF_TVF8FqUzdbBoeXjw7HLlTEfxYJgF4efjcZxntkxjud5ZPVrlvqlGF3i_0W57dXlNO-_Ye333X-4ejiSdn4XyEDpcaVW7sQ8-tnqQmr89ZLiwD0j_Si4sepgOG67_BFtPkLqk02-7RwqWnAksbOfd_pKoy8T-4RH8RE78YBvjLp3ebEKyk1SalUk6kOu-Hfl3z1zNbHdoCyi2THtd89cr72-Hq5H8Xw2eQXGPtdL726aq3IZwAF2JFWuEXZco0OLrcy504xco6i4rz2mlD48m_jts657e3J9ifzGCNDiNYFVl8FpG91oPqbjWvqt_T4H8c-PV5VzBhMhZ8bSuxpXrL8zUn1yRV3IzUvGnEvSd1Bxvz1g1DdiwKTU7we1cll-1KtCYg9F_Cuz_g-nwxuJw2C61fz-6145ZwEatPKUndcb1yX_cSvFB8yIspuHIvPEWNA1ZUWRQMy4_-NwlLIpsJPjkKWE0S7K3HzbSMMmCkZjoVEw6Y7Beu2lrY5m263NjLwpOZ2wkOD7ZnAQBRtCK_OAT2yzAqBc9foDeft5BI0vUxjJZtuczx0f0UCkNlUaEUqGRhCYWavaEwOQeDEqDwCxUXBsLG8FkgRO4A5SFaqRFjZ08LsE1TvWOC9ReJvNdotIISoNAY8CqvWOMYHLTsA3Cy5YXW1BS7GHLDJA44PGMxAEwAwysf8q1AGcyE-J40GBgy54R2MAFVYHdek_qgxQ674_U4mAC_zBcbkAqXTPhH_eA264uWuNflH4yUAn24uwUe59-jfVC2w228SdZWtX-WneeULaNL1jlr8DdAxjE2p-l5ghW890OS2h2kO-dXf4A8OCeZDV2OI2PUE7CQ2iKzyjBbv3xHbceq-7gEsy-zpWA_mTzYDozUDHt_txBwSRYFKL1l1nYoCU0MSCUsf7Eru82ne0dPI4BL8yFbDLikgT8zuqdQAMvW9ToIRmK8HA6Za1qg9iqLbEQrN2LGO86iYOaCaEKj4oshyARmnZwINdAaFIorf0pYdKjYxyfHObO7A06ZwxqiyVo3DBdetqpCuo9GN-o-8IHh5Nqmjql3krP-4o7rsEL2zt5JTcsF949gyPju91gy99RyLcIWikLBWtMx0uXHMY0gyOuFsbKKd4yuWmncblrrD9jd7LcNPL7ztr_f9j-Q0_bu0C3FGibjq4sHc7Ox4_uxjL84tpeCm-hfap2t-yQS1xCdrvs9pZrc_3oltVrRxtfUDqoL0ygQ_K1ZEbYWe3A6pLwAM-lke22__gSg2ueLg90bDhj4HhgxWU_7silASGOIfXRPJcIg_NA7bLeXzoJT7fQTltKeRQmlWAb04E0dQrpNDifEQxG8JACdcneHmUvMW82cCcrBb-2q4I_316AGxe-xo2flW2T_KwC-oXXFaFDCNr1zpdLu8X95eKWY-XW1ZE0_-JFX4ex7Krc5Kq8CcsszNgV3kzjlM6ybBalV9ubIAnCisZxnpQ0LDKa5yynZRmXLMvKPC-u-A0NaBjMaBykURKmk2kWUhoXYZCmYRKmIZkFWDMuJh5jpTdXvtLdxDRM4ivBchTGv5pEqcSXrgxSSqLllb7xr37kzcaQWSC4saaXYrkV_p2m-y93DyRawqIxVtWj9YLQ1WC16JsDv2j0CwSU3DXnbvH3y7fryjzEr66gXe0-WeO7gusLx2GxH7QGVvk3HK4aLW621u588aYrQlcbbrdNPilUPXi_ZfzWi8fFELryuP07AAD__5GlfgE">