Closed sebastianpoeplau closed 1 year ago
The part of the compiler pass that handles expressions for structs is quite involved, as evidenced by the long comment in the function linked in the original issue description. I think it makes sense to try and improve it in general, rather than just adding one more special case. Let's collect the requirements...
insertvalue/extractvalue
to load/store
. Moreover, we don't have a way to describe expression trees with a single pointer at the moment.undef
undef
members. Here we need to handle the case where all values are concrete, as well as the case where at least one has a symbolic expression attached to it.The current implementation handles undef
(by creating an all-zeros expression); it also tries to handle structs with values in them but fails, which is the reason for the present bug. This brings us to the last requirement: there should be tests that cover the functionality :upside_down_face:
It is tempting to describe structs with trees of expressions... For example, the struct type { i8, i32 }
could have a shadow type { ptr, ptr }
containing expression pointers for individual elements.
The advantage would be that insertvalue/extractvalue
wouldn't have to convert expression kinds anymore (e.g., to and from floating-point kind); this would be left to load/store
, which already do it anyway. We'd need rather complex logic to handle struct values in load/store
which couldn't be in the runtime: it depends on the bitcode type of the value being loaded/stored. However, the same is true for initial expression creation if we express in-memory representations. We could emit conversion functions to/from tree representation when we first encounter the struct type, but I wonder how this would work with literal struct types (i.e., struct types that are defined inline rather than named at top level) :thinking:
This is a bug related to SymCC's handling of struct values in bitcode. The code that triggers it is the following:
%bar
is a symbolic value, so we need to create an expression for the constant{i8 1, i32 undef}
. The compiler pass generates the following code:That is, we write the struct to newly allocated memory and read it symbolically to get the expression. Unfortunately, the struct constant is fully concrete, so
_sym_read_memory
returnsnullptr
, which we promptly feed into_sym_build_insert
, causing a segfault.