<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/118066>118066</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
`fir.embox` lowering produces invalid IR during `fir-to-llvm-ir`
</td>
</tr>
<tr>
<th>Labels</th>
<td>
flang:codegen
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
clementval,
jeanPerier
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
matthias-springer
</td>
</tr>
</table>
<pre>
I noticed that `fir-opt` produces invalid IR during `fir-to-llvm-ir` for this test case:
```mlir
fir.global @elesize_of_embox constant : i32 {
%0 = fir.zero_bits !fir.ptr<i32>
%1 = fir.embox %0 : (!fir.ptr<i32>) -> !fir.box<!fir.ptr<i32>>
%2 = fir.box_elesize %1 : (!fir.box<!fir.ptr<i32>>) -> i32
fir.has_value %2 : i32
}
```
Error:
```
within split at llvm-project/flang/test/Fir/convert-to-llvm.fir:1 offset :4:8: error: ops with side effects not allowed in global initializers
%2 = fir.box_elesize %1 : (!fir.box<!fir.ptr<i32>>) -> i32
^
within split at llvm-project/flang/test/Fir/convert-to-llvm.fir:1 offset :4:8: note: see current operation: %23 = "llvm.load"(%22) <{ordering = 0 : i64}> : (!llvm.ptr) -> i64
```
This is only one of the problems. The dialect conversion also inserts an `unrealized_conversion_cast` from the boxed ptr to a bare pointer:
```mlir
"llvm.mlir.global"() <{addr_space = 0 : i32, constant, global_type = i32, linkage = #llvm.linkage<external>, sym_name = "elesize_of_embox", visibility_ = 0 : i64}> ({
%0 = "llvm.mlir.zero"() : () -> !llvm.ptr
%1 = "llvm.mlir.constant"() <{value = 9 : i32}> : () -> i32
%2 = "llvm.mlir.zero"() : () -> !llvm.ptr
%3 = "llvm.getelementptr"(%2) <{elem_type = i32, rawConstantIndices = array<i32: 1>}> : (!llvm.ptr) -> !llvm.ptr
%4 = "llvm.ptrtoint"(%3) : (!llvm.ptr) -> i64
...
%20 = "llvm.insertvalue"(%19, %0) <{position = array<i64: 0>}> : (!llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)>, !llvm.ptr) -> !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)>
%21 = "builtin.unrealized_conversion_cast"(%20) : (!llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)>) -> !llvm.ptr
%22 = "llvm.getelementptr"(%21) <{elem_type = !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)>, rawConstantIndices = array<i32: 0, 1>}> : (!llvm.ptr) -> !llvm.ptr
%23 = "llvm.load"(%22) <{ordering = 0 : i64}> : (!llvm.ptr) -> i64
%24 = "llvm.trunc"(%23) <{overflowFlags = #llvm.overflow<none>}> : (i64) -> i32
"llvm.return"(%24) : (i32) -> ()
}) : () -> ()
```
Within `fir.global`, `fir.embox` does not lower to an `alloca` but directly to an LLVM struct. This does not compose with the remaining ops. I think the only thing you can do is returning the boxed values via `fir.has_value`, everything else produces invalid IR.
Why does Flang store the LLVM struct that is generated during "boxing" in a stack allocation? Why not use the LLVM struct directly? In the type converter, there is `convertBoxType` and `convertBoxTypeAsStruct`. Why isn't `convertBoxTypeAsStruct` used everywhere?
Context: I am looking at this as part of [refactorings of the dialect conversion framework](https://discourse.llvm.org/t/rfc-merging-1-1-and-1-n-dialect-conversions/82513) and ran into issues with `HasValueOpConversion` and `InsertValueOpConversion` (in `CodeGen.cpp`). Ideally, these should run with a type converter. I'm trying to understand what's the right solution here.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy8WF-P4jgS_zTmpQRKHAjwwANND3dIe7rT3Wj3ETlJBbxt7Mh26GY-_ansJEA307envr0RGoa4Un9-9as_HuGcPGjEFZs9Mc5LhSfU_iwU45zxDeP8dxT6H2glWno0ex6J1h-NXZ2E90cp3Ng1VuoD2lFhqstqB9p4WWIF_ig8sDyppR2bxrM8gcaaqi3RgdRnoWQFu39C1dLrvaA3Y6XOp7G0JF8bC_4oHXh0HkrhkGVrloRPnsTPSUnLknUt7eSgTCEUsGmCCp38gXtT7_FUmDcojXZeaA8sW4PMOLD5E0vWAIzPEmDZM5CCH2jNvpDeAeMpPWi8ZdlGZpxl33rxdBCPqjsNa2B88eg1voQxy771KgvzxrLNI8GrCT6YKMzbvgumt31r6FNlvWF6QopJ5ijc_ixUi72ZdXfM5s-3qEaQv1lrbAf5zcmr9EepwTVKehAeQsYaa37H0jO-rZXQB8a3lDTGt1tpGd-WRp_R-j7Bk1qS4hRMXTsMaZmybL0gh7CzCqZxQLbAyQoB6xpL74hfIJQyr1iB1NAlXWrppVDyB1r358IY_rDZtz8fCG08ER4cIpSttag9mAat8NLoGMGMZyFIxnnQpoyoQuku6IyT8xTZ_MnYCmOhZc8Q-SrzKWWdqDmgEZQQAkPU-fQjL75TTUoHRqsLGI1gavBHpPouFJ7cBL4fESopFJYeYsROGg1COQNSO7TegdBU9a22GPJW7a-C-1K40DFqa05BdWHesILGW_AGBBTCIjRGao_2pz0BBljoQdceenR6YERV2b1rRIm30GTU_YauQf-Ob-_9pYmCnYiS-kUcsEtCFpMQn7Fsg28erRYq8GgD7nLaa3Hqpfn7NhWbLpylk4VU0l_2j9PFF337umlgd7FSJ7uNtMvvtRUNiR60pB-1XOO_x6zrINkzLAe43jHpQ9EM9fhVP-8Jf0CPcWgF1vbMv_pKpx-yZsXrpottpytJI4lOhbXi0hf_GlJK23-skIdOTu-cbLz1xNXBv-wu2p9WXVQ3mUyuPyi4-3zHcgopGfSnS4qSqHEFojFOUuO4jzSnbgPJTyN13ralD91xETzcBOfoK0IpF4_-XnaM_wywr6i-gjHQtmil8lJPPmkoAz2SB_h_KdLPuMD5H2Fs-jPK_o8y8ccon5DoF3j__xlHvbH7KvO21eXVWnZj7Yy2VuZ1q8TB3bXq_oRlG200fgg8IHzfy3pzFn1r9dXe9IZTISMDTiELYRzNnx-3uU7i3Zj9La4XcTXux1ceUtQ9i1MjT6AyGDcj2ovijAwv0qJUCpIoWg-VtFh6denOf_nl179BpBVNbOmuakpzaozDuH7R_LV4ElJTxkzjJrCjvVy_hKOwBdDPA1xMC6XQUBlaDyJC9Pw6wUOfcnCWoo9hWEm70PCM9hLVoXL46NLQ9cPfjpfo8ZYWLXDeWAymbgKL1xDp4ICaNieshhsH54V5k7ShcVokBTgvyheIkMUVawtkgwBp3UfVPZwkt9PhOFRtt-JhqFF_RIvkAMuT7uDJvH2_NBQvCF19PFi7f8Vaz5NJcEA6zfjcfypJHlYRvFcyybJtRGljtMc3T6TbgTiBMuaF4hc-3q2Eg0ZYTzscmz1ZrEXpDSHk-rXuwSJXW3HCV2Nf2OyZ8cXR-8bRHsa3jG8r6UrTWoeTWGM2LMGMb21djk9oD1Ifxuk4HQtdjdOxHncGxlcDjvHtgs_SUMQEkhUapPbEK0cECsRkefJX4X4l8vy92Qwv3wC7C8PxoQSVaaiRjanwL6gnZdMECi4nsKtQKHXp8ucQ3NG0qgLb6mhZvMv0BHaMz0_g7SXw3UCrK7TUbit4PQrP-NzFQpKHowdnVBuGMaWK6DyqVlm1zJZihKt0nvFFvuT5YnRcLbNiUZezKplxXvJpOs9EXpbZdDHLaz4v-EiueMKnacqXySKb8sWk5GmdL7BIi7TCuajoPnwSUg3ZGAUMV2m6SPJ8pESBynX_ARCvLNm6NBUeUHdXfrsKN5uiPTg2TZR03l2VeekVrt43pNCHCIr_8s4_aq1a3dPpIP2xLSalOTG-Jcnu6-amFUnB-LaL6bzi_w4AAP__6WQFGQ">