Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LLVM Error with asm! #83495

Closed
Soveu opened this issue Mar 25, 2021 · 2 comments · Fixed by #83853
Closed

LLVM Error with asm! #83495

Soveu opened this issue Mar 25, 2021 · 2 comments · Fixed by #83853
Labels
A-inline-assembly Area: Inline assembly (`asm!(…)`) C-bug Category: This is a bug. F-asm `#![feature(asm)]` (not `llvm_asm`) O-x86_64 Target: x86-64 processors (like x86_64-*) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@Soveu
Copy link
Contributor

Soveu commented Mar 25, 2021

I tried this code:

#![feature(asm)]

#[inline(always)]
fn check_bsf() -> (u64, u8) {
    let flags: u8;
    let result: u64;

    unsafe {
        asm!(
            "bsf rbx, rbx",
            "lahf",
            inout("rbx") 0u64 => result,
            out("ah") flags,
            options(nostack, nomem),
        );
    }

    return (result, flags);
}

fn main() {
    let flags1: u8;
    unsafe {
        asm!("lahf", out("ah") flags1, options(nostack, nomem));
    }

    let (result, flags2) = check_bsf();
    let flagsdiff = flags2 ^ flags1;
    let zero_flag = 1 << 6;

    println!("result={}", result);
    assert_eq!(flagsdiff, zero_flag);
}

I expected to see this happen:
The code compiles, like with opt-level 0 or 1

Instead, this happened:
When compiling with opt-level 2 or 3, just this message appears

LLVM ERROR: Cannot encode high byte register in REX-prefixed instruction

Meta

rustc --version --verbose:

rustc 1.53.0-nightly (07e0e2ec2 2021-03-24)
binary: rustc
commit-hash: 07e0e2ec268c140e607e1ac7f49f145612d0f597
commit-date: 2021-03-24
host: x86_64-unknown-linux-gnu
release: 1.53.0-nightly
LLVM version: 12.0.0

No backtrace

@Soveu Soveu added the C-bug Category: This is a bug. label Mar 25, 2021
@jonas-schievink jonas-schievink added A-inline-assembly Area: Inline assembly (`asm!(…)`) F-asm `#![feature(asm)]` (not `llvm_asm`) labels Mar 25, 2021
@nagisa nagisa added E-needs-mcve Call for participation: This issue has a repro, but needs a Minimal Complete and Verifiable Example and removed E-needs-mcve Call for participation: This issue has a repro, but needs a Minimal Complete and Verifiable Example labels Mar 25, 2021
@nagisa
Copy link
Member

nagisa commented Mar 26, 2021

Minimal-ish IR test case:

define dso_local void @main(i64* %arg) unnamed_addr {
  %a = tail call { i64, i8 } asm "", "={bx},={ah}"()
  %_4.0 = extractvalue { i64, i8 } %a, 0
  %_4.1 = extractvalue { i64, i8 } %a, 1
  store i64 %_4.0, i64* %arg
  %1 = xor i8 %_4.1, 0
  call void @banana()
  %_30.not = icmp eq i8 %1, 64
  br i1 %_30.not, label %bb7, label %bb6

bb6:
  unreachable

bb7:
  unreachable
}

declare dso_local void @banana() unnamed_addr

Pending verification if reproducible in LLVM main. https://bugs.llvm.org/show_bug.cgi?id=49729

@JohnTitor JohnTitor added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Mar 26, 2021
@Amanieu
Copy link
Member

Amanieu commented Apr 4, 2021

I'm considering just outright banning the use of ah on x86_64 with a note to use ax instead.

Amanieu added a commit to Amanieu/rust that referenced this issue Apr 4, 2021
@jonas-schievink jonas-schievink added the O-x86_64 Target: x86-64 processors (like x86_64-*) label Apr 4, 2021
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this issue Apr 5, 2021
Disallow the use of high byte registes as operands on x86_64

They are still allowed on x86 though.

Fixes rust-lang#83495

r? ``@nagisa``
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this issue Apr 5, 2021
Disallow the use of high byte registes as operands on x86_64

They are still allowed on x86 though.

Fixes rust-lang#83495

r? `@nagisa`
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this issue Apr 5, 2021
Disallow the use of high byte registes as operands on x86_64

They are still allowed on x86 though.

Fixes rust-lang#83495

r? `@nagisa`
@bors bors closed this as completed in b1bcff0 Apr 5, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-inline-assembly Area: Inline assembly (`asm!(…)`) C-bug Category: This is a bug. F-asm `#![feature(asm)]` (not `llvm_asm`) O-x86_64 Target: x86-64 processors (like x86_64-*) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants