-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
reject unsound toggling of RISCV target features #134337
Conversation
These commits modify compiler targets. Some changes occurred in compiler/rustc_codegen_gcc |
6111eda
to
5dc6e55
Compare
5dc6e55
to
270c9fa
Compare
270c9fa
to
171223e
Compare
@RalfJung So, "Zfinx" is literally
Basically, it's a dedicated extension for "I can't believe it's not soft float!" Hardware that has it must use a soft-float ABI, since it has no float registers, and this means it cannot implement a float ABI. ...but as long as we require that "ilp32f" means you implement "f" then we're fine. |
Err("feature is required by ABI") | ||
} | ||
"ilp32e" if enable => { | ||
// The `d` feature apparently is incompatible with this ABI. |
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 `d` feature apparently is incompatible with this ABI. | |
// ilp32e is incompatible with features that need aligned load/stores > 32 bits, like `d` |
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.
I am confused: Rust lets you always define types that need >32bit alignment, so that can't be a problem in itself?
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.
You are correct AFAIK that this isn't actually a problem, however the RISC-V ELF psABI for the ILP32E ABI states:
The ILP32E calling convention is not compatible with ISAs that have registers that require load and store alignments of more than 32 bits. In particular, this calling convention must not be used with the D ISA extension.
Correspondingly, LLVM emits an error when there is an attempt to use the D extension with the ILP32E ABI:
rustc-LLVM ERROR: ILP32E cannot be used with the D ISA extension
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.
ack, I didn't mean to confuse.
yeah, it's about the actual CPU-internal alignment requirements imposed by the way the hardware moves things around, as opposed to our language requirements.
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.
oh actually it's kinda weirder, sorry, here we go:
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.
Okay, makes sense.
// Given that this is a negative feature, consider this before stabilizing: | ||
// does it really make sense to enable this feature in an individual | ||
// function with `#[target_feature]`? | ||
nightly_feature: sym::riscv_target_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.
not really, but it does allow #[cfg(target_feature = "e")]
, unfortunately, but that may not be correct if it tries to be dependent on the ABI
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.
Sounds like we may want to mark this feature as "forbidden", i.e., "must be fixed by target spec and cannot be queried by cfg
", and have a separate way to query the ABI.
But anyway it's a nightly-only feature so that can be done in a future PR.
allow_toggle: |target, enable| { | ||
match &*target.llvm_abiname { | ||
_ if !enable => { | ||
// This is a negative feature, *disabling* it is always okay. |
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.
// This is a negative feature, *disabling* it is always okay. | |
// ilp32e can run on rv32i, treating x16-x31 as caller-save |
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.
reason for explicit reasoning: "negative features" have a weird tendency to become "not" at some point (although there's reservations which suggest that shouldn't happen in this case), so having a clear justification for why is preferable in case we have to revisit it.
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.
Unfortunately now the comment has so much jargon that I don't understand it...
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.
r=me with comment adjustments or not
Can you check this correctly warns when using |
Stability::Unstable { | ||
nightly_feature: sym::riscv_target_feature, | ||
allow_toggle: |target, enable| match &*target.llvm_abiname { | ||
"ilp32d" | "lp64d" if !enable => { |
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.
Btw do you know why the 32bit ABIs start with "ilp" but the 64bit ABIs start with "lp"?
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.
- ILP32: Int, Long, and Pointer are 32-bit
- LP64: Long and Pointer are 64-bit (int is 32-bit)
(see also "Data models" section in https://en.cppreference.com/w/cpp/language/types)
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.
So it should really be I32LP64 then...
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.
Yes, but a convention at some point developed that
- we omit the "c8s16" prefix... types that are the smallest possible value
- we all quietly pretend the smallest possible value of int is 32 bits and not 16
names deeply fermented in tradition.
I attempted to make the comments understandable by people who are not RISCV experts; could you take a look? |
It will definitely not warn. We don't even have that feature in the known feature list. |
1551bf5
to
934ed85
Compare
Yes, those are fine~ |
@bors r=workingjubilee |
…workingjubilee reject unsound toggling of RISCV target features ~~Stacked on top of rust-lang#133417, only the last commit is new.~~ Works towards rust-lang#132618 (but more [remains to be done](rust-lang#134337 (comment))) Part of rust-lang#116344 Cc `@beetrees` I hope I got everything. I didn't do anything about "The f and zfinx features are incompatible" and that's not an ABI thing (right?) and I am not sure how to handle it with these ABI checks. r? `@workingjubilee` Ideally we'd also reject target specs that disable the `f` feature but set an ABI that requires `f`... but I don't want to duplicate this logic. I have some ideas for how maybe the entire float ABI check logic should be different, now that we have some examples of what these ABI checks look like, but that will be a future PR.
…llaumeGomez Rollup of 9 pull requests Successful merges: - rust-lang#132056 (Stabilize `#[diagnostic::do_not_recommend]`) - rust-lang#134124 (CI: use free runners for x86_64-gnu-llvm jobs) - rust-lang#134197 (rustc_mir_build: Clarify that 'mirrored' does not mean 'flipped' or 'reversed') - rust-lang#134260 (Correctly handle comments in attributes in doctests source code) - rust-lang#134277 (rustdoc-search: handle `impl Into<X>` better) - rust-lang#134284 (Keep track of patterns that could have introduced a binding, but didn't) - rust-lang#134337 (reject unsound toggling of RISCV target features) - rust-lang#134385 (tests/ui/asm: Remove uses of rustc_attrs, lang_items, and decl_macro features by using minicore) - rust-lang#134386 (Some trait method vs impl method signature difference diagnostic cleanups) r? `@ghost` `@rustbot` modify labels: rollup
…iaskrgr Rollup of 9 pull requests Successful merges: - rust-lang#134124 (CI: use free runners for x86_64-gnu-llvm jobs) - rust-lang#134197 (rustc_mir_build: Clarify that 'mirrored' does not mean 'flipped' or 'reversed') - rust-lang#134260 (Correctly handle comments in attributes in doctests source code) - rust-lang#134277 (rustdoc-search: handle `impl Into<X>` better) - rust-lang#134284 (Keep track of patterns that could have introduced a binding, but didn't) - rust-lang#134337 (reject unsound toggling of RISCV target features) - rust-lang#134371 (Check for array lengths that aren't actually `usize`) - rust-lang#134385 (tests/ui/asm: Remove uses of rustc_attrs, lang_items, and decl_macro features by using minicore) - rust-lang#134386 (Some trait method vs impl method signature difference diagnostic cleanups) r? `@ghost` `@rustbot` modify labels: rollup
Rollup merge of rust-lang#134337 - RalfJung:riscv-target-features, r=workingjubilee reject unsound toggling of RISCV target features ~~Stacked on top of rust-lang#133417, only the last commit is new.~~ Works towards rust-lang#132618 (but more [remains to be done](rust-lang#134337 (comment))) Part of rust-lang#116344 Cc ``@beetrees`` I hope I got everything. I didn't do anything about "The f and zfinx features are incompatible" and that's not an ABI thing (right?) and I am not sure how to handle it with these ABI checks. r? ``@workingjubilee`` Ideally we'd also reject target specs that disable the `f` feature but set an ABI that requires `f`... but I don't want to duplicate this logic. I have some ideas for how maybe the entire float ABI check logic should be different, now that we have some examples of what these ABI checks look like, but that will be a future PR.
Stacked on top of #133417, only the last commit is new.Works towards #132618 (but more remains to be done)
Part of #116344
Cc @beetrees I hope I got everything. I didn't do anything about "The f and zfinx features are incompatible" and that's not an ABI thing (right?) and I am not sure how to handle it with these ABI checks.
r? @workingjubilee
Ideally we'd also reject target specs that disable the
f
feature but set an ABI that requiresf
... but I don't want to duplicate this logic. I have some ideas for how maybe the entire float ABI check logic should be different, now that we have some examples of what these ABI checks look like, but that will be a future PR.