Skip to content

attach global target features to module-level assembly - #160594

Merged
rust-bors[bot] merged 1 commit into
rust-lang:mainfrom
folkertdev:asm-forward-target-features
Aug 29, 2026
Merged

rust-bors[bot] merged 1 commit into
rust-lang:mainfrom
folkertdev:asm-forward-target-features

Conversation

@folkertdev

@folkertdev folkertdev commented Aug 5, 2026 •

Copy link
Copy Markdown
Contributor

View all comments

  • I did not use an LLM to create a change in this PR.
  • I used an LLM to create a change in this PR, and I have explained below how it was used.

fixes #80608
fixes #127269

At long last, we can forward global target features to LLVM and it will preserve the target features a block of module-level assembly was defined with through LTO.

cc @nikic (who made this happen)
cc @RalfJung any nasty side-effects we might be overlooking here?

@rustbot rustbot added the A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. label Aug 5, 2026
@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Aug 5, 2026
@rustbot

rustbot commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

r? @petrochenkov

rustbot has assigned @petrochenkov.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: compiler
  • compiler expanded to 75 candidates
  • Random selection from 17 candidates

Props.TargetFeatures = StringRef(TargetFeatures, TargetFeaturesLen);
Props.TargetCPU = StringRef(TargetCPU, TargetCPULen);
unwrap(M)->appendModuleInlineAsm(
Module::GlobalAsmFragment(std::string(Asm, AsmLen), std::move(Props)));

@folkertdev folkertdev Aug 5, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

  • the std::move is required here. It isn't there in some of the LLVM source, I'm not sure why, but llvm complains loudly without it.
  • I believe this needs a std::string instead of a StringRef because GlobalAsmFragment needs something owned. Hopefully this is right in terms of ownership and cleanup?

View changes since the review

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

the std::move is required here. It isn't there in some of the LLVM source, I'm not sure why, but llvm complains loudly without it.

Shouldn't really be required here, but the std::move is fine...

I believe this needs a std::string instead of a StringRef because GlobalAsmFragment needs something owned. Hopefully this is right in terms of ownership and cleanup?

Either would work, but it will become an owned std::string in the end, so construct it as such makes sense.

|
LL | .intel_syntax noprefix
| ^
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

@folkertdev folkertdev Aug 5, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

no idea where this comes from

View changes since the review

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Me neither...

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

-Z deduplicate-diagnostics=no is set by compiletest AFAIK.

@nikic nikic Aug 26, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The question is more why the diagnostic appears twice after this change :)

llvm::append_module_inline_asm(llmod, &asm, "", "");
let asm = create_section_with_flags_asm(".llvmcmd", section_flags, &[]);
llvm::append_module_inline_asm(llmod, &asm);
llvm::append_module_inline_asm(llmod, &asm, "", "");

@folkertdev folkertdev Aug 5, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I believe we just embed bytes here, so the target features and cpu don't seem relevant.

View changes since the review

@rust-log-analyzer

This comment has been minimized.

@RalfJung

RalfJung commented Aug 5, 2026

Copy link
Copy Markdown
Member

any nasty side-effects we might be overlooking here?

I don't have the slightest clue what it means to forward target features to assembly.^^

@folkertdev

Copy link
Copy Markdown
Contributor Author

Fair. So what this does is attach the target features and cpu information to piece of assembly. Previously the target information would sometimes get lost, especially when doing LTO and potentially merging modules with different target features. LLVM would error when assembly used instructions that are gated on a particular target feature, even though the feature is in fact globally enabled.

My practical question for you is: am I forwarding the right target features here? and might a particular target cpu that we forward imply target features that we didn't intend to enable?

@folkertdev
folkertdev force-pushed the asm-forward-target-features branch from 9bd2882 to 48835fa Compare August 5, 2026 22:37
@folkertdev folkertdev changed the title forward global target features to module-level assembly attach global target features to module-level assembly Aug 5, 2026
@rust-log-analyzer

This comment has been minimized.

@RalfJung

RalfJung commented Aug 6, 2026

Copy link
Copy Markdown
Member

I have no idea, sorry. I don't even know which potential problems one has to be aware of here.

@folkertdev
folkertdev force-pushed the asm-forward-target-features branch from 48835fa to fad8008 Compare August 6, 2026 08:57
@rust-log-analyzer

This comment has been minimized.

@folkertdev
folkertdev force-pushed the asm-forward-target-features branch from fad8008 to e416dec Compare August 6, 2026 09:45
@petrochenkov

Copy link
Copy Markdown
Contributor

r? @nikic

@rustbot rustbot assigned nikic and unassigned petrochenkov Aug 6, 2026
@rust-log-analyzer

This comment has been minimized.

@folkertdev
folkertdev force-pushed the asm-forward-target-features branch from e416dec to 9e1ce26 Compare August 6, 2026 10:56
@folkertdev

Copy link
Copy Markdown
Contributor Author

I've prepared a followup that also forwards target features on naked functions:

@nikic nikic left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks reasonable.

View changes since this review

#if LLVM_VERSION_GE(23, 0)
Module::GlobalAsmProperties Props;
Props.TargetFeatures = StringRef(TargetFeatures, TargetFeaturesLen);
Props.TargetCPU = StringRef(TargetCPU, TargetCPULen);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Both of these are std::strings. It's probably more obvious to directly construct it instead of creating it from StringRef.

Props.TargetFeatures = StringRef(TargetFeatures, TargetFeaturesLen);
Props.TargetCPU = StringRef(TargetCPU, TargetCPULen);
unwrap(M)->appendModuleInlineAsm(
Module::GlobalAsmFragment(std::string(Asm, AsmLen), std::move(Props)));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

the std::move is required here. It isn't there in some of the LLVM source, I'm not sure why, but llvm complains loudly without it.

Shouldn't really be required here, but the std::move is fine...

I believe this needs a std::string instead of a StringRef because GlobalAsmFragment needs something owned. Hopefully this is right in terms of ownership and cleanup?

Either would work, but it will become an owned std::string in the end, so construct it as such makes sense.

|
LL | .intel_syntax noprefix
| ^
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Me neither...

@folkertdev
folkertdev force-pushed the asm-forward-target-features branch from 9e1ce26 to 113d262 Compare August 26, 2026 08:58
@rustbot

rustbot commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@rust-log-analyzer

This comment has been minimized.

@folkertdev
folkertdev force-pushed the asm-forward-target-features branch from 113d262 to 0692ec5 Compare August 26, 2026 11:11
@rustbot

rustbot commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator

rustc_codegen_cranelift is developed in its own repository. If possible, consider making this change to rust-lang/rustc_codegen_cranelift instead.

cc @bjorn3

rustc_codegen_gcc is developed in its own repository. If possible, consider making this change to rust-lang/rustc_codegen_gcc instead.

cc @antoyo, @GuillaumeGomez

@folkertdev
folkertdev force-pushed the asm-forward-target-features branch from 0692ec5 to 37aaf5c Compare August 26, 2026 11:18
rust-bors Bot pushed a commit that referenced this pull request Aug 29, 2026
…uwer

Rollup of 16 pull requests

Successful merges:

 - #161945 (std: optimise IO error formatting)
 - #160594 (attach global target features to module-level assembly)
 - #161577 (implement [u8]::split_ascii_whitespace)
 - #161858 (fix ICE in generic_const_parameter_types with inherents)
 - #161377 ([bootstrap] Don't reverse the order of dylib search path entries)
 - #161702 (Use `drop_guard` in some places in {core,alloc,std})
 - #161804 (Document PartialOrd behavior for Option<T> where T: PartialOrd)
 - #161865 (loongarch: support passing `u128`/`i128` to inline assembly)
 - #161877 (Do not load macro metadata for local definitions in rustdoc)
 - #161880 (fix rustc_lint_defs doctest issues)
 - #161883 (better deal with internal features being injected into doctests)
 - #161887 (std: uefi: fix File::seek returning the EOF sentinel)
 - #161897 (Reject contract attributes without arguments)
 - #161909 (Report the configured Polonius default in -Z help)
 - #161910 (Add rustdoc-html regression test for generated macro)
 - #161914 (Retroactively add relnotes for `bool::{ok_or,ok_or_else}` (1.98.0))
Zalathar added a commit to Zalathar/rust that referenced this pull request Aug 29, 2026
…ures, r=nikic

attach global target features to module-level assembly

fixes rust-lang#80608
fixes rust-lang#127269

At long last, we can forward global target features to LLVM and it will preserve the target features a block of module-level assembly was defined with through LTO.

cc @nikic (who made this happen)
cc @RalfJung any nasty side-effects we might be overlooking here?
rust-bors Bot pushed a commit that referenced this pull request Aug 29, 2026
Rollup of 17 pull requests

Successful merges:

 - #161945 (std: optimise IO error formatting)
 - #160594 (attach global target features to module-level assembly)
 - #161577 (implement [u8]::split_ascii_whitespace)
 - #161858 (fix ICE in generic_const_parameter_types with inherents)
 - #161377 ([bootstrap] Don't reverse the order of dylib search path entries)
 - #161804 (Document PartialOrd behavior for Option<T> where T: PartialOrd)
 - #161865 (loongarch: support passing `u128`/`i128` to inline assembly)
 - #161877 (Do not load macro metadata for local definitions in rustdoc)
 - #161880 (fix rustc_lint_defs doctest issues)
 - #161883 (better deal with internal features being injected into doctests)
 - #161887 (std: uefi: fix File::seek returning the EOF sentinel)
 - #161897 (Reject contract attributes without arguments)
 - #161909 (Report the configured Polonius default in -Z help)
 - #161910 (Add rustdoc-html regression test for generated macro)
 - #161914 (Retroactively add relnotes for `bool::{ok_or,ok_or_else}` (1.98.0))
 - #161924 (Windows: document that `normalize_lexically` converts `/` to `\`)
 - #161927 (Change `rustc_middle/src/hooks/mod.rs` to `hooks.rs`)
rust-bors Bot pushed a commit that referenced this pull request Aug 29, 2026
Rollup of 17 pull requests

Successful merges:

 - #161945 (std: optimise IO error formatting)
 - #160594 (attach global target features to module-level assembly)
 - #161577 (implement [u8]::split_ascii_whitespace)
 - #161858 (fix ICE in generic_const_parameter_types with inherents)
 - #161377 ([bootstrap] Don't reverse the order of dylib search path entries)
 - #161804 (Document PartialOrd behavior for Option<T> where T: PartialOrd)
 - #161865 (loongarch: support passing `u128`/`i128` to inline assembly)
 - #161877 (Do not load macro metadata for local definitions in rustdoc)
 - #161880 (fix rustc_lint_defs doctest issues)
 - #161883 (better deal with internal features being injected into doctests)
 - #161887 (std: uefi: fix File::seek returning the EOF sentinel)
 - #161897 (Reject contract attributes without arguments)
 - #161909 (Report the configured Polonius default in -Z help)
 - #161910 (Add rustdoc-html regression test for generated macro)
 - #161914 (Retroactively add relnotes for `bool::{ok_or,ok_or_else}` (1.98.0))
 - #161924 (Windows: document that `normalize_lexically` converts `/` to `\`)
 - #161927 (Change `rustc_middle/src/hooks/mod.rs` to `hooks.rs`)
rust-bors Bot pushed a commit that referenced this pull request Aug 29, 2026
Rollup of 17 pull requests

Successful merges:

 - #161945 (std: optimise IO error formatting)
 - #160594 (attach global target features to module-level assembly)
 - #161577 (implement [u8]::split_ascii_whitespace)
 - #161858 (fix ICE in generic_const_parameter_types with inherents)
 - #161377 ([bootstrap] Don't reverse the order of dylib search path entries)
 - #161804 (Document PartialOrd behavior for Option<T> where T: PartialOrd)
 - #161865 (loongarch: support passing `u128`/`i128` to inline assembly)
 - #161877 (Do not load macro metadata for local definitions in rustdoc)
 - #161880 (fix rustc_lint_defs doctest issues)
 - #161883 (better deal with internal features being injected into doctests)
 - #161887 (std: uefi: fix File::seek returning the EOF sentinel)
 - #161888 (compiler: Allow safestack to be togglable via #[sanitize(safestack = "...")])
 - #161897 (Reject contract attributes without arguments)
 - #161910 (Add rustdoc-html regression test for generated macro)
 - #161914 (Retroactively add relnotes for `bool::{ok_or,ok_or_else}` (1.98.0))
 - #161924 (Windows: document that `normalize_lexically` converts `/` to `\`)
 - #161927 (Change `rustc_middle/src/hooks/mod.rs` to `hooks.rs`)
@rust-bors
rust-bors Bot merged commit aea48c1 into rust-lang:main Aug 29, 2026
16 of 26 checks passed
rust-bors Bot pushed a commit that referenced this pull request Aug 29, 2026
Rollup merge of #160594 - folkertdev:asm-forward-target-features, r=nikic

attach global target features to module-level assembly

fixes #80608
fixes #127269

At long last, we can forward global target features to LLVM and it will preserve the target features a block of module-level assembly was defined with through LTO.

cc @nikic (who made this happen)
cc @RalfJung any nasty side-effects we might be overlooking here?
@rustbot rustbot added this to the 1.100.0 milestone Aug 29, 2026
@tgross35

Copy link
Copy Markdown
Member

@rustbot label +beta-nominated

There is another backport (#162820) needed to unbreak builds on thumb targets, which is currently relying on this PR in stable. There are possible workarounds but they're not as elegant as having this backported, it seems worth considering given the change is reasonably self-contained.

See some more context at #t-compiler/help > Valid `bx lr` rejected on arm.

@rustbot rustbot added the beta-nominated Nominated for backporting to the compiler in the beta channel. label Sep 17, 2026
@apiraino

Copy link
Copy Markdown
Contributor

@folkertdev would you be in favor to backport this?

@folkertdev

Copy link
Copy Markdown
Contributor Author

Yes, that seems fine to me. We've not seen any issues since merging this.

@rustbot

rustbot commented Sep 17, 2026

Copy link
Copy Markdown
Collaborator

beta backport approved as per compiler team on Zulip. A backport PR will be authored by the release team at the end of the current development cycle. Backport labels are handled by them.

@rustbot rustbot added the beta-accepted Accepted for backporting to the compiler in the beta channel. label Sep 17, 2026
@folkertdev folkertdev added the relnotes Marks issues that should be documented in the release notes of the next release. label Sep 17, 2026
@apiraino

Copy link
Copy Markdown
Contributor

Backport of this patch is cherry-picked in #162820 (see comment), so removing the nomination here to avoid confusion

@rustbot label -beta-nominated -beta-accepted

@rustbot rustbot removed beta-accepted Accepted for backporting to the compiler in the beta channel. beta-nominated Nominated for backporting to the compiler in the beta channel. labels Sep 17, 2026
@cuviper cuviper added the beta-accepted Accepted for backporting to the compiler in the beta channel. label Sep 19, 2026
@cuviper cuviper mentioned this pull request Sep 19, 2026
@cuviper cuviper modified the milestones: 1.100.0, 1.99.0 Sep 19, 2026
rust-bors Bot pushed a commit that referenced this pull request Sep 19, 2026
[beta] backports

- Re-export `core::fmt::NumBuffer` in `alloc` (and `std`) #161430
- Make `VaArgSafe` dyn-incompatible #162374
- Destabilize `VaArgSafe` #162909
- attach global target features to module-level assembly #160594
- (partial) compiler-builtins subtree update - #162816

r? me
rust-bors Bot pushed a commit that referenced this pull request Sep 19, 2026
[beta] backports

- Re-export `core::fmt::NumBuffer` in `alloc` (and `std`) #161430
- Make `VaArgSafe` dyn-incompatible #162374
- Destabilize `VaArgSafe` #162909
- attach global target features to module-level assembly #160594
- (partial) compiler-builtins subtree update - #162816

r? me
rust-bors Bot pushed a commit that referenced this pull request Sep 19, 2026
[beta] backports

- Re-export `core::fmt::NumBuffer` in `alloc` (and `std`) #161430
- Make `VaArgSafe` dyn-incompatible #162374
- Destabilize `VaArgSafe` #162909
- attach global target features to module-level assembly #160594
- (partial) compiler-builtins subtree update - #162816

r? me
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. beta-accepted Accepted for backporting to the compiler in the beta channel. relnotes Marks issues that should be documented in the release notes of the next release. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

9 participants