Improve description of the problem based on helpful feedback from rnk.
Diff Detail
Event Timeline
lgtm
Do you think we can one day support promoting byval struct parameters that aren't in the variadic argument pack, or will that change the classification of downstream structs on the edge of the regparm area?
I think the answer is 'no' as long as LLVM handles variadic args the way it
currently does. Currently, the fits_in_gp predicate is computed based on
assumptions about the size of arguments on the stack. Anything that could
change that will break variadic functions.
I don't think this is entirely accurate. Each va_arg expansion from Clang should be completely independent, and so far as I can tell doesn't encode any information about how many non-variadic parameters there were. It *does* encode information about the AST-level type, which is what is breaking this test case of 5 pointers plus one 2 x i64 struct.
Hm, now I understand the problem. I wouldn't say that the stack size is hardcoded into the IR in any way, though. The issue is that adding / removing / promoting non-pack parameters changes the classification of pack parameters. The classification of arguments at the call site is decided at compile time by clang, and the classification in the callee is determined dynamically by clang's expansion of va_arg.
DAE already knows this:
Liveness Result; if (F.getFunctionType()->isVarArg()) { // Variadic functions will already have a va_arg function expanded inside // them, making them potentially very sensitive to ABI changes resulting // from removing arguments entirely, so don't. For example AArch64 handles // register and stack HFAs very differently, and this is reflected in the // IR which has already been generated. Result = Live;
For some reason argument promotion doesn't know this, even though it also removes dead arguments. I'm a bit surprised at the duplicated functionality, honestly.