A few of the ARM MVE builtins directly return a structure type. This
causes an assertion failure at code-gen time if you try to assign the
result of the builtin to a variable, because the RValue created in
EmitBuiltinExpr from the llvm::Value produced by codegen is always
made by RValue::get(), which creates a non-aggregate RValue that
will fail an assertion when AggExprEmitter::withReturnValueSlot calls
Src.getAggregatePointer(). A similar failure occurs if you try to use
the struct return value directly to extract one field, e.g.
vld2q(address).val[0].
The existing code-gen tests for those MVE builtins pass the returned
structure type directly to the C return statement, which apparently
managed to avoid that particular code path, so we didn't notice the
crash.
Now EmitBuiltinExpr checks the evaluation kind of the builtin's return
value, and does the necessary handling for aggregate returns. I've added
two extra test cases, both of which crashed before this change.
The requirement is that we construct an RValue of the right kind for the expression's result type, so the correct approach here is to switch over getEvaluationKind(E->getType()). This is also a more reliable signal than the presence of the return value slot.
We then need to think about how the return value will be returned to us in each case: