<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/57550>57550</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Incorrect handling of lateout pairs in inline asm
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
newpavlov
</td>
</tr>
</table>
<pre>
The issue was discovered while looking into source of https://github.com/rust-lang/rust/issues/101346.
The following Rust function:
```rust
pub fn foo() -> u32 {
let t1: u32;
let t2: u32;
unsafe {
asm!(
"mov {0:e}, 1",
"mov eax, 42",
lateout(reg) t1,
lateout("eax") t2,
options(nostack),
);
}
t1
}
```
Get compiled into this obviously incorrect assembly:
```asm
example::foo:
mov eax, 1
mov eax, 42
ret
```
Godbolt link: https://rust.godbolt.org/z/Yb9v7WobM
LLVM incorrectly reuses register for a pair of `lateout`s if it can see that one of those does not get used later.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJx9VE1vnDAQ_TVwsYKM-VoOHJKmrSoll6pq1aOBAdx4Pcg2u0l_fceQTbLNh-VdY8_wZubNMy32D82PCZhybgF2lI71ynV4AAs9O05KA9OId8qMTBmPzOFiO2A4sMn72UXZZSS-0ByVn5Y26XBPG7s4f6GlGR-faVnxHT2kPM3yMon4dcQvt_8Qf0Ct8RjCfKcX2LCYzis0AX_zLPk2V7z1aF5aNhh6EyOxi0TNLqLsM1sywaLqanNhNDR45lMCCqYo-98i3rIsxskBznHCkI7KS0O4s-MwIiH2eAivcEKEqLqOxCdGvoLWd91B3ge3XLznp6UHXIjBnYUxFEmlfOxHSCuqWL3fRsU5kEvt2Bl0XnZ35PvKMZy9JCWU9LShNLa-nA6fGrRtvxK3JIaZBNRvyvGTcgzbg8LF6Qc669Ba6DyR6mDf6ofXvQ50rydwL_ezhuCRXYaGn1xPuQYuw3jkM_3QSmyfmS34t2vAvkXtmVbmLqjkXPFBiMm4uSRog9b_0u93Wx-qX9jevlT4zc3P2-eKqXoLiwNHy6icB0sitkyyWSobrhZlcOpnyR1TA1PEpjTMARCP0jM06x30EzpgPRKUQc9GIp1w-1UNNomhSctSiJqLooj7JuvrrJaxV15D8-2J_0maXoebR4CPYddMKLChSSYIwo8Xq5sPLr3Wh9NyMVv8Q9Av731RFQWPp6aUWVd1RT3k6Q7ETtRpn_McxCBoU_JdrGUL2jVRcUUaNnDcPk1Bz8V1rBrBheA1z9M0rbIiySr6nIhsyMsBeAVtlHPYS6WTkEdoS2ybNaV2GR0ZNfHtno2kPTUagDUc4cuFKLUNhZ3lQeMhXoM3a_L_AKF5fTw">