Skip to content

asm_goto_with_outputs miscompilation #137867

Closed
@quaternic

Description

@quaternic

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-inline-assemblyArea: Inline assembly (`asm!(…)`)C-bugCategory: This is a bug.F-asm`#![feature(asm)]` (not `llvm_asm`)I-miscompileIssue: Correct Rust code lowers to incorrect machine codeT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions