Currently both calling conventions preserve registers that are used to store
a return value. This causes the returned value to be lost:
define i32 @bar() { %1 = call preserve_mostcc i32 @foo() ret i32 %1 } define preserve_mostcc i32 @foo() { ret i32 2 ; preserve_mostcc will restore %rax, whatever it was before the call. }
This contradicts the current documentation (preserve_allcc "behaves
identical to the C calling conventions on how arguments and return
values are passed") and also breaks [[clang::preserve_most]].
This change makes CSRs be preserved iff they are not used to store a
return value (e.g. %rax for scalars, {%rax:%rdx} for __int128, %xmm0
for double). For void functions no additional registers are
preserved, i.e. the behaviour is backward compatible with existing
code.
Juergen, can you please take a look, since you added the CCs originally?
Phoebe, I added you as a reviewer as well, since you touched the X86 CC code recently :)
Thanks!