-
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
Add a notion of "some ABIs require certain target features" #134794
base: master
Are you sure you want to change the base?
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"ilp32" | "lp64" => NOTHING, | |
"ilp32" | "lp64" => { | |
// Incompatible with e. | |
(&[], &["e"]) | |
} |
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.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 |
Could we instead add a -nofloat version of these targets? Or provide a compiler way to disable all use of float types with a build-std config to go with it.
Thus far, the lang and libs-api teams have insisted that all targets must support float types. They may be software emulated but they cannot be missing.
In principle this is entirely feasible, it is just not currently supported by LLVM.
|
…led by the ABI target feature check
e42ad00
to
17b820c
Compare
This PR modifies cc @jieyouxu |
// It's unclear how the `abi` and the `soft-float` target feature interact. | ||
// We use the `abi` as our primary signal, and force `soft-float` to match. | ||
match &*self.abi { | ||
"eabi" => (&["soft-float"], &[]), |
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.
Turns out the arm-linux-androideabi target sets the eabi
ABI, but does not set +soft-float
. What does that even mean? Is it a valid combination?
With my PR, +soft-float
now gets added automatically, which is why the run-make test needed adjustments.
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.
@maurer @chriswailes @mgeisler almost all our ARM eabi
targets set +soft-float
; the android targets seems to be the only exception (at least they are the only exception I have found so far). Is there a reason for this or is it just an oversight?
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.
Turns out the arm-linux-androideabi target sets the
eabi
ABI, but does not set+soft-float
. What does that even mean? Is it a valid combination?
Yes, it is a valid combination. It means, in essence, "pass floats via integer registers, but internal to functions, use the hardware float instructions".
It makes sense when your original baseline for target support for an architecture was originally "the hardware FPU is... optional? or... the exact one you're using isn't specified, at least...?" and you don't want to break ABI but have nonetheless raised the hardware requirements to run your target.
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, it is a valid combination. It means, in essence, "pass floats via integer registers, but internal to functions, use the hardware float instructions".
AFAIK, the abi
field is not forwarded to LLVM in any form. (We have llvm_abiname
for that.) So I can't align what you are saying with what the Rust compiler does.
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, my apologies, I was only answering the abstract question because you said ABI and not abi
. As I mentioned, the abi
field is just a string intended to identify what ABI we are supposed to be using. Despite it being a valid notion, we may not actually be implementing anything correctly here, as I have no idea what set of mystical incantations LLVM expects here (as each target backend seems to implement the idea of "a soft-float ABI may exist" slightly differently).
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.
My understanding was that +soft-float,+fpregs
is how we request a softfloat ABI but using float instructions where possible. But I am not sure whether that actually works.
ARM targets have -float-abi
in clang (which we expose via -Csoft-float
), which may be a more reliable way to control this than target features? But that makes me wonder what the point is of having both that flag and the soft-float
target feature...
This comment has been minimized.
This comment has been minimized.
17b820c
to
6861049
Compare
This comment has been minimized.
This comment has been minimized.
6861049
to
958f3f3
Compare
Cc @JamieCunliffe -- it may be possible to use it (from a quick test, it seems to work). |
Cool. Just Doing That would be appreciated. I'd rather special-case one target tuple for a while for your benefit, if necessary, while we hash out some details, than have that particular need affect how we handle other targets. |
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". 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.
This is best reviewed commit-by-commit. The first commit adds the new
abi_required_features
function. For now, that function supports x86, ARM, and RISC-V (just like the previous logic did). Unsurprisingly, RISC-V is the nicest. ;) Both-Ctarget-feature
and#[target_feature]
are updated to ensure we follow the rules of the ABI. We also 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.As a side-effect this also (unstably) allows enabling
x87
when that is harmless.This should also prepare us for requiring SSE on x86-32bit when we want to use that for our ABI (and for float semantics sanity), see #133611.
The last commit marks SSE2 as required on x86-64, to better match the actual logic in LLVM and because all x86-64 chips do have SSE2.
r? @workingjubilee