Repository: rust
Issue: LLVM can't support partial register clobbers
Labels: A-LLVM,A-inline-assembly,T-libs-api,T-compiler,C-bug,A-ABI

<!--
Thank you for filing a bug report! 🐛 Please provide a short summary of the bug,
along with any information you feel relevant to replicating the bug.
-->

On x86_64-pc-windows-msvc, the [system ABI](https://learn.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-170) considers `xmm0-5` as volatile/caller-save registers, and `xmm6-15` as non-volatile/callee-save registers. However, `clobber_abi("C")` incorrectly marks `xmm6-15` as clobbered, which produces a bunch of wasteful register saves/restores.

This behaves according to [the documentation](https://doc.rust-lang.org/reference/inline-assembly.html#abi-clobbers) (which specifies that xmm6-15 will be clobbered), but it's almost certainly not what the developer wanted due to the unnecessary clobbering causing performance problems. The workaround is to avoid using `clobber_abi` on Windows and to manually clobber registers; this is a pain and may cause problems down the line as more volatile registers are added to the ABI.

So a breaking change seems warranted here.

[Godbolt link](https://godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(filename:'1',fontScale:14,fontUsePx:'0',j:1,lang:rust,selection:(endColumn:24,endLineNumber:5,positionColumn:24,positionLineNumber:5,selectionStartColumn:24,selectionStartLineNumber:5,startColumn:24,startLineNumber:5),source:'%23%5Bno_mangle%5D%0Apub+fn+foo()+%7B%0A++++unsafe+%7B%0A++++++++std::arch::asm!!+%7B%0A++++++++++++%22call+bar%22,%0A++++++++++++clobber_abi(%22C%22),%0A++++++++%7D%0A++++%7D%0A%7D%0A'),l:'5',n:'1',o:'Rust+source+%231',t:'0')),k:33.333333333333336,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:r1790,filters:(b:'1',binary:'1',binaryObject:'1',commentOnly:'1',debugCalls:'1',demangle:'0',directives:'1',execute:'1',intel:'0',libraryCode:'1',trim:'1',verboseDemangling:'0'),flagsViewOpen:'1',fontScale:14,fontUsePx:'0',j:1,lang:rust,libs:!(),options:'--target+x86_64-pc-windows-msvc+-C+opt-level%3D3',overrides:!(),selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1),l:'5',n:'0',o:'+rustc+1.79.0+(Editor+%231)',t:'0')),k:33.333333333333336,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:output,i:(compilerName:'x64+msvc+v19.latest',editorid:1,fontScale:14,fontUsePx:'0',j:1,wrap:'1'),l:'5',n:'0',o:'Output+of+rustc+1.79.0+(Compiler+%231)',t:'0')),k:33.33333333333333,l:'4',n:'0',o:'',s:0,t:'0')),l:'2',n:'0',o:'',t:'0')),version:4)

```rust
#[no_mangle]
pub fn foo() {
    unsafe {
        std::arch::asm! {
            "call bar",
            clobber_abi("C"),
        }
    }
}
```

Asm:
```
foo:
        sub     rsp, 168
        movaps  xmmword ptr [rsp + 144], xmm15
        movaps  xmmword ptr [rsp + 128], xmm14
        movaps  xmmword ptr [rsp + 112], xmm13
        movaps  xmmword ptr [rsp + 96], xmm12
        movaps  xmmword ptr [rsp + 80], xmm11
        movaps  xmmword ptr [rsp + 64], xmm10
        movaps  xmmword ptr [rsp + 48], xmm9
        movaps  xmmword ptr [rsp + 32], xmm8
        movaps  xmmword ptr [rsp + 16], xmm7
        movaps  xmmword ptr [rsp], xmm6

        call    bar

        movaps  xmm6, xmmword ptr [rsp]
        movaps  xmm7, xmmword ptr [rsp + 16]
        movaps  xmm8, xmmword ptr [rsp + 32]
        movaps  xmm9, xmmword ptr [rsp + 48]
        movaps  xmm10, xmmword ptr [rsp + 64]
        movaps  xmm11, xmmword ptr [rsp + 80]
        movaps  xmm12, xmmword ptr [rsp + 96]
        movaps  xmm13, xmmword ptr [rsp + 112]
        movaps  xmm14, xmmword ptr [rsp + 128]
        movaps  xmm15, xmmword ptr [rsp + 144]
        add     rsp, 168
        ret
```

I expected that `foo` would just establish a frame and call `bar` without saving/restoring of the XMM registers.

### Meta
<!--
If you're using the stable version of the compiler, you should also check if the
bug also exists in the beta or nightly versions.
-->

`rustc --version --verbose`:
```
rustc 1.78.0 (9b00956e5 2024-04-29)
binary: rustc
commit-hash: 9b00956e56009bab2aa15d7bff10916599e3d6d6
commit-date: 2024-04-29
host: x86_64-unknown-linux-gnu
release: 1.78.0
LLVM version: 18.1.2
```

But this repros in nightly.