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 assertion: Can only indirectify direct input operands! #29382

Open
Amanieu opened this Issue Oct 26, 2015 · 7 comments

Comments

Projects
None yet
6 participants
@Amanieu
Copy link
Contributor

Amanieu commented Oct 26, 2015

The following code triggers an LLVM assert:

#![feature(asm)]
unsafe fn test(x: *mut u32) {
    asm!("": "=m" (*x));
}
rustc: /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp:6012: void llvm::SelectionDAGBuilder::visitInlineAsm(llvm::ImmutableCallSite): Assertion `(OpInfo.isMultipleAlternative || (OpInfo.Type == InlineAsm::isInput)) && "Can only indirectify direct input operands!"' failed.

One thing of note in the LLVM output is this line:

%5 = call i32 asm "", "=m,~{dirflag},~{fpsr},~{flags}"(), !dbg !199, !srcloc !201

Note that the operand to the asm is left empty for some reason, which is probably wrong.

@Amanieu

This comment has been minimized.

Copy link
Contributor Author

Amanieu commented Nov 3, 2015

Here is what clang generates for equivalent code, it seems to translate "m" and "=m" into "*m" and "=*m":

call void asm "", "=*m"(i32* %2) #1, !srcloc !3

Using the =*m constraint directly from rust is difficult because type checking treats it as an output even though the parameter is an input pointer value.

bors added a commit that referenced this issue Nov 4, 2015

Auto merge of #29543 - Amanieu:asm_mem_constraint, r=alexcrichton
The "m" memory constraint in inline assembly is broken (generates incorrect code or triggers LLVM asserts) and should not be used. Instead, indirect memory operands should be used with "\*m", "=\*m" and "+\*m".

Clang does this transparently by transforming "m" constraints into "\*m" indirect constraints, but for now just being able to use "\*m" directly is enough since asm! isn't stable.

While "\*m" works fine as an input operand, "=\*m" and "+\*m" need to be specified as input operands because they take a pointer value as an input. This PR relaxes the constraint checker to allow constraints starting with "=" or "+" if the constraint string contains a "\*", which indicates an indirect operand.

This (indirectly) fixes these issues: #29382, #16383 and #13366. The code will need to be changed to use "\*m" instead of "m".
@brson

This comment has been minimized.

Copy link
Contributor

brson commented Apr 11, 2017

Still repros.

@steveklabnik

This comment has been minimized.

Copy link
Member

steveklabnik commented Apr 11, 2017

playpen repro: https://is.gd/rUbnON

@eddyb

This comment has been minimized.

Copy link
Member

eddyb commented Apr 11, 2017

@Amanieu By _ you mean *?

@Amanieu

This comment has been minimized.

Copy link
Contributor Author

Amanieu commented Apr 11, 2017

@eddyb yes

@eddyb

This comment has been minimized.

Copy link
Member

eddyb commented Apr 11, 2017

@Amanieu We should update the compiler to treat =*m as write to *output, I guess.
Maybe MIR borrowck will be able to handle it better shrug.

@istankovic

This comment has been minimized.

Copy link
Contributor

istankovic commented Mar 18, 2018

Still a problem with rustc 1.26.0-nightly (adf2135ad 2018-03-17).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.