Closed
Description
This should return 7
, but returns a
, with or without optimizations.
#![feature(asm_goto)]
#![feature(asm_goto_with_outputs)]
#[unsafe(no_mangle)]
pub fn asm_goto_test(
mut a: i16,
) -> i16 {
unsafe {
std::arch::asm!(
"jmp {op}",
inout("eax") a,
op = label { a = 7; },
options(nostack,nomem)
);
a
}
}
https://godbolt.org/z/Efze66G84
As far as I can tell, the MIR looks correct:
fn asm_goto_test(_1: i16) -> i16 {
debug a => _1;
let mut _0: i16;
bb0: {
asm!("jmp {1}", inout("ax") copy _1 => _1, label 1, options(NOMEM | NOSTACK)) -> [return: bb1, label: bb2, unwind unreachable];
}
bb1: {
_0 = copy _1;
return;
}
bb2: {
_1 = const 7_i16;
goto -> bb1;
}
}
In particular, the value assigned to _1
in bb2
is returned in bb1
.
The LLVM-IR is incorrect, as bb2
stores the value to ptr %a
, but bb1
then overwrites that with the previous value in %2
.
define i16 @asm_goto_test(i16 %0) unnamed_addr {
start:
%a = alloca [2 x i8], align 2
store i16 %0, ptr %a, align 2
%1 = load i16, ptr %a, align 2
%2 = callbr i16 asm sideeffect inteldialect "jmp ${2:l}", "=&{ax},0,!i,~{dirflag},~{fpsr},~{flags}"(i16 %1) #1
to label %bb1 [label %bb2]
bb2:
store i16 %2, ptr %a, align 2
store i16 7, ptr %a, align 2
br label %bb1
bb1:
store i16 %2, ptr %a, align 2
%_0 = load i16, ptr %a, align 2
ret i16 %_0
}
rustc --version --verbose
:
rustc 1.86.0-nightly (f85c6de55 2025-01-26)
binary: rustc
commit-hash: f85c6de55206dbee5ffedfd821df1503a7b92346
commit-date: 2025-01-26
host: x86_64-unknown-linux-gnu
release: 1.86.0-nightly
LLVM version: 19.1.7
asm_goto tracking issue: #119364
@rustbot label +F-asm +A-inline-assembly +T-compiler