-
Notifications
You must be signed in to change notification settings - Fork 15.4k
Description
I noticed that fir-opt produces invalid IR during fir-to-llvm-ir for this test case:
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:
"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 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.