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

Clarify that asm! blocks can be duplicated or deduplicated by the compiler #1441

Merged
merged 1 commit into from
Jul 9, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/inline-assembly.md
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,7 @@ To avoid undefined behavior, these rules must be followed when using function-sc
- The compiler cannot assume that the instructions in the asm are the ones that will actually end up executed.
- This effectively means that the compiler must treat the `asm!` as a black box and only take the interface specification into account, not the instructions themselves.
- Runtime code patching is allowed, via target-specific mechanisms.
- However there is no guarantee that each `asm!` directly corresponds to a single instance of instructions in the object file: the compiler is free to duplicate or deduplicate `asm!` blocks.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the lines above, we specify that the compiler is not allowed to examine the instructions. How is it possible to deduplicate asm blocks without analyzing the instructions within?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand correctly, it's that in the very end, LLVM sees two functions that have the exact same instructions emitted and then merges them. I agree that it's slightly weird that that's how it works, but I think LLVM's justification is that it doesn't analyze behavior, just the exact instructions that its assembler emits.

Ideally we would have a way to tell codegen to knock it off and really don't do anything if it sees asm! in a function, but I'm not sure if LLVM (or other backends) support that.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Essentially deduplication can happen when the exact same asm text is generated twice. It's a bit tricky to specify since technically some extra whitespace would cause deduplication to fail, but I'm not sure we want to guarantee that.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should explicitly specify the other direction as well (no guarantee that an instance of instructions in the object file corresponds to exactly one asm! expression). When only stated in the current direction, the lack of guarantee could still be understood as only permitting duplication or removal of asm!, where unification is the originating observed behavior.

Separately, it would be good to specify when disjoint asm! are able to be unified, given the prior assertion that the compiler is not permitted to rely on the contents of the asm! string being the instructions which get executed. I think the correct precondition would be that the instantiated asm! strings are structurally equivalent — that the directives/instructions given to the assembler are identical.

The compiler is not permitted to interpret the effect of the directives/instructions, but it is permitted to inspect the identity of thus.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should explicitly specify the other direction as well (no guarantee that an instance of instructions in the object file corresponds to exactly one asm! expression). When only stated in the current direction, the lack of guarantee could still be understood as only permitting duplication or removal of asm!, where unification is the originating observed behavior.

I think this is already covered by the word "deduplicate"?

Separately, it would be good to specify when disjoint asm! are able to be unified, given the prior assertion that the compiler is not permitted to rely on the contents of the asm! string being the instructions which get executed. I think the correct precondition would be that the instantiated asm! strings are structurally equivalent — that the directives/instructions given to the assembler are identical.

The compiler is not permitted to interpret the effect of the directives/instructions, but it is permitted to inspect the identity of thus.

I think that we may have to allow more flexibility here due to things like link-time identical code folding. This would merge separate asm that may be structurally different but end up emitting the same bytes. I'm open to suggestions on the exact wording to use here.

- Unless the `nostack` option is set, asm code is allowed to use stack space below the stack pointer.
- On entry to the asm block the stack pointer is guaranteed to be suitably aligned (according to the target ABI) for a function call.
- You are responsible for making sure you don't overflow the stack (e.g. use stack probing to ensure you hit a guard page).
Expand Down