Skip to content

Conversation

@daxpedda
Copy link
Contributor

@daxpedda daxpedda commented Nov 2, 2025

Adds the ability to make any target feature a target modifier.
Specifically makes Wasm target features atomics and exception-handling target modifiers

Tracking issue: #136966.

r? @alexcrichton


Draft

Would like to get some initial feedback on the implementation and the green light from @alexcrichton if this makes sense in the first place.

Still missing tests as well.

@rustbot rustbot added A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. A-run-make Area: port run-make Makefiles to rmake.rs A-rustdoc-json Area: Rustdoc JSON backend S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. labels Nov 2, 2025
// If feature is a target modifier.
type TargetModifier = bool;

static ARM_FEATURES: &[(&str, Stability, ImpliedFeatures, TargetModifier)] = &[
Copy link
Contributor Author

Choose a reason for hiding this comment

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

It might be time to turn this into a struct type?

Copy link
Member

Choose a reason for hiding this comment

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

This might work well as a builder-style structure such as:

    unstable("aclass, sym::...),
    stable("aes"), 
    stable("other").deps(["a", "b", "c"]),

where .target_modifier(true) could be one of those.

Comment on lines 98 to 99
if session.target.rust_target_features().iter().any(
|(name, _, _, target_modifier)| base_feature == *name && *target_modifier,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This doesn't handle implied features. Its not required right now, but let me know if we should handle it as well.

Copy link
Contributor Author

@daxpedda daxpedda Nov 3, 2025

Choose a reason for hiding this comment

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

This also doesn't handle base features, which is more of a concern.
I'm not entirely sure how this could be handled here.

Could I assume that Session::target_features contains the base features and add any codegen options on top of that?

EDIT: done.

@rust-log-analyzer

This comment has been minimized.

@daxpedda daxpedda force-pushed the wasm-target-feature-target-modifier branch from 3cace49 to 3d7ec4d Compare November 2, 2025 22:34
@rustbot rustbot added A-tidy Area: The tidy tool T-bootstrap Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap) labels Nov 2, 2025
@rust-log-analyzer

This comment has been minimized.

@daxpedda daxpedda force-pushed the wasm-target-feature-target-modifier branch 2 times, most recently from 282f522 to 2aefd42 Compare November 3, 2025 05:54
@daxpedda daxpedda force-pushed the wasm-target-feature-target-modifier branch from 2aefd42 to 2a67ade Compare November 3, 2025 06:08
Copy link
Member

@alexcrichton alexcrichton left a comment

Choose a reason for hiding this comment

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

To flag here on the PR as well there's a concern on Zulip -- #t-compiler > target modifiers for target features @ 💬 -- about using target features for this.

View changes since this review

Comment on lines +96 to +126
for feature in session
.target_features
.iter()
.map(|symbol| symbol.as_str())
.chain(val.value_name.split(','))
{
if let Some(feature) = feature.strip_prefix('+') {
if session
.target
.rust_target_features()
.iter()
.any(|(name, _, _, target_modifier)| feature == *name && *target_modifier)
{
target_features.push(feature);
}
} else if let Some(feature) = feature.strip_prefix('-') {
if session
.target
.rust_target_features()
.iter()
.any(|(name, _, _, target_modifier)| feature == *name && *target_modifier)
{
for (index, target_feature) in target_features.iter().enumerate() {
if *target_feature == feature {
target_features.remove(index);
break;
}
}
}
}
}
Copy link
Member

Choose a reason for hiding this comment

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

I suspect this parsing already exists elsewhere in the codebase -- would it be possible to deduplicate the parsing routine?

Copy link
Member

@bjorn3 bjorn3 Nov 3, 2025

Choose a reason for hiding this comment

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

-Ctarget-features is parsed by parse_rust_feature_flag in cg_ssa. sess.target.features is split on , by cg_llvm and then parsed by LLVM given that it is a set of backend features rather than rust features:

// Features implied by an implicit or explicit `--target`.
features.extend(sess.target.features.split(',').filter(|v| !v.is_empty()).map(String::from));

// If feature is a target modifier.
type TargetModifier = bool;

static ARM_FEATURES: &[(&str, Stability, ImpliedFeatures, TargetModifier)] = &[
Copy link
Member

Choose a reason for hiding this comment

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

This might work well as a builder-style structure such as:

    unstable("aclass, sym::...),
    stable("aes"), 
    stable("other").deps(["a", "b", "c"]),

where .target_modifier(true) could be one of those.

@bors
Copy link
Collaborator

bors commented Nov 5, 2025

☔ The latest upstream changes (presumably #147645) made this pull request unmergeable. Please resolve the merge conflicts.

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. A-run-make Area: port run-make Makefiles to rmake.rs A-rustdoc-json Area: Rustdoc JSON backend A-tidy Area: The tidy tool S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-bootstrap Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants