Starting in #51583, we're representing scalar pair bools 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.
Starting in #51583, we're representing scalar pair
bools asi8in LLVM aggregates to match their memory storage, whereas they arei1as immediate values.When a pair is the argument to a function, we use
PassMode::Pairand pass each part like independent immediate values. We don't use that mode for return values though, so a pairedboolwill be extended toi8for return, then truncated back toi1when the caller unpacks it.Quoting @eddyb in #51583 (comment):