Add a notion of "some ABIs require certain target features" - #134794
Conversation
|
Could not assign reviewer from: |
|
r? @davidtwco rustbot has assigned @davidtwco. Use |
|
These commits modify compiler targets. Some changes occurred in compiler/rustc_codegen_gcc |
This comment has been minimized.
This comment has been minimized.
79f8de2 to
849fb06
Compare
This comment has been minimized.
This comment has been minimized.
849fb06 to
a25cfb0
Compare
This comment has been minimized.
This comment has been minimized.
a25cfb0 to
e89c9ff
Compare
This comment has been minimized.
This comment has been minimized.
e89c9ff to
c221672
Compare
This comment has been minimized.
This comment has been minimized.
c221672 to
b144ab7
Compare
|
I will get around to this, I just put a freeze on my queue because I was accumulating enough reviews in addition to ongoing patch series. :P |
| // Embedded ABI, requires e. | ||
| (&["e"], &[]) | ||
| } | ||
| "ilp32" | "lp64" => NOTHING, |
There was a problem hiding this comment.
| "ilp32" | "lp64" => NOTHING, | |
| "ilp32" | "lp64" => { | |
| // Incompatible with e. | |
| (&[], &["e"]) | |
| } |
There was a problem hiding this comment.
Ah right the old logic treated all the non-e ABIs the same, we should keep that.
The old logic also allowed disabling e when using an e ABI, so we should probably keep that, too.
b144ab7 to
7563d57
Compare
|
@ojeda wrote
That no longer works after this PR ( |
| // We support 2 ABIs, hardfloat (default) and softfloat. | ||
| if self.has_feature("soft-float") { | ||
| NOTHING |
There was a problem hiding this comment.
It seems like this might be wrong, and we should be checking self.abi instead... but I am not sure yet.
| for feature in abi_enable { | ||
| all_rust_features.push((true, feature)); | ||
| } | ||
| for feature in abi_disable { | ||
| all_rust_features.push((false, feature)); | ||
| } |
There was a problem hiding this comment.
This is the part where we explicitly set the ABI-relevant features. The concern here is on the one hand not knowing the default target features, and also not being entirely sure that we correctly model all "implied features" on the LLVM side.
Currently this adds the ABI-relevant features after the ones from -Ctarget-features, i.e. we are overriding the user here. That's a massive change in behavior. I feel I should probably swap the order, but then we are not protected against unexpected feature implications any more. Still, we probably want the target modifier story to be more solidified before we do any behavior changes here.
I changed this to add the ABI features before the user-defined features, so things will behave as before with |
This comment has been minimized.
This comment has been minimized.
Could we instead add a |
8799588 to
43ede97
Compare
|
Rebased now that #134932 landed; the ARM code here now is very clean. We don't even have to mark |
workingjubilee
left a comment
There was a problem hiding this comment.
thank you! this does look a lot nicer overall. only a small nit or three (as most of the "review" of "how even to proceed?" happened on Zulip already)
This comment has been minimized.
This comment has been minimized.
887803d to
2e64b53
Compare
|
Wonderful! @bors r+ |
|
☀️ Test successful - checks-actions |
|
Finished benchmarking commit (feb32c6): comparison URL. Overall result: ❌ regressions - no action needed@rustbot label: -perf-regression Instruction countThis is the most reliable metric that we have; it was used to determine the overall result at the top of this comment. However, even this metric can sometimes exhibit noise.
Max RSS (memory usage)Results (primary -1.7%, secondary 0.6%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesResults (secondary 1.7%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
Binary sizeResults (primary 0.0%, secondary 0.1%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
Bootstrap: 763.545s -> 762.625s (-0.12%) |
…s, r=workingjubilee Add a notion of "some ABIs require certain target features" I think I finally found the right shape for the data and checks that I recently added in rust-lang#133099, rust-lang#133417, rust-lang#134337: we have a notion of "this ABI requires the following list of target features, and it is incompatible with the following list of target features". Both `-Ctarget-feature` and `#[target_feature]` are updated to ensure we follow the rules of the ABI. This removes all the "toggleability" stuff introduced before, though we do keep the notion of a fully "forbidden" target feature -- this is needed to deal with target features that are actual ABI switches, and hence are needed to even compute the list of required target features. We always explicitly (un)set all required and in-conflict features, just to avoid potential trouble caused by the default features of whatever the base CPU is. We do this *before* applying `-Ctarget-feature` to maintain backward compatibility; this poses a slight risk of missing some implicit feature dependencies in LLVM but has the advantage of not breaking users that deliberately toggle ABI-relevant target features. They get a warning but the feature does get toggled the way they requested. For now, our logic supports x86, ARM, and RISC-V (just like the previous logic did). Unsurprisingly, RISC-V is the nicest. ;) As a side-effect this also (unstably) allows *enabling* `x87` when that is harmless. I used the opportunity to mark SSE2 as required on x86-64, to better match the actual logic in LLVM and because all x86-64 chips do have SSE2. This infrastructure also prepares us for requiring SSE on x86-32 when we want to use that for our ABI (and for float semantics sanity), see rust-lang#133611, but no such change is happening in this PR. r? `@workingjubilee`
…re-arm, r=davidtwco make target feature ABI check a hard error on ARM With LLVM 24, we now (finally) get hard errors from the backend for "you want ABI X but the target features required for that ABI are missing", at least on the ARM backend: ``` error: <unknown>:0:0: in function _RNvXsc_Cs4Af2OiBEA1T_8minicoreiNtB5_3Add3add i32 (i32, i32): calling convention is hard-float, but floating-point registers are unavailable ``` That's not a pretty error, so let's make rust emit a hard error before we even get there -- just on ARM for now, matching LLVM. We have emitted a future-compat error for this since Rust 1.86 (rust-lang#136147, rust-lang#134794). I'm not making it a hard error everywhere since for other targets we are still figuring out the exact things we have to check, and it's better to do that without risking new hard errors. For ARM, the exact check we are doing is: - every target must set `llvm_floatabi` to either "soft" or "hard" - on softfloat targets, no check is needed - on hardfloat targets, the "fpregs" target feature is *required* and the the "soft-float" target feature is *forbidden* Since this is a new hard error, this probably requires FCP. I am not sure for which team -- @rust-lang/lang is often involved for target feature things, but this is mostly about rejecting invalid `-C` flags which are handled by t-compiler (@davidtwco @BoxyUwU). Fixes rust-lang#161276 Tracking issue rust-lang#116344 Cc @TimNN
…re-arm, r=davidtwco make target feature ABI check a hard error on ARM With LLVM 24, we now (finally) get hard errors from the backend for "you want ABI X but the target features required for that ABI are missing", at least on the ARM backend: ``` error: <unknown>:0:0: in function _RNvXsc_Cs4Af2OiBEA1T_8minicoreiNtB5_3Add3add i32 (i32, i32): calling convention is hard-float, but floating-point registers are unavailable ``` That's not a pretty error, so let's make rust emit a hard error before we even get there -- just on ARM for now, matching LLVM. We have emitted a future-compat error for this since Rust 1.86 (rust-lang#136147, rust-lang#134794). I'm not making it a hard error everywhere since for other targets we are still figuring out the exact things we have to check, and it's better to do that without risking new hard errors. For ARM, the exact check we are doing is: - every target must set `llvm_floatabi` to either "soft" or "hard" - on softfloat targets, no check is needed - on hardfloat targets, the "fpregs" target feature is *required* and the the "soft-float" target feature is *forbidden* Since this is a new hard error, this probably requires FCP. I am not sure for which team -- @rust-lang/lang is often involved for target feature things, but this is mostly about rejecting invalid `-C` flags which are handled by t-compiler (@davidtwco @BoxyUwU). Fixes rust-lang#161276 Tracking issue rust-lang#116344 Cc @TimNN
…re-arm, r=davidtwco make target feature ABI check a hard error on ARM With LLVM 24, we now (finally) get hard errors from the backend for "you want ABI X but the target features required for that ABI are missing", at least on the ARM backend: ``` error: <unknown>:0:0: in function _RNvXsc_Cs4Af2OiBEA1T_8minicoreiNtB5_3Add3add i32 (i32, i32): calling convention is hard-float, but floating-point registers are unavailable ``` That's not a pretty error, so let's make rust emit a hard error before we even get there -- just on ARM for now, matching LLVM. We have emitted a future-compat error for this since Rust 1.86 (rust-lang#136147, rust-lang#134794). I'm not making it a hard error everywhere since for other targets we are still figuring out the exact things we have to check, and it's better to do that without risking new hard errors. For ARM, the exact check we are doing is: - every target must set `llvm_floatabi` to either "soft" or "hard" - on softfloat targets, no check is needed - on hardfloat targets, the "fpregs" target feature is *required* and the the "soft-float" target feature is *forbidden* Since this is a new hard error, this probably requires FCP. I am not sure for which team -- @rust-lang/lang is often involved for target feature things, but this is mostly about rejecting invalid `-C` flags which are handled by t-compiler (@davidtwco @BoxyUwU). Fixes rust-lang#161276 Tracking issue rust-lang#116344 Cc @TimNN
Rollup merge of #161280 - RalfJung:abi-required-target-feature-arm, r=davidtwco make target feature ABI check a hard error on ARM With LLVM 24, we now (finally) get hard errors from the backend for "you want ABI X but the target features required for that ABI are missing", at least on the ARM backend: ``` error: <unknown>:0:0: in function _RNvXsc_Cs4Af2OiBEA1T_8minicoreiNtB5_3Add3add i32 (i32, i32): calling convention is hard-float, but floating-point registers are unavailable ``` That's not a pretty error, so let's make rust emit a hard error before we even get there -- just on ARM for now, matching LLVM. We have emitted a future-compat error for this since Rust 1.86 (#136147, #134794). I'm not making it a hard error everywhere since for other targets we are still figuring out the exact things we have to check, and it's better to do that without risking new hard errors. For ARM, the exact check we are doing is: - every target must set `llvm_floatabi` to either "soft" or "hard" - on softfloat targets, no check is needed - on hardfloat targets, the "fpregs" target feature is *required* and the the "soft-float" target feature is *forbidden* Since this is a new hard error, this probably requires FCP. I am not sure for which team -- @rust-lang/lang is often involved for target feature things, but this is mostly about rejecting invalid `-C` flags which are handled by t-compiler (@davidtwco @BoxyUwU). Fixes #161276 Tracking issue #116344 Cc @TimNN
I think I finally found the right shape for the data and checks that I recently added in #133099, #133417, #134337: we have a notion of "this ABI requires the following list of target features, and it is incompatible with the following list of target features". Both
-Ctarget-featureand#[target_feature]are updated to ensure we follow the rules of the ABI. This removes all the "toggleability" stuff introduced before, though we do keep the notion of a fully "forbidden" target feature -- this is needed to deal with target features that are actual ABI switches, and hence are needed to even compute the list of required target features.We always explicitly (un)set all required and in-conflict features, just to avoid potential trouble caused by the default features of whatever the base CPU is. We do this before applying
-Ctarget-featureto maintain backward compatibility; this poses a slight risk of missing some implicit feature dependencies in LLVM but has the advantage of not breaking users that deliberately toggle ABI-relevant target features. They get a warning but the feature does get toggled the way they requested.For now, our logic supports x86, ARM, and RISC-V (just like the previous logic did). Unsurprisingly, RISC-V is the nicest. ;)
As a side-effect this also (unstably) allows enabling
x87when that is harmless. I used the opportunity to mark SSE2 as required on x86-64, to better match the actual logic in LLVM and because all x86-64 chips do have SSE2. This infrastructure also prepares us for requiring SSE on x86-32 when we want to use that for our ABI (and for float semantics sanity), see #133611, but no such change is happening in this PR.r? @workingjubilee