Reland "[X86][ABI] Don't preserve return regs for preserve_all/preserve_most CCs""
authorAnton Bikineev <bikineev@chromium.org>
Mon, 6 Feb 2023 12:16:08 +0000 (13:16 +0100)
committerAnton Bikineev <bikineev@chromium.org>
Thu, 9 Feb 2023 09:59:16 +0000 (10:59 +0100)
commit10629bb96aebfefaadfb0069bc7e276b868fcef9
treeae3f374ff2df33a8e1da2bb8db3b3524f628b131
parent2929683eef27e6b3ac95325d955cd39bc2e416c0
Reland "[X86][ABI] Don't preserve return regs for preserve_all/preserve_most CCs""

The original change mistakenly excluded parameter registers from the
list of callee-saved-registers. This reland fixes it - it only excludes
the return registers for preserve_all/preserve_most CCs.

Original description:
> 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.

Differential Revision: https://reviews.llvm.org/D143425
llvm/docs/LangRef.rst
llvm/lib/Target/X86/X86CallingConv.td
llvm/lib/Target/X86/X86ISelLowering.cpp
llvm/test/CodeGen/X86/dynamic-regmask-preserve-all.ll [new file with mode: 0644]
llvm/test/CodeGen/X86/dynamic-regmask-preserve-most.ll [new file with mode: 0644]
llvm/test/CodeGen/X86/preserve_allcc64-ret-double.ll [new file with mode: 0644]
llvm/test/CodeGen/X86/preserve_allcc64.ll
llvm/test/CodeGen/X86/preserve_mostcc64-ret-double.ll [new file with mode: 0644]
llvm/test/CodeGen/X86/preserve_mostcc64-sret.ll [new file with mode: 0644]
llvm/test/CodeGen/X86/preserve_mostcc64.ll