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

Invalid inline assembly is silently discarded #22892

Closed
devyn opened this issue Feb 28, 2015 · 12 comments
Closed

Invalid inline assembly is silently discarded #22892

devyn opened this issue Feb 28, 2015 · 12 comments
Labels
A-inline-assembly Area: Inline assembly (`asm!(…)`) C-bug Category: This is a bug. requires-nightly This issue requires a nightly compiler in some way.

Comments

@devyn
Copy link

devyn commented Feb 28, 2015

Minimal testcase:

#![feature(asm)]

fn main() {
    let byte = 0;
    let port = 0x80;

    unsafe { asm!("out %al, %dx" :: "a" (byte), "d" (port) :: "volatile"); }
}

rustc --version:

rustc 1.0.0-nightly (4db0b3246 2015-02-25) (built 2015-02-26)

rustc output:

$ rustc mintest.rs
$

(i.e., nothing)

Resulting objdump on x86_64-unknown-linux-gnu:

0000000000005070 <_ZN4main20h953519ae653eac04eaaE>:
    5070:       64 48 3b 24 25 70 00    cmp    %fs:0x70,%rsp
    5077:       00 00 
    5079:       77 1a                   ja     5095 <_ZN4main20h953519ae653eac04eaaE+0x25>
    507b:       49 ba 10 00 00 00 00    movabs $0x10,%r10
    5082:       00 00 00 
    5085:       49 bb 00 00 00 00 00    movabs $0x0,%r11
    508c:       00 00 00 
    508f:       e8 80 00 00 00          callq  5114 <__morestack>
    5094:       c3                      retq   
    5095:       48 83 ec 10             sub    $0x10,%rsp
    5099:       c7 44 24 0c 00 00 00    movl   $0x0,0xc(%rsp)
    50a0:       00 
    50a1:       c7 44 24 08 80 00 00    movl   $0x80,0x8(%rsp)
    50a8:       00 
    50a9:       8b 44 24 0c             mov    0xc(%rsp),%eax
    50ad:       8b 4c 24 08             mov    0x8(%rsp),%ecx
    50b1:       89 44 24 04             mov    %eax,0x4(%rsp)
    50b5:       89 0c 24                mov    %ecx,(%rsp)
    50b8:       48 83 c4 10             add    $0x10,%rsp
    50bc:       c3                      retq   
    50bd:       0f 1f 00                nopl   (%rax)

Unless I'm missing something, I should either get an error, or I should see "out %al, %dx" somewhere in there, but instead, absolutely nothing happens.

@huonw huonw added the A-inline-assembly Area: Inline assembly (`asm!(…)`) label Feb 28, 2015
@devyn
Copy link
Author

devyn commented Mar 1, 2015

LLVM IR appears to include the inline asm, so I'm guessing this is an LLVM bug:

; ModuleID = 'mintest.0.rs'
target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

@const10 = internal unnamed_addr constant i32 0
@const14 = internal unnamed_addr constant i32 128

; Function Attrs: uwtable
define internal void @_ZN4main20h4fb6a247161ac946eaaE() unnamed_addr #0 {
entry-block:
  %byte = alloca i32
  %port = alloca i32
  store i32 0, i32* %byte
  store i32 128, i32* %port
  %0 = load i32* %byte
  %1 = load i32* %port
  call void asm sideeffect "out %al, %dx", "a,d,~{dirflag},~{fpsr},~{flags}"(i32 %0, i32 %1), !srcloc !0
  ret void
}

define i64 @main(i64, i8**) unnamed_addr #1 {
top:
  %2 = call i64 @_ZN2rt10lang_start20hb1b8686306685c6ftRLE(i8* bitcast (void ()* @_ZN4main20h4fb6a247161ac946eaaE to i8*), i64 %0, i8** %1)
  ret i64 %2
}

declare i64 @_ZN2rt10lang_start20hb1b8686306685c6ftRLE(i8*, i64, i8**) unnamed_addr #1

attributes #0 = { uwtable "split-stack" }
attributes #1 = { "split-stack" }

!0 = !{i32 1}

I'll check to see what clang does.

@devyn
Copy link
Author

devyn commented Mar 1, 2015

C source:

int main(int argc, char **argv)
{
    unsigned char  byte = 0;
    unsigned short port = 0x80;

    asm volatile("out %%al, %%dx" :: "a" (byte), "d" (port));
}

clang LLVM IR (clang -emit-llvm -S mintest.c):

; ModuleID = 'mintest.c'
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

; Function Attrs: nounwind uwtable
define i32 @main(i32 %argc, i8** %argv) #0 {
  %1 = alloca i32, align 4
  %2 = alloca i8**, align 8
  %byte = alloca i8, align 1
  %port = alloca i16, align 2
  store i32 %argc, i32* %1, align 4
  store i8** %argv, i8*** %2, align 8
  store i8 0, i8* %byte, align 1
  store i16 128, i16* %port, align 2
  %3 = load i8* %byte, align 1
  %4 = load i16* %port, align 2
  call void asm sideeffect "out %al, %dx", "{ax},{dx},~{dirflag},~{fpsr},~{flags}"(i8 %3, i16 %4) #1, !srcloc !1
  ret i32 0
}

attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind }

!llvm.ident = !{!0}

!0 = metadata !{metadata !"clang version 3.5.1 (tags/RELEASE_351/final)"}
!1 = metadata !{i32 115}

So it looks like it might be a Rust bug after all; Rust should be generating {ax} and {dx} constraints in the IR?

@devyn
Copy link
Author

devyn commented Mar 2, 2015

Okay, so I looked at this again today:

asm!("out %al, %dx" :: "{ax}" (byte), "{dx}" (port) :: "volatile");

seems to work just fine. The relevant LLVM documentation is for struct llvm::InlineAsm::SubConstraintInfo, field Codes where it specifies that the register name may come in braces, but doesn't really say anything more specific than that.

If Rust isn't receiving an error from LLVM about the invalid constraint, that's an LLVM bug, right? Still, I would like Rust documentation to be a little more specific about what constraints are allowed in asm! and perhaps for rustc to verify them, if LLVM won't.

@thepowersgang
Copy link
Contributor

This issue appears to have returned with the recent LLVM update. If the data type passed to the inline assembly does not match the register size, the assembly is not emitted into assembly.

#![feature(asm)]

fn main() {
    unsafe {
        // - Errors, as expected
        //asm!("lttr %cx" : : "{ecx}" (7*8));
        // No error, no emitted instruction.
        asm!("lttr %cx" : : "{rcx}" (7*8));
    }
}

@jethrogb
Copy link
Contributor

This is still a problem. Title of this bug should be: Invalid inline assembly is silently discarded.

@devyn devyn changed the title Inline assembly fails to generate OUT instruction with the required constraints Invalid inline assembly is silently discarded Jan 14, 2016
@devyn
Copy link
Author

devyn commented Jan 14, 2016

Updated.

@Mark-Simulacrum
Copy link
Member

Mark-Simulacrum commented Apr 16, 2017

Minimal test case from top comment produces, so presumably this is fixed. However, output files (rust_out.0.o and rust_out.crate.metadata.o) are still produced despite the error, so I'm not sure if this should be closed quite yet. If yes, please do so.

error: couldn't allocate input reg for constraint 'a'
 --> <anon>:7:14
  |
7 |     unsafe { asm!("out %al, %dx" :: "a" (byte), "d" (port) :: "volatile"); }
  |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

Edit: This probably means #26648 is also fixed, but I'm not sure...

@Mark-Simulacrum
Copy link
Member

If anyone can reproduce, please reopen. I haven't been able to reproduce since the original source doesn't quite compile--we should open another issue about incomplete compiles leaving files behind.

@jethrogb
Copy link
Contributor

Might be good to add a regression test?

@Mark-Simulacrum
Copy link
Member

Hmm, yeah. I'll reopen and mark as E-needstest.

@Mark-Simulacrum Mark-Simulacrum added the E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. label Apr 28, 2017
@Mark-Simulacrum Mark-Simulacrum added the C-bug Category: This is a bug. label Jul 22, 2017
varkor added a commit to varkor/rust that referenced this issue Feb 26, 2019
Centril added a commit to Centril/rust that referenced this issue Feb 27, 2019
…hton

Add tests for several E-needstest issues

This PR adds a number of tests for various `E-needstest` errors. These tend to have been left open for a long time and seem unlikely to be closed otherwise.

Closes rust-lang#10876.
Closes rust-lang#22892.
Closes rust-lang#26448.
Closes rust-lang#26577.
Closes rust-lang#26619.
Closes rust-lang#27054.
Closes rust-lang#28587.
Closes rust-lang#44127.
Closes rust-lang#44255.
Closes rust-lang#55731.
Closes rust-lang#57781.
varkor added a commit to varkor/rust that referenced this issue Feb 27, 2019
pietroalbini added a commit to pietroalbini/rust that referenced this issue Mar 1, 2019
…hton

Add tests for several E-needstest issues

This PR adds a number of tests for various `E-needstest` errors. These tend to have been left open for a long time and seem unlikely to be closed otherwise.

Closes rust-lang#10876.
Closes rust-lang#22892.
Closes rust-lang#26448.
Closes rust-lang#26577.
Closes rust-lang#26619.
Closes rust-lang#27054.
Closes rust-lang#28587.
Closes rust-lang#44127.
Closes rust-lang#44255.
Closes rust-lang#55731.
Closes rust-lang#57781.
Centril added a commit to Centril/rust that referenced this issue Mar 9, 2019
…hton

Add tests for several E-needstest issues

This PR adds a number of tests for various `E-needstest` errors. These tend to have been left open for a long time and seem unlikely to be closed otherwise.

Closes rust-lang#10876.
Closes rust-lang#22892.
Closes rust-lang#26448.
Closes rust-lang#26577.
Closes rust-lang#26619.
Closes rust-lang#27054.
Closes rust-lang#28587.
Closes rust-lang#44127.
Closes rust-lang#44255.
Closes rust-lang#55731.
Closes rust-lang#57781.
Centril added a commit to Centril/rust that referenced this issue Mar 9, 2019
…hton

Add tests for several E-needstest issues

This PR adds a number of tests for various `E-needstest` errors. These tend to have been left open for a long time and seem unlikely to be closed otherwise.

Closes rust-lang#10876.
Closes rust-lang#22892.
Closes rust-lang#26448.
Closes rust-lang#26577.
Closes rust-lang#26619.
Closes rust-lang#27054.
Closes rust-lang#28587.
Closes rust-lang#44127.
Closes rust-lang#44255.
Closes rust-lang#55731.
Closes rust-lang#57781.
@varkor
Copy link
Member

varkor commented Mar 9, 2019

There seem to still be issues with this test case on armhf-gnu: #59046 (comment).

@varkor varkor removed the E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. label Mar 9, 2019
varkor added a commit to varkor/rust that referenced this issue Mar 11, 2019
varkor added a commit to varkor/rust that referenced this issue Mar 12, 2019
@Centril Centril added the requires-nightly This issue requires a nightly compiler in some way. label Oct 25, 2019
@Amanieu
Copy link
Member

Amanieu commented May 22, 2020

This issue does not apply to the new asm! (RFC 2850) which validates the operand register classes.

The legacy llvm_asm! is deprecated and is no longer maintained.

@Amanieu Amanieu closed this as completed May 22, 2020
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. requires-nightly This issue requires a nightly compiler in some way.
Projects
None yet
Development

No branches or pull requests

8 participants