-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Tracking Issue for inline assembly (asm!
)
#72016
Comments
asm!
)
Note: if you'd like to report an issue in inline assembly, please report it as a separate github issue, and just link to this one. Please don't report issues in inline assembly as comments on this tracking issue. |
Definitely want the explicit import. This would also make it a bit clearer what's going on when somebody tries to compile an old-style |
On Mon, May 25, 2020 at 03:56:53PM -0700, Bart Massey wrote:
Definitely want the explicit import. This would also make it a bit clearer what's going on when somebody tries to compile an old-style `asm!` with a newer compiler, which is going to happen a lot: you'd get an unresolved symbol rather than mysterious syntax errors.
Rust will actually catch many instances of this. Any use of the old
`asm!` syntax that has any operands at all will get caught in the parser
(because it uses a ':'), and result in a very clear error telling the
user about the syntax transition, and a hint suggesting `llvm_asm!`. (At
some point that hint should also start suggesting the use of the new
syntax.)
The only case that wouldn't be caught in the parser would be if you have
an `asm!` that has no inputs, no outputs, no clobbers, and no options,
so it just looks like `asm!("...");`. In that case, on x86, it'll give
you an assembly syntax error from the backend if you used AT&T syntax.
We might, theoretically, be able to do a little better than *that*, as
well; looking into that.
|
Minor compatibility concern: Other backends using external assemblers may need to do some pre-processing before passing the asm text to them. |
GNU Assembler (IIRC defined as the official assembly dialect by the RFC), and by extension GCC, supports C-style comments too, so they are definitely not LLVM-specific. |
I am also in favor of explicit imports from arch modules. I would suggest going even further and introduce separate macros for each supported target (e.g. |
Some feedback from various places in response to the blog post. (I'm skipping general expressions of awesomeness, though there have been many; I'm quoting those that have specific feedback.) @amluto (Andy Lutomirski, prominent Linux kernel developer who works on a lot of low-level x86) at https://news.ycombinator.com/item?id=23467108 :
Several people on HN were a little confused about the backward-compatibility story here; in the future, when we talk about features that have only existed on nightly, we need to be more clear in the future about messaging around our stability policy. Several people wondered why this used a string constant; it'd be good to explain that in documentation. And this doesn't mean the assembly isn't parsed, it means it isn't parsed by rustc (it's parsed by LLVM in the backend). We really should have mentioned, in the blog post, that AT&T syntax was supported with Someone mentioned preferring an "explicit clobber" syntax (like Closely related, I think we should definitely have both "clobber all function-clobbered registers" and "clobber all general-purpose registers" options. |
I’ll add one more comment: please document what happens if you try to use not-quite-general-purpose registers as operands (clobber or otherwise). The most important case is the PIC register. GCC does not appreciate inline asm that clobbers the PIC register. IMO it should be allowed, especially for things like CPUID on x86_32. This also includes thinks like EBP/RBP. If I’m building with frame pointers on or I do something that forces a frame pointer, is RBP available? RSP is another example — presumably it’s not available. |
Actually what I feel a lot of people are really asking is: "Why isn't this just like MSVC's The issue with that approach is that in a lot of cases, we can't actually figure out the constraints just from the assembly code. Common examples are call and syscall instructions which can have an arbitrary ABI. Finally, if you really want it, you can parse the asm code in a proc macro and derive the necessary input/output/clobber operations from it. In fact, this is what Clang does to support the MS
This is actually quite tricky and I believe it is a bug for the back-end (GCC/LLVM) to silently accept the use of these registers and then generate wrong code (for example by not preserving the PIC base around the We currently always disallow the use of the stack pointer and frame pointer as operands for inline asm in the front-end. However the exact set of reserved registers depends not only on the current target but can also be different depending on the properties of the function:
These properties can vary depending on the optimization level and inlining so there is no way we can selectively enforce this in the front-end. A blanket ban on the use of registers that may be reserved is also a non-starter since these registers are commonly used (e.g. for syscall arguments). |
One more issue I've observed in several contexts: everyone formats Notably, this includes how to format both single-line and multi-line assembly statements. EDIT: originally, in this comment, I proposed an initial set of requirements. To keep format bikeshedding out of this tracking issue, I've moved that to an issue on the fmt-rfcs repo. |
I'm trying to implement an optimization barrier like The following code is working so far. However, it seems that it's relying on an undocumented behavior of the compiler. Is there any legit way to avoid the "argument never used" error? #[inline]
fn secure(mut x: f64) -> f64 {
unsafe {
// Won't compile without `# {0}` due to an "argument never used" error.
asm!("# {0}", inout(xmm_reg) x, options(nomem, nostack));
}
x
}
Full example code (should be built with
|
I don't think a blackbox is enough for LLVM to always use the rounding mode you want. I think LLVM is allowed to reset the rounding mode at any point in your code. I think your code is only guaranteed to work fine when you pass the https://reviews.llvm.org/D62731
|
Thank you for your reply. Thank you for letting me know about them! |
Another comment that seems relevant to capture:
Are these supported by LLVM? |
I thought |
Those aren't separators, they are part of the instruction name on AArch64. They do not exist on 32-bit ARM. |
Per the bug report referenced in the above, `asm!` is back ― but it has a [brand-new syntax](https://doc.rust-lang.org/nightly/unstable-book/library-features/asm.html) associated with it that includes, among other things, `intel` and `volatile` by default. As if that's not enough, they're now deprecating `llvm_asm!` upstream in favor of this.
Given the caveats around labels with intel syntax (labels should be numeric, but can't be 0, 1, or a number made up of only those digits), is it worth getting an issue on file to at least improve the error messages? Is there one already? |
We have a |
Stabilize asm! and global_asm! Tracking issue: rust-lang#72016 It's been almost 2 years since the original [RFC](rust-lang/rfcs#2850) was posted and we're finally ready to stabilize this feature! The main changes in this PR are: - Removing `asm!` and `global_asm!` from the prelude as per the decision in rust-lang#87228. - Stabilizing the `asm` and `global_asm` features. - Removing the unstable book pages for `asm` and `global_asm`. The contents are moved to the [reference](rust-lang/reference#1105) and [rust by example](rust-lang/rust-by-example#1483). - All links to these pages have been removed to satisfy the link checker. In a later PR these will be replaced with links to the reference or rust by example. - Removing the automatic suggestion for using `llvm_asm!` instead of `asm!` if you're still using the old syntax, since it doesn't work anymore with `asm!` no longer being in the prelude. This only affects code that predates the old LLVM-style `asm!` being renamed to `llvm_asm!`. - Updating `stdarch` and `compiler-builtins`. - Updating all the tests. r? `@joshtriplett`
Stabilize asm! and global_asm! Tracking issue: rust-lang#72016 It's been almost 2 years since the original [RFC](rust-lang/rfcs#2850) was posted and we're finally ready to stabilize this feature! The main changes in this PR are: - Removing `asm!` and `global_asm!` from the prelude as per the decision in rust-lang#87228. - Stabilizing the `asm` and `global_asm` features. - Removing the unstable book pages for `asm` and `global_asm`. The contents are moved to the [reference](rust-lang/reference#1105) and [rust by example](rust-lang/rust-by-example#1483). - All links to these pages have been removed to satisfy the link checker. In a later PR these will be replaced with links to the reference or rust by example. - Removing the automatic suggestion for using `llvm_asm!` instead of `asm!` if you're still using the old syntax, since it doesn't work anymore with `asm!` no longer being in the prelude. This only affects code that predates the old LLVM-style `asm!` being renamed to `llvm_asm!`. - Updating `stdarch` and `compiler-builtins`. - Updating all the tests. r? `@joshtriplett`
127: Add scalar optimizations from CRoaring / arXiv:1709.07821 section 3 r=Kerollmops a=saik0 ### Purpose This PR adds some optimizations from CRoaring as outlined in arXiv:1709.07821 section 3 ### Overview * All inserts and removes are now branchless (!in arXiv:1709.0782, in CRoaring) * Section 3.1 was already implemented, except for `BitmapIter`. This is covered in #125 * Implement Array-Bitset aggregates as outlined in section 3.2 * Also branchless 😎 * Tracks bitmap cardinality while performing bitmap-bitmap ops * This is a deviation from CRoaring, and will need to be benchmarked further before this Draft PR is ready * Curious to hear what you think about this `@lemire` * In order to track bitmap cardinality the len field had to moved into `Store::Bitmap` * This is unfortunately a cross cutting change * `Store` was quite large (LoC) and had many responsibilities. The largest change in this draft is decomposing `Store` such hat it's field variants are two new container types: each responsible for maintaining their invariants and implementing `ops` * `Bitmap8K` keeps track of it's cardinality * `SortedU16Vec` maintains its sorting * `Store` now only delegates to these containers * My hope is that this will be useful when implementing run containers. 🤞 * Unfortunately so much code was moved this PR is _HUGE_ ### Out of scope * Inline ASM for Array-Bitset aggregates * Section 4 (explicit SIMD). As noted by the paper authors: The compiler does a decent job of autovectorization, though not as good as hand-tuned ### Notes * I attempted to emulate the inline ASM Array-Bitset aggregates by using a mix of unsafe ptr arithmetic and x86-64 intrinsics, hoping to compile to the same instructions. I was unable to get it under 13 instructions per iteration (compared to the papers 5). While it was an improvement, I abandoned the effort in favor of waiting for the `asm!` macro to stabilize. rust-lang/rust#72016 Co-authored-by: saik0 <[email protected]> Co-authored-by: Joel Pedraza <[email protected]>
I see that there are some new feature flags in nightly for tracking the long tail of |
I created separate tracking issues for each sub-feature:
This tracking issue can be closed now that |
Update tracking issue numbers for inline assembly sub-features The main tracking issue for inline assembly is [closed](rust-lang#72016 (comment)), further tracking of the remaining sub-features has been moved to separate tracking issues.
127: Add scalar optimizations from CRoaring / arXiv:1709.07821 section 3 r=Kerollmops a=saik0 ### Purpose This PR adds some optimizations from CRoaring as outlined in arXiv:1709.07821 section 3 ### Overview * All inserts and removes are now branchless (!in arXiv:1709.0782, in CRoaring) * Section 3.1 was already implemented, except for `BitmapIter`. This is covered in RoaringBitmap#125 * Implement Array-Bitset aggregates as outlined in section 3.2 * Also branchless 😎 * Tracks bitmap cardinality while performing bitmap-bitmap ops * This is a deviation from CRoaring, and will need to be benchmarked further before this Draft PR is ready * Curious to hear what you think about this `@lemire` * In order to track bitmap cardinality the len field had to moved into `Store::Bitmap` * This is unfortunately a cross cutting change * `Store` was quite large (LoC) and had many responsibilities. The largest change in this draft is decomposing `Store` such hat it's field variants are two new container types: each responsible for maintaining their invariants and implementing `ops` * `Bitmap8K` keeps track of it's cardinality * `SortedU16Vec` maintains its sorting * `Store` now only delegates to these containers * My hope is that this will be useful when implementing run containers. 🤞 * Unfortunately so much code was moved this PR is _HUGE_ ### Out of scope * Inline ASM for Array-Bitset aggregates * Section 4 (explicit SIMD). As noted by the paper authors: The compiler does a decent job of autovectorization, though not as good as hand-tuned ### Notes * I attempted to emulate the inline ASM Array-Bitset aggregates by using a mix of unsafe ptr arithmetic and x86-64 intrinsics, hoping to compile to the same instructions. I was unable to get it under 13 instructions per iteration (compared to the papers 5). While it was an improvement, I abandoned the effort in favor of waiting for the `asm!` macro to stabilize. rust-lang/rust#72016 Co-authored-by: saik0 <[email protected]> Co-authored-by: Joel Pedraza <[email protected]>
Hi @nagisa , In the reference for inline assembly for Rust, only input operand type is that of register operand. Do we have similar method use variable as input from memory rather than register ? |
Next time please open a new issue, or even better, ask on Zulip, rather than commenting on one that has been closed for more than a year at this point. As far as I know, no, memory operands are considered a future possibility by the RFC that implemented inline assembly and would require some design & implementation work. Your next best bet is to pass in an address to the variable in a register. |
This is a tracking issue for the RFC 2873 (rust-lang/rfcs#2873).
The feature gate for the issue is
#![feature(asm)]
.Stabilization
Blockers: Tracking Issue for inline assembly (asm!
) #72016 (comment)Blockers: Tracking Issue for inline assembly (asm!
) #72016 (comment)asm!
) #72016 (comment)Steps
asm!
#76738)Implementation history
January status update
April status update
July status update
November stabilization report for FCP
November FCP checklist
The text was updated successfully, but these errors were encountered: