Repository: rust
Issue: asm: Since nightly-2024-08-01 (LLVM 19), in and out is sometime allocated to the same register
Labels: A-LLVM,A-inline-assembly,P-high,T-compiler,I-unsound,C-bug,WG-llvm,regression-untriaged,llvm-fixed-upstream,I-miscompile

<!--
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.
-->

Repro:

```sh
# Prerequisite: Environment that can compile or cross-compile aach64-linux-gnu
git clone https://github.com/taiki-e/atomic-maybe-uninit.git
cd atomic-maybe-uninit
git checkout v0.3.2
RUSTFLAGS='-C target-feature=+lse' \
  ./tools/test.sh --tests --target aarch64-unknown-linux-gnu --release --no-run
```

I expected to see this happen: compile pass

Instead, this happened:

```
error: unpredictable STXP instruction, status is also a source
   --> src/arch/aarch64.rs:571:37
    |
571 | ...                   concat!("st", $release, "xp {tmp:w}, {val_lo}, {val_hi}, [{dst}]"),
    |                       ^
    |
note: instantiated into assembly here
   --> <inline asm>:3:6
    |
3   | stxp w8, x8, x23, [x9]
    |      ^

error: unpredictable STXP instruction, status is also a source
   --> src/arch/aarch64.rs:571:37
    |
571 | ...                   concat!("st", $release, "xp {tmp:w}, {val_lo}, {val_hi}, [{dst}]"),
    |                       ^
    |
note: instantiated into assembly here
   --> <inline asm>:3:7
    |
3   | stlxp w8, x8, x23, [x9]
    |       ^
```

[This](https://github.com/taiki-e/atomic-maybe-uninit/blob/v0.3.2/src/arch/aarch64.rs#L565-L580) is the inline assembly that received the error, and `tmp` and `val_lo` which the compiler assigned the same registers are `out` and `in`, respectively.

```rs
                                val_lo = in(reg) val.pair.lo,
                                val_hi = in(reg) val.pair.hi,
                                tmp = out(reg) _,
```

Those two must not be allocated the same register, but for some reason the compiler seems to be treating `out` as if it were [`lateout`](https://doc.rust-lang.org/nightly/reference/inline-assembly.html#asm.operand-type.supported-operands.lateout).

> lateout(\<reg\>) \<expr\>
> Identical to `out` except that the register allocator can reuse a register allocated to an `in`.

I have confirmed that at least the following three targets are affected:
- aarch64-unknown-linux-gnu ([ci log](https://github.com/taiki-e/atomic-maybe-uninit/actions/runs/10190828070/job/28191393249#step:19:2610))
- aarch64_be-unknown-linux-gnu ([ci log](https://github.com/taiki-e/atomic-maybe-uninit/actions/runs/10190828070/job/28191393573#step:19:4375))
- riscv64gc-unknown-linux-gnu ([ci log](https://github.com/taiki-e/atomic-maybe-uninit/actions/runs/10190828070/job/28191401156#step:15:3091))

As for riscv64gc-unknown-linux-gnu, I consistently get the [unexpected result](https://github.com/taiki-e/atomic-maybe-uninit/actions/runs/10190828070/job/28191401156#step:15:3091) at runtime (not compile error) in exactly the same version range.

In the aarch64 case, the problem appeared in a form that the assembler could detect as an error, resulting in a compilation error, but in some situations, as in the riscv64 case, the code may be silently miscompiled.

### 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.82.0-nightly (f167efad2 2024-08-24)
binary: rustc
commit-hash: f167efad2f51088d86180ee89177b3d7c9e7c2f5
commit-date: 2024-08-24
host: aarch64-unknown-linux-gnu
release: 1.82.0-nightly
LLVM version: 19.1.0
```

It can be reproduced with nightly-2024-08-01 or later.

```
rustc 1.82.0-nightly (28a58f2fa 2024-07-31)
binary: rustc
commit-hash: 28a58f2fa7f0c46b8fab8237c02471a915924fe5
commit-date: 2024-07-31
host: aarch64-unknown-linux-gnu
release: 1.82.0-nightly
LLVM version: 19.1.0
```


The last version *not* affected by the problem is nightly-2024-07-31, which uses LLVM 18, so it seems likely that the update to LLVM 19 (https://github.com/rust-lang/rust/pull/127513) caused this regression.
cc @nikic

```
rustc 1.82.0-nightly (f8060d282 2024-07-30)
binary: rustc
commit-hash: f8060d282d42770fadd73905e3eefb85660d3278
commit-date: 2024-07-30
host: aarch64-unknown-linux-gnu
release: 1.82.0-nightly
LLVM version: 18.1.7
```

---

@rustbot label +I-unsound, +A-LLVM, +A-inline-assembly