I see here: https://llvm.org/docs/LangRef.html#ret-instruction
That the return instruction must only return values of first class types, which would exclude struct and arrays. But some llvm instrinsics do return struct, and it does not seems to be enforced on any function.
Is that restriction lifted and the documentation not up to date? Can we return arrays?
I see the same restriction for select. Can/should we lift it too?
In practice, you can return structs and arrays, and this while you stay
within the optimizer, but how targets handle this is very variable.
X86 internally lowers it to sret or something very similar to sret
whereas lesser used targets (think MSP430) may outright assert.
My understanding is that calling an intrinsic that returns a struct
is defined (and never needs a ret instruction), but returning a struct
from user code (which does need a ret instruction) is not, which is
why LangRef is written like that.
Ah, that’s why Clang is obsessively pushing them into return by reference?
Ah, that's why Clang is obsessively pushing them into return by
Not only that. Even on targets that do correctly translate returning
structs by value, the resulting ABI is not defined (and it will, in
fact, not match the C ABI in practice), and clang usually needs to
follow the C or C++ ABI.
IMO it's the wording that tries to define "first-class" that's dodgy.
I don't think it's trying to describe the concept of primitive types
(which would exclude structs), but rather to distinguish first-class
from metadata and function types (as distinguished from function
pointer types) that it makes no sense to return, or do much else with.
This fits with the introductory sentence: "Values of these types are
the only ones which can be produced by instructions".