Description
Starting in #51583, we're representing scalar pair bool
s as i8
in LLVM aggregates to match their memory storage, whereas they are i1
as immediate values.
When a pair is the argument to a function, we use PassMode::Pair
and pass each part like independent immediate values. We don't use that mode for return values though, so a paired bool
will be extended to i8
for return, then truncated back to i1
when the caller unpacks it.
Quoting @eddyb in #51583 (comment):
I wonder if they should be using the pair "passing mode" that arguments do, and create a LLVM aggregate type on the fly, using the immediate types for the pair components. That way we'd get
{i1, i1}
for returns, but everything else would see{i8, i8}
.Not sure it's worth the complexity though. When inlining, LLVM should collapse the zext followed by trunc, just like it gets rid of packing into a pair and unpacking it.
Activity
eddyb commentedon Jul 13, 2018
I think that for compatibility with backends that support "true multiple return" (i.e. Cranelift), we should be using
PassMode::Pair
for returns as well, with more explicit packing. cc @sunfishcodesunfishcode commentedon Jul 13, 2018
That sounds right to me. Even in LLVM, an aggregate return type in LLVM is essentially LLVM's convention for multiple return values, so it sounds desirable to use
i1
there too.