Repository: rust
Issue: Inline assembly fails to compile after allowing inlining on the enclosing function for i686-pc-windows-msvc
Labels: A-inline-assembly,C-bug,O-x86_32

<!--
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.
-->
Consider the following code:

```rust
use std::arch::asm;

#[inline(never)]
pub fn my_test(a: u32, b: u32, c: u32, d: u32) -> u32 {
    let mut g = 3;
    unsafe {
        asm!(
            "mov {a}, {b}",
            "xor {a}, {c}",
            "and {a}, {d}",
            "or {a}, {e}",
            "not {f}",
            "add {a}, {f}",
            "sub {a}, {g}",
            "mov {g}, {a}",

            a = in(reg) a,
            b = in(reg) b,
            c = in(reg) c,
            d = in(reg) d,
            e = out(reg) _,
            f = out(reg) _,
            g = inout(reg) g
        )
    }
    g
}
```
which uses 7 registers. If we try to compile this on `i686-pc-windows-msvc`, in principle there are 7 general registers, but [Rust Reference](https://doc.rust-lang.org/reference/inline-assembly.html#register-names) mentions that `ebp` and `esi` would be reserved, so I expect a compilation error.

We can put this in a `lib.rs`, and in `main.rs` we put:
```rust
use asm_test::my_test;

fn main() {
    println!("{}", my_test(1, 2, 3, 4));
}

```

Instead, when compiling in release mode using `cargo build --release --target i686-pc-windows-msvc`, it compiles. `cargo asm --lib --target i686-pc-windows-msvc` reveals that the compiler does allocate `esi` and `ebp`.

<details>
<summary>cargo asm output</summary>

```asm
.section .text,"xr",one_only,asm_test::my_test
        .globl  asm_test::my_test
        .p2align        4, 0x90
asm_test::my_test:
Lfunc_begin0:
        .cv_func_id 0
        .cv_file        1 "R:\\asm-test\\src\\lib.rs" "D7E84472A8BA4CD0C091D8930D59F9C5C684E1A6" 2
        .cv_loc 0 1 3 0
        .cv_fpo_proc    asm_test::my_test 16
        push ebp
        .cv_fpo_pushreg ebp
        push ebx
        .cv_fpo_pushreg ebx
        push edi
        .cv_fpo_pushreg edi
        push esi
        .cv_fpo_pushreg esi
        .cv_fpo_endprologue
        mov ecx, dword ptr [esp + 20]
        mov edx, dword ptr [esp + 24]
        mov esi, dword ptr [esp + 28]
        mov edi, dword ptr [esp + 32]
        mov eax, 3
        .cv_loc 0 1 6 0
        #APP

        mov ecx, edx
        xor ecx, esi
        and ecx, edi
        or ecx, ebx
        not ebp
        add ecx, ebp
        sub ecx, eax
        mov eax, ecx

        #NO_APP
        .cv_loc 0 1 26 0
        pop esi
        pop edi
        pop ebx
        pop ebp
        ret
        .cv_fpo_endproc
```
</details>

However, if we change `#[inline(never)]` to `#[inline]`, the compiler correctly displays:
```
error: inline assembly requires more registers than available
```

I would expect a compilation error in both cases, and a guarantee that neither `esi` nor `ebp` gets allocated.

I haven't tried on `x86_64` target yet simply because the number of general registers is a lot. I could try it later today.

### 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.
-->
Tried on both stable and nightly
`rustc --version --verbose`:
```
rustc 1.66.1 (90743e729 2023-01-10)
binary: rustc
commit-hash: 90743e7298aca107ddaa0c202a4d3604e29bfeb6
commit-date: 2023-01-10
host: i686-pc-windows-msvc
release: 1.66.1
LLVM version: 15.0.2
```
```
rustc 1.68.0-nightly (1e4f90061 2023-01-11)
binary: rustc
commit-hash: 1e4f90061cc4bc566f99ab21b1f101182b10cf0c
commit-date: 2023-01-11
host: i686-pc-windows-msvc
release: 1.68.0-nightly
LLVM version: 15.0.6
```

No backtrace available.