-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
forbid toggling x87 and fpregs on hard-float targets #133099
base: master
Are you sure you want to change the base?
Conversation
Some changes occurred in compiler/rustc_codegen_cranelift cc @bjorn3 These commits modify compiler targets. Some changes occurred in cfg and check-cfg configuration cc @Urgau Some changes occurred in compiler/rustc_codegen_gcc |
64c138c
to
4017676
Compare
This comment has been minimized.
This comment has been minimized.
86932a6
to
35bdfe8
Compare
This comment has been minimized.
This comment has been minimized.
35bdfe8
to
73bb2e9
Compare
73bb2e9
to
a43aacb
Compare
☔ The latest upstream changes (presumably #133568) made this pull request unmergeable. Please resolve the merge conflicts. |
tests/ui/check-cfg/mix.stderr
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Urgau do we need these tests enumerating all target features? They make these kinds of PRs more conflict-heavy than they'd have to be, and they almost always add a "PR CI fails" roundtrip when adding new target features.
IMO it'd be better to normalize away the feature list so that the test output doesn't change just because we add a new feature.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The target features in tests/ui/check-cfg/mix.stderr
only serves as a convenient cfg with many values so we test test the "and XXX more" part, we could normalize the output or replace it with another cfg.
As for the target_feature
cfg values in tests/ui/check-cfg/well-known-values.stderr
having the full list is on purpose, they serve as an anti-regression test, i.e. making sure that any modifications to the target features (adding one, removing one, modifying, ...) are intended and reflected in the well known target_feature
list.
We could remove it, but we don't currently have any other test that would make sure that the list is coherent with what we should except and that makes me a bit worried that it will drift at some point.
For example in this PR you modified many of the logic in target_features.rs
which is the source of truth for the well known target_feature
values, with the test I can be confident that every users (through Cargo) of the target_feature
cfg won't get a warning, which we might missed without the test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
making sure that any modifications to the target features (adding one, removing one, modifying, ...) are intended
One has to quite explicitly edit the target_features file for that. I don't recall a single incident where this happened accidentally before the addition of this test, so I don't think that's a relevant risk. The test being located in check-cfg
also indicates its point is to test check-cfg, not to test the target feature tracking.
OTOH, the extra work caused by having to re-bless this test all the time is quite real.
we don't currently have any other test that would make sure that the list is coherent with what we should except and that makes me a bit worried that it will drift at some point.
The test generally gets blindly --bless
ed, and the list is way too long to be checked by hand. I don't see how this test can meaningfully check that the list is coherent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And not to mention the conflicts -- we are generally trying hard to make it so that independent work can land independently, but this test ensures that any two PRs adding a target feature will necessarily conflict.
with the test I can be confident that every users (through Cargo) of the target_feature cfg won't get a warning, which we might missed without the test.
We need tests that target feature cfg
are recognized obviously. But we don't want an exhaustive list of all target features in the test, IMO. Certainly not all in one line where it causes a conflict in 100% of the cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As Ralf said, it is effectively impossible to accidentally change the list of Rust-recognized target features. I don't find this test particularly relevant.
#[target_feature(enable = "x87")] | ||
//~^ERROR: cannot be toggled with | ||
pub unsafe fn my_fun() {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this unsound? I thought enable = "x87"
on cfg(target_feature = "x87")
environment is no-op.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah we could allow enabling x87 if it is already enabled. But I think that's wasted effort and a useless risk of getting the logic wrong.
Note that #[target_feature(enable = "x87")]
already does not work on stable. So I'd rather wait for someone to show up with a concrete usecase for doing that, and not enable it "just because we can" as part of this PR which is meant to lock down what can be done in terms of target features.
a43aacb
to
41ab0fc
Compare
/// `Stability` where `allow_toggle` has not been computed yet. | ||
/// Returns `Ok` if the toggle is allowed, `Err` with an explanation of not. | ||
pub type StabilityUncomputed = Stability<fn(&Target) -> Result<(), &'static str>>; | ||
/// `Stability` where `allow_toggle` has already been computed. | ||
pub type StabilityComputed = Stability<Result<(), &'static str>>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...is this typestate for a lazylock OnceCell?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmhm, this OnceCell-ish scheme results in a somewhat mysterious-to-read API.
pub fn is_stable(self) -> bool { | ||
matches!(self, Stable) | ||
impl StabilityUncomputed { | ||
pub fn compute(self, target: &Target) -> StabilityComputed { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can this be, like, compute_toggleability
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤷 sure. Seems like the type aliases should also have a different name then, but StabilityWithComputedToggleability
is a bit too much IMO...
I wonder if we ever need to answer the question about toggleability without having access to a If that seems like it'd be worse, then some clearer phrasing will suffice. |
Hm, I didn't think of this like The thing we want to represent is "when are we allowed to toggle a feature flag". This depends on the current target. We could have each target specify that property, but I'd rather have that logic centralized in one place where it can be more easily reviewed. So, the natural representation of this is a function that takes IMO the natural representation for that is a type that is generic in which type is used to represent "can this be toggled", and instantiating it with either the "uncomputed" form (still a function) or the "computed" form (storing the result of the function). Also, queries cannot return function pointers (they don't have a stable hash), and given that we have a query that returns information about target feature, we have to chose a different representation here -- the "fully computed" representation is a natural choice here since queries require a I can try to sprinkle more comments about this design in various places if you think that helps? I would appreciate some pointers for which parts you found most confusing so that this comment sprinkling is not entirely unguided. ;) |
We better don't as I don't think that's a valid question to ask. Toggleability is target-dependent.
I don't understand this sentence, sorry. Pass what unconditionally? Cache things where? The query gets cached, but some of the target feature logic is unfortunately invoked before there is a |
This comment has been minimized.
This comment has been minimized.
8a639d4
to
bd53b3e
Compare
Oh no, I definitely didn't have a global cache in mind. Will try to cook up a better explanation of what I meant about things in a wee bit. |
…cs, r=jieyouxu Reducing `target_feature` check-cfg merge conflicts It was rightfully pointed in rust-lang#133099 (comment) that the expected values for the `target_feature` cfg are regularly updated and unfortunately the check-cfg tests for it are very merge-conflict prone. This PR aims at drastically reducing the likely-hood of those, by normalizing the "and X more" diagnostic, as well as making the full expected list multi-line instead of being on a single one. cc `@RalfJung` r? `@jieyouxu`
Rollup merge of rust-lang#133710 - Urgau:target_feature-merge-conflitcs, r=jieyouxu Reducing `target_feature` check-cfg merge conflicts It was rightfully pointed in rust-lang#133099 (comment) that the expected values for the `target_feature` cfg are regularly updated and unfortunately the check-cfg tests for it are very merge-conflict prone. This PR aims at drastically reducing the likely-hood of those, by normalizing the "and X more" diagnostic, as well as making the full expected list multi-line instead of being on a single one. cc `@RalfJung` r? `@jieyouxu`
☔ The latest upstream changes (presumably #133770) made this pull request unmergeable. Please resolve the merge conflicts. |
well, on the upside, you'll have to deal with that particular conflict less in the future |
…e can be invalid to toggle Also rename some things for extra clarity
bd53b3e
to
0cb8b2b
Compare
…youxu Reducing `target_feature` check-cfg merge conflicts It was rightfully pointed in rust-lang/rust#133099 (comment) that the expected values for the `target_feature` cfg are regularly updated and unfortunately the check-cfg tests for it are very merge-conflict prone. This PR aims at drastically reducing the likely-hood of those, by normalizing the "and X more" diagnostic, as well as making the full expected list multi-line instead of being on a single one. cc `@RalfJung` r? `@jieyouxu`
Part of #116344, follow-up to #129884:
The
x87
target feature on x86 and thefpregs
target feature on ARM must not be disabled on a hardfloat target, as that would change the float ABI. However, enablingfpregs
on ARM is explicitly requested as it seems to be useful. Therefore, we need to refine the distinction of "forbidden" target features and "allowed" target features: all (un)stable target features can determine on a per-target basis whether they should be allowed to be toggled or not.fpregs
then checks whether the current target has thesoft-float
feature, and if yes,fpregs
is permitted -- otherwise, it is not. (Same forx87
on x86).Also fixes #132351. Since
fpregs
andx87
can be enabled on some builds and disabled on others, it would make sense that one can query it viacfg
. Therefore, I made them behave incfg
like any other unstable target feature.The first commit prepares the infrastructure, but does not change behavior. The second commit then wires up
fpregs
andx87
with that new infrastructure.r? @workingjubilee