-
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
The ABI of float types can be changed by -Ctarget-feature
#116344
Comments
Cc @rust-lang/opsem |
FTR, I think the -x87,+softfp and -x87,+sse codegens are wrong for at least the C abi, because Sys-V (and msabi) do prescribe that float/double are returned in st(0) and provide no other alternative - so I think rustc should reject this code in particular. I actually wanted a similar prohibition retroactively on the simd types, but the x86_64-psabi list did not accept that request. |
This is correct.
I believe I have vocalized that this is my desired solution as well. |
Demonstrating the 3 different ways that rustc returns floats on x86: https://rust.godbolt.org/z/r83MbYh5n. Although it seems f64 specifically is spared on sse and softfp (not between |
Force enabling them (or blanket erroring) on i686-wide would affect kernel mode code that typically disables the FPU and vector extensions to avoid having to save that state every context switch. Refusing to codegen floats is a reasonable alternative, though. For sse in particular, llvm really loves to copy data arround using xmm registers, so this will either cause a |
Kernel-friendly targets need to be handled specially as always. |
I was about to say this didn't need O-x86_64, but... |
I just realized that with
Force enabling them wouldn't affect that code if it doesn't use any floats. :) |
It does though, especially sse as mentioned. |
It does?
Bless you? To me it looks like you put the output of |
If you tell llvm that it can use sse instructions, it will completely decide to fold scalar bytewise copies into sse copies and cause a general protection exception in kernel code that isn't configured to allow those instructions. This is why it's considered undefined behaviour to merely enter code with an unavailable feature available. |
Example of llvm using |
Ah, bummer. That sounds like we want |
Disabling target features is incredibly useful when writing all kinds of code. Kernel and driver code especially, but I write a lot of "Low-level user mode code" that also somestimes requires finagling with And sometimes you live before the kernel. A bootloader gratuitously opting arbitrary kernels into cr4.OSXFSAVE is even worse, because the instructions won't trap, just silently clobber user mode state. |
You are describing a good motivation for a You are not describing why we should offer the ability to disable target features, when perfectly valid alternatives exist; alternatives that do not also eat your kitttens. "It is useful" applies to many things that we very deliberately do not let people do because they just cause too many issues. |
It is still possible to obtain what is desired for those by switching to an enable-only process, or virtually so (I realize that softfloat is technically a feature one must often disable to get correct codegen). |
Note: #115919 would make this apply by toggling |
#115919 could be adjusted to only kick in when the baseline features of the target include SSE. If we do that, does enabling SSE ever affect the ABI of f32/f64? If the answer is "no" then I think the i586 targets are good, right? For softfloat targets, we'd have to ensure their f32/f64 ABI is unaffected by enabling x87 or SSE, or we have to reject enabling those features. The former should actually be possible, right? I would assume f32 is passed much like i32 and f64 like i64 on those targets, so we can tell LLVM to pass floats as i32/i64 and then we don't have to worry about target features at all? |
…ngjubilee Always specify `llvm_abiname` for RISC-V targets For RISC-V targets, when `llvm_abiname` is not specified LLVM will infer the ABI from the target features, causing rust-lang#116344 to occur. This PR adds the correct `llvm_abiname` to all RISC-V targets where it is missing (which are all soft-float targets), and adds a test to prevent future RISC-V targets from accidentally omitting `llvm_abiname`. The only affect of this PR is that `-Ctarget-feature=+f` (or similar) will no longer affect the ABI on the modified targets. <!-- homu-ignore:start --> r? `@RalfJung` <!--- homu-ignore:end -->
Rollup merge of rust-lang#131807 - beetrees:riscv-target-abi, r=workingjubilee Always specify `llvm_abiname` for RISC-V targets For RISC-V targets, when `llvm_abiname` is not specified LLVM will infer the ABI from the target features, causing rust-lang#116344 to occur. This PR adds the correct `llvm_abiname` to all RISC-V targets where it is missing (which are all soft-float targets), and adds a test to prevent future RISC-V targets from accidentally omitting `llvm_abiname`. The only affect of this PR is that `-Ctarget-feature=+f` (or similar) will no longer affect the ABI on the modified targets. <!-- homu-ignore:start --> r? `@RalfJung` <!--- homu-ignore:end -->
-Ctarget-feature
…, r=workingjubilee mark some target features as 'forbidden' so they cannot be (un)set with -Ctarget-feature The context for this is rust-lang#116344: some target features change the way floats are passed between functions. Changing those target features is unsound as code compiled for the same target may now use different ABIs. So this introduces a new concept of "forbidden" target features (on top of the existing "stable " and "unstable" categories), and makes it a hard error to (un)set such a target feature. For now, the x86 and ARM feature `soft-float` is on that list. We'll have to make some effort to collect more relevant features, and similar features from other targets, but that can happen after the basic infrastructure for this landed. (These features are being collected in rust-lang#131799.) I've made this a warning for now to give people some time to speak up if this would break something. MCP: rust-lang/compiler-team#780
…r=workingjubilee mark some target features as 'forbidden' so they cannot be (un)set with -Ctarget-feature The context for this is rust-lang#116344: some target features change the way floats are passed between functions. Changing those target features is unsound as code compiled for the same target may now use different ABIs. So this introduces a new concept of "forbidden" target features (on top of the existing "stable " and "unstable" categories), and makes it a hard error to (un)set such a target feature. For now, the x86 and ARM feature `soft-float` is on that list. We'll have to make some effort to collect more relevant features, and similar features from other targets, but that can happen after the basic infrastructure for this landed. (These features are being collected in rust-lang#131799.) I've made this a warning for now to give people some time to speak up if this would break something. MCP: rust-lang/compiler-team#780
…r=workingjubilee mark some target features as 'forbidden' so they cannot be (un)set with -Ctarget-feature The context for this is rust-lang#116344: some target features change the way floats are passed between functions. Changing those target features is unsound as code compiled for the same target may now use different ABIs. So this introduces a new concept of "forbidden" target features (on top of the existing "stable " and "unstable" categories), and makes it a hard error to (un)set such a target feature. For now, the x86 and ARM feature `soft-float` is on that list. We'll have to make some effort to collect more relevant features, and similar features from other targets, but that can happen after the basic infrastructure for this landed. (These features are being collected in rust-lang#131799.) I've made this a warning for now to give people some time to speak up if this would break something. MCP: rust-lang/compiler-team#780
…jubilee mark some target features as 'forbidden' so they cannot be (un)set with -Ctarget-feature The context for this is rust-lang/rust#116344: some target features change the way floats are passed between functions. Changing those target features is unsound as code compiled for the same target may now use different ABIs. So this introduces a new concept of "forbidden" target features (on top of the existing "stable " and "unstable" categories), and makes it a hard error to (un)set such a target feature. For now, the x86 and ARM feature `soft-float` is on that list. We'll have to make some effort to collect more relevant features, and similar features from other targets, but that can happen after the basic infrastructure for this landed. (These features are being collected in rust-lang/rust#131799.) I've made this a warning for now to give people some time to speak up if this would break something. MCP: rust-lang/compiler-team#780
…jubilee mark some target features as 'forbidden' so they cannot be (un)set with -Ctarget-feature The context for this is rust-lang/rust#116344: some target features change the way floats are passed between functions. Changing those target features is unsound as code compiled for the same target may now use different ABIs. So this introduces a new concept of "forbidden" target features (on top of the existing "stable " and "unstable" categories), and makes it a hard error to (un)set such a target feature. For now, the x86 and ARM feature `soft-float` is on that list. We'll have to make some effort to collect more relevant features, and similar features from other targets, but that can happen after the basic infrastructure for this landed. (These features are being collected in rust-lang/rust#131799.) I've made this a warning for now to give people some time to speak up if this would break something. MCP: rust-lang/compiler-team#780
…jubilee mark some target features as 'forbidden' so they cannot be (un)set with -Ctarget-feature The context for this is rust-lang/rust#116344: some target features change the way floats are passed between functions. Changing those target features is unsound as code compiled for the same target may now use different ABIs. So this introduces a new concept of "forbidden" target features (on top of the existing "stable " and "unstable" categories), and makes it a hard error to (un)set such a target feature. For now, the x86 and ARM feature `soft-float` is on that list. We'll have to make some effort to collect more relevant features, and similar features from other targets, but that can happen after the basic infrastructure for this landed. (These features are being collected in rust-lang/rust#131799.) I've made this a warning for now to give people some time to speak up if this would break something. MCP: rust-lang/compiler-team#780
…s, r=workingjubilee forbid toggling x87 and fpregs on hard-float targets Part of rust-lang#116344, follow-up to rust-lang#129884: The `x87` target feature on x86 and the `fpregs` target feature on ARM must not be disabled on a hardfloat target, as that would change the float ABI. However, *enabling* `fpregs` on ARM is [explicitly requested](rust-lang#130988) 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 the `soft-float` feature, and if yes, `fpregs` is permitted -- otherwise, it is not. (Same for `x87` on x86). Also fixes rust-lang#132351. Since `fpregs` and `x87` can be enabled on some builds and disabled on others, it would make sense that one can query it via `cfg`. Therefore, I made them behave in `cfg` like any other unstable target feature. The first commit prepares the infrastructure, but does not change behavior. The second commit then wires up `fpregs` and `x87` with that new infrastructure. r? `@workingjubilee`
…ingjubilee forbid toggling x87 and fpregs on hard-float targets Part of rust-lang/rust#116344, follow-up to rust-lang/rust#129884: The `x87` target feature on x86 and the `fpregs` target feature on ARM must not be disabled on a hardfloat target, as that would change the float ABI. However, *enabling* `fpregs` on ARM is [explicitly requested](rust-lang/rust#130988) 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 the `soft-float` feature, and if yes, `fpregs` is permitted -- otherwise, it is not. (Same for `x87` on x86). Also fixes rust-lang/rust#132351. Since `fpregs` and `x87` can be enabled on some builds and disabled on others, it would make sense that one can query it via `cfg`. Therefore, I made them behave in `cfg` like any other unstable target feature. The first commit prepares the infrastructure, but does not change behavior. The second commit then wires up `fpregs` and `x87` with that new infrastructure. r? `@workingjubilee`
…gjubilee reject aarch64 target feature toggling that would change the float ABI ~~Stacked on top of rust-lang#133099. Only the last two commits are new.~~ The first new commit lays the groundwork for separately controlling whether a feature may be enabled or disabled. The second commit uses that to make it illegal to *disable* the `neon` feature (which is only possible via `-Ctarget-feature`, and so the new check just adds a warning). Enabling the `neon` feature remains allowed on targets that don't disable `neon` or `fp-armv8`, which is all our built-in targets. This way, the entire PR is not a breaking change. Fixes rust-lang#131058 for hardfloat targets (together with rust-lang#133102 which fixed it for softfloat targets). Part of rust-lang#116344.
…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.
…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.
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.
A function that returns an
f32
/f64
is not ABI-compatible with other functions that have the same signature on i686 when certain target features differ. It looks like one can disable thex87
feature or enable thesoft-float
and then it will use different ways of passing floating-point arguments.This is unsound as code calling methods from the standard library would now use the wrong registers to return results. In other words, setting
-Ctarget-feature=-x87
or-Ctarget-feature=+soft-float
can introduce UB unless the standard library is rebuilt with the same flags. We therefore should reject these flags, to avoid the UB. This issue tracks that problem, and transitioning it to a hard error.(SIMD types have a similar problem, but we are dealing with that differently. See #116558.)
Current status:
#[target_feature]
(will be shipped in 1.84) -- not a breaking change since those features were not allowed in#[target_feature]
before either, only the error message changed-Ctarget-feature
announcing that this will become a hard error in the future (will be shipped in 1.84)The text was updated successfully, but these errors were encountered: