Skip to content
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

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

RalfJung
Copy link
Member

@RalfJung RalfJung commented Dec 26, 2024

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

@rustbot
Copy link
Collaborator

rustbot commented Dec 26, 2024

Could not assign reviewer from: workingjubilee.
User(s) workingjubilee are either the PR author, already assigned, or on vacation, and there are no other candidates.
Use r? to specify someone else to assign.

@rustbot
Copy link
Collaborator

rustbot commented Dec 26, 2024

r? @davidtwco

rustbot has assigned @davidtwco.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Dec 26, 2024
@rustbot
Copy link
Collaborator

rustbot commented Dec 26, 2024

These commits modify compiler targets.
(See the Target Tier Policy.)

Some changes occurred in compiler/rustc_codegen_gcc

cc @antoyo, @GuillaumeGomez

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@RalfJung RalfJung force-pushed the abi-required-target-features branch from 849fb06 to a25cfb0 Compare December 26, 2024 19:43
@rust-log-analyzer

This comment has been minimized.

@RalfJung RalfJung force-pushed the abi-required-target-features branch from a25cfb0 to e89c9ff Compare December 26, 2024 20:50
@rust-log-analyzer

This comment has been minimized.

@RalfJung RalfJung force-pushed the abi-required-target-features branch from e89c9ff to c221672 Compare December 26, 2024 21:34
@rust-log-analyzer

This comment has been minimized.

@RalfJung RalfJung force-pushed the abi-required-target-features branch from c221672 to b144ab7 Compare December 26, 2024 22:11
@workingjubilee
Copy link
Member

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,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"ilp32" | "lp64" => NOTHING,
"ilp32" | "lp64" => {
// Incompatible with e.
(&[], &["e"])
}

Copy link
Member Author

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.

@RalfJung RalfJung force-pushed the abi-required-target-features branch from b144ab7 to 7563d57 Compare December 27, 2024 08:43
@RalfJung
Copy link
Member Author

@ojeda wrote

(currently, arm64 in the kernel uses --target=aarch64-unknown-none -Ctarget-feature="-neon").

That no longer works after this PR (neon is a required ABI feature so it cannot be disabled with -Ctarget-feature)... so I probably need to at least slightly adjust my strategy here.

Comment on lines 855 to 774
// We support 2 ABIs, hardfloat (default) and softfloat.
if self.has_feature("soft-float") {
NOTHING
Copy link
Member Author

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.

Comment on lines 775 to 780
for feature in abi_enable {
all_rust_features.push((true, feature));
}
for feature in abi_disable {
all_rust_features.push((false, feature));
}
Copy link
Member Author

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.

@RalfJung
Copy link
Member Author

That no longer works after this PR (neon is a required ABI feature so it cannot be disabled with -Ctarget-feature)... so I probably need to at least slightly adjust my strategy here.

I changed this to add the ABI features before the user-defined features, so things will behave as before with -Ctarget-feature=-neon on ARM targets. However, a warning is shown since this is not a supported combination -- long-term we want to forbid disabling neon on targets that need float registers for their ABI.

@rust-log-analyzer

This comment has been minimized.

@tgross35
Copy link
Contributor

I changed this to add the ABI features before the user-defined features, so things will behave as before with -Ctarget-feature=-neon on ARM targets. However, a warning is shown since this is not a supported combination -- long-term we want to forbid disabling neon on targets that need float registers for their ABI.

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.

@workingjubilee
Copy link
Member

@tgross35 We already have aarch64-unknown-none-softfloat.

@ojeda Why does the kernel not use it?

@RalfJung
Copy link
Member Author

RalfJung commented Dec 28, 2024 via email

@RalfJung RalfJung force-pushed the abi-required-target-features branch from e42ad00 to 17b820c Compare December 28, 2024 08:07
@rustbot rustbot added the A-run-make Area: port run-make Makefiles to rmake.rs label Dec 28, 2024
@rustbot
Copy link
Collaborator

rustbot commented Dec 28, 2024

This PR modifies tests/run-make/. If this PR is trying to port a Makefile
run-make test to use rmake.rs, please update the
run-make port tracking issue
so we can track our progress. You can either modify the tracking issue
directly, or you can comment on the tracking issue and link this PR.

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"], &[]),
Copy link
Member Author

@RalfJung RalfJung Dec 28, 2024

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.

Copy link
Member Author

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?

Copy link
Member

@workingjubilee workingjubilee Dec 28, 2024

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.

Copy link
Member Author

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.

Copy link
Member

@workingjubilee workingjubilee Dec 28, 2024

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).

Copy link
Member Author

@RalfJung RalfJung Dec 29, 2024

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...

@rust-log-analyzer

This comment has been minimized.

@RalfJung RalfJung force-pushed the abi-required-target-features branch from 17b820c to 6861049 Compare December 28, 2024 09:26
@rust-log-analyzer

This comment has been minimized.

@RalfJung RalfJung force-pushed the abi-required-target-features branch from 6861049 to 958f3f3 Compare December 28, 2024 10:03
@ojeda
Copy link
Contributor

ojeda commented Dec 28, 2024

@tgross35 We already have aarch64-unknown-none-softfloat.

@ojeda Why does the kernel not use it?

Cc @JamieCunliffe -- it may be possible to use it (from a quick test, it seems to work).

@workingjubilee
Copy link
Member

workingjubilee commented Dec 28, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-run-make Area: port run-make Makefiles to rmake.rs S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants